Update issue #231

Status: Fixed

The globbing expressions are now saved and used.
This includes the new filter test dialog that generates globbing rather than regexps.

git-svn-id: https://duplicati.googlecode.com/svn/trunk@904 59da171f-624f-0410-aa54-27559c288bec
This commit is contained in:
kenneth.skovhede@gmail.com
2011-09-21 20:13:07 +00:00
parent 345d18a013
commit 1030577a8e
17 changed files with 819 additions and 535 deletions
@@ -0,0 +1 @@
ALTER TABLE "TaskFilter" ADD COLUMN "GlobbingFilter" TEXT NULL;
+3 -2
View File
@@ -83,7 +83,8 @@ CREATE TABLE "TaskFilter" (
"SortOrder" INTEGER NULL,
"Include" BOOLEAN NULL,
"Filter" TEXT NULL,
"TaskID" INTEGER NULL
"TaskID" INTEGER NULL,
"GlobbingFilter" TEXT NULL
);
CREATE TABLE "SettingExtension" (
@@ -107,4 +108,4 @@ CREATE TABLE "EncryptionSetting" (
"Value" TEXT NULL
);
INSERT INTO "Version" ("Version") VALUES (7);
INSERT INTO "Version" ("Version") VALUES (8);
+48 -19
View File
@@ -114,6 +114,54 @@ namespace Duplicati.Datamodel
get { return new TaskExtensionWrapper(this); }
}
public string FilterXml
{
get
{
if (this.Filters.Count <= 0)
return "";
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
System.Xml.XmlNode root = doc.AppendChild(doc.CreateElement("root"));
foreach (TaskFilter f in this.SortedFilters)
{
System.Xml.XmlNode e = root.AppendChild(doc.CreateElement("filter"));
e.Attributes.Append(doc.CreateAttribute("include")).Value = f.Include.ToString();
e.Attributes.Append(doc.CreateAttribute("filter")).Value = f.Filter ?? "";
e.Attributes.Append(doc.CreateAttribute("globbing")).Value = f.GlobbingFilter ?? "";
}
return doc.OuterXml;
}
set
{
if (value == this.EncodedFilter)
return;
//Delete previous ones
this.SortedFilters = new TaskFilter[0];
if (string.IsNullOrEmpty(value))
return;
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(value);
List<TaskFilter> filters = new List<TaskFilter>();
foreach(System.Xml.XmlNode n in doc.SelectNodes("root/filter"))
{
TaskFilter tf = this.DataParent.Add<TaskFilter>();
tf.Include = bool.Parse(n.Attributes["include"].Value);
tf.GlobbingFilter = n.Attributes["globbing"].Value;
tf.Filter = n.Attributes["filter"].Value;
filters.Add(tf);
}
this.SortedFilters = filters.ToArray();
}
}
public string EncodedFilter
{
get
@@ -127,25 +175,6 @@ namespace Duplicati.Datamodel
return Library.Utility.FilenameFilter.EncodeAsFilter(filters);
}
set
{
if (value == this.EncodedFilter)
return;
//Delete previous ones
this.SortedFilters = new TaskFilter[0];
List<TaskFilter> filters = new List<TaskFilter>();
foreach (KeyValuePair<bool, string> f in Library.Utility.FilenameFilter.DecodeFilter(value))
{
TaskFilter tf = this.DataParent.Add<TaskFilter>();
tf.Filter = f.Value;
tf.Include = f.Key;
filters.Add(tf);
}
this.SortedFilters = filters.ToArray();
}
}
public bool ExistsInDb
+89 -80
View File
@@ -17,84 +17,93 @@
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
//
#endregion
/// <metadata>
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
/// <type>Table</type>
/// <namespace>Duplicati.Datamodel</namespace>
/// <name>TaskFilter</name>
/// <sql></sql>
/// </metadata>
using System.Data.LightDatamodel;
using System.Data.LightDatamodel.DataClassAttributes;
namespace Duplicati.Datamodel
{
[DatabaseTable("TaskFilter")]
public partial class TaskFilter : DataClassBase
{
#region " private members "
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
private System.Int64 m_ID = long.MinValue;
[DatabaseField("SortOrder")]
private System.Int64 m_SortOrder = long.MinValue;
[DatabaseField("Include")]
private System.Boolean m_Include = false;
[DatabaseField("Filter")]
private System.String m_Filter = "";
[Relation("TaskFilterTask", typeof(Task), "ID"), DatabaseField("TaskID")]
private System.Int64 m_TaskID = long.MinValue;
#endregion
#region " properties "
public System.Int64 ID
{
get{return m_ID;}
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
}
public System.Int64 SortOrder
{
get{return m_SortOrder;}
set{object oldvalue = m_SortOrder;OnBeforeDataChange(this, "SortOrder", oldvalue, value);m_SortOrder = value;OnAfterDataChange(this, "SortOrder", oldvalue, value);}
}
public System.Boolean Include
{
get{return m_Include;}
set{object oldvalue = m_Include;OnBeforeDataChange(this, "Include", oldvalue, value);m_Include = value;OnAfterDataChange(this, "Include", oldvalue, value);}
}
public System.String Filter
{
get{return m_Filter;}
set{object oldvalue = m_Filter;OnBeforeDataChange(this, "Filter", oldvalue, value);m_Filter = value;OnAfterDataChange(this, "Filter", oldvalue, value);}
}
public System.Int64 TaskID
{
get{return m_TaskID;}
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
}
#endregion
#region " referenced properties "
[Affects(typeof(Task))]
public Task Task
{
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("TaskFilterTask", this); }
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("TaskFilterTask", this, value); }
}
#endregion
}
/// <metadata>
/// <creator>This class was created by DataClassFileBuilder (LightDatamodel)</creator>
/// <provider name="System.Data.LightDatamodel.SQLiteDataProvider" connectionstring="Version=3;Data Source=D:\Dokumenter\duplicati\Duplicati\GUI\Datamodel\Duplicati.sqlite;" />
/// <type>Table</type>
/// <namespace>Duplicati.Datamodel</namespace>
/// <name>TaskFilter</name>
/// <sql></sql>
/// </metadata>
using System.Data.LightDatamodel;
using System.Data.LightDatamodel.DataClassAttributes;
namespace Duplicati.Datamodel
{
[DatabaseTable("TaskFilter")]
public partial class TaskFilter : DataClassBase
{
#region " private members "
[AutoIncrement, PrimaryKey, DatabaseField("ID")]
private System.Int64 m_ID = long.MinValue;
[DatabaseField("SortOrder")]
private System.Int64 m_SortOrder = long.MinValue;
[DatabaseField("Include")]
private System.Boolean m_Include = false;
[DatabaseField("Filter")]
private System.String m_Filter = "";
[Relation("TaskFilterTask", typeof(Task), "ID"), DatabaseField("TaskID")]
private System.Int64 m_TaskID = long.MinValue;
[DatabaseField("GlobbingFilter")]
private System.String m_GlobbingFilter = "";
#endregion
#region " properties "
public System.Int64 ID
{
get{return m_ID;}
set{object oldvalue = m_ID;OnBeforeDataChange(this, "ID", oldvalue, value);m_ID = value;OnAfterDataChange(this, "ID", oldvalue, value);}
}
public System.Int64 SortOrder
{
get{return m_SortOrder;}
set{object oldvalue = m_SortOrder;OnBeforeDataChange(this, "SortOrder", oldvalue, value);m_SortOrder = value;OnAfterDataChange(this, "SortOrder", oldvalue, value);}
}
public System.Boolean Include
{
get{return m_Include;}
set{object oldvalue = m_Include;OnBeforeDataChange(this, "Include", oldvalue, value);m_Include = value;OnAfterDataChange(this, "Include", oldvalue, value);}
}
public System.String Filter
{
get{return m_Filter;}
set{object oldvalue = m_Filter;OnBeforeDataChange(this, "Filter", oldvalue, value);m_Filter = value;OnAfterDataChange(this, "Filter", oldvalue, value);}
}
public System.Int64 TaskID
{
get{return m_TaskID;}
set{object oldvalue = m_TaskID;OnBeforeDataChange(this, "TaskID", oldvalue, value);m_TaskID = value;OnAfterDataChange(this, "TaskID", oldvalue, value);}
}
public System.String GlobbingFilter
{
get { return m_GlobbingFilter; }
set { object oldvalue = m_GlobbingFilter; OnBeforeDataChange(this, "GlobbingFilter", oldvalue, value); m_GlobbingFilter = value; OnAfterDataChange(this, "GlobbingFilter", oldvalue, value); }
}
#endregion
#region " referenced properties "
[Affects(typeof(Task))]
public Task Task
{
get{ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObject<Task>("TaskFilterTask", this); }
set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("TaskFilterTask", this, value); }
}
#endregion
}
}
+1
View File
@@ -1143,6 +1143,7 @@
<EmbeddedResource Include="Database schema\5. Remove signaturekey.sql" />
<EmbeddedResource Include="Database schema\6. Remove TimeSeparator and UseShortFilenames.sql" />
<EmbeddedResource Include="Database schema\7. Add error message field to log.sql" />
<EmbeddedResource Include="Database schema\8. Add filter fields.sql" />
<None Include="Resources\Play.png" />
<None Include="Resources\Delay.png" />
<None Include="Resources\Pause.png" />
+2
View File
@@ -68,6 +68,7 @@ namespace Duplicati.GUI.HelperControls
//
resources.ApplyResources(this.FilterText, "FilterText");
this.FilterText.Name = "FilterText";
this.FilterText.TextChanged += new System.EventHandler(this.FilterText_TextChanged);
//
// OKBtn
//
@@ -151,6 +152,7 @@ namespace Duplicati.GUI.HelperControls
this.Controls.Add(this.Inclusive);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
this.Name = "FilterDialog";
this.Activated += new System.EventHandler(this.FilterDialog_Activated);
this.Load += new System.EventHandler(this.FilterDialog_Load);
((System.ComponentModel.ISupportInitialize)(this.HelpImage)).EndInit();
this.ResumeLayout(false);
+82 -11
View File
@@ -30,15 +30,52 @@ namespace Duplicati.GUI.HelperControls
{
public partial class FilterDialog : Form
{
KeyValuePair<bool, string> m_filter;
public class FilterEntry
{
public FilterEntry(bool include, string filter, string globbing)
{
this.Include = include;
this.Filter = filter;
this.Globbing = globbing;
}
public FilterDialog(KeyValuePair<bool, string> filter)
public string Filter;
public bool Include;
public string Globbing;
public string DisplayValue { get { return string.IsNullOrEmpty(this.Globbing) ? this.Filter : this.Globbing; } }
public string ImageKey
{
get
{
return
(string.IsNullOrEmpty(this.Globbing) ? "regexp" : "globbing")
+ "-" +
(this.Include ? "include" : "exclude");
}
}
public override string ToString()
{
return this.DisplayValue;
}
public ListViewItem CreateListViewItem()
{
ListViewItem lvi = new ListViewItem(this.DisplayValue, this.ImageKey);
lvi.Tag = this;
return lvi;
}
}
FilterEntry m_filter;
public FilterDialog(FilterEntry filter)
: this()
{
m_filter = filter;
}
public KeyValuePair<bool, string> Filter
public FilterEntry Filter
{
get { return m_filter; }
}
@@ -50,7 +87,8 @@ namespace Duplicati.GUI.HelperControls
private void OKBtn_Click(object sender, EventArgs e)
{
string f;
string filter;
string globbing;
if (IsRegExp.Checked)
{
try
@@ -62,22 +100,44 @@ namespace Duplicati.GUI.HelperControls
MessageBox.Show(this, string.Format(Strings.FilterDialog.InvalidRegExpMessage, ex.Message), Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
return;
}
f = FilterText.Text;
filter = FilterText.Text;
globbing = null;
}
else
f = Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(FilterText.Text);
{
filter = Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(FilterText.Text);
globbing = FilterText.Text;
}
m_filter = new KeyValuePair<bool, string>(Inclusive.Checked, f);
m_filter = new FilterEntry(Inclusive.Checked, filter, globbing);
this.DialogResult = DialogResult.OK;
this.Close();
}
private void FilterDialog_Load(object sender, EventArgs e)
{
Inclusive.Checked = m_filter.Key;
Exclusive.Checked = !m_filter.Key;
FilterText.Text = m_filter.Value;
IsRegExp.Checked = !string.IsNullOrEmpty(m_filter.Value);
Inclusive.Checked = m_filter.Include;
Exclusive.Checked = !m_filter.Include;
FilterText.Text = m_filter.Filter;
if (string.IsNullOrEmpty(m_filter.Globbing))
{
if (string.IsNullOrEmpty(m_filter.Filter))
{
//New filter is default globbing
IsRegExp.Checked = false;
FilterText.Text = "";
}
else
{
IsRegExp.Checked = true;
FilterText.Text = m_filter.Filter;
}
}
else
{
IsRegExp.Checked = false;
FilterText.Text = m_filter.Globbing;
}
try { FilterText.Focus(); }
catch { }
@@ -111,5 +171,16 @@ namespace Duplicati.GUI.HelperControls
{
HelpImage_Click(sender, e);
}
private void FilterText_TextChanged(object sender, EventArgs e)
{
OKBtn.Enabled = FilterText.Text!= null && FilterText.Text.Trim().Length > 0;
}
private void FilterDialog_Activated(object sender, EventArgs e)
{
try { FilterText.Focus(); }
catch { }
}
}
}
+12 -9
View File
@@ -156,7 +156,7 @@
<value>170, 17</value>
</data>
<data name="Exclusive.TabIndex" type="System.Int32, mscorlib">
<value>1</value>
<value>2</value>
</data>
<data name="Exclusive.Text" xml:space="preserve">
<value>Exclude files matching the filter</value>
@@ -183,7 +183,7 @@
<value>29, 13</value>
</data>
<data name="label1.TabIndex" type="System.Int32, mscorlib">
<value>2</value>
<value>3</value>
</data>
<data name="label1.Text" xml:space="preserve">
<value>Filter</value>
@@ -207,7 +207,7 @@
<value>272, 20</value>
</data>
<data name="FilterText.TabIndex" type="System.Int32, mscorlib">
<value>3</value>
<value>5</value>
</data>
<data name="&gt;&gt;FilterText.Name" xml:space="preserve">
<value>FilterText</value>
@@ -221,6 +221,9 @@
<data name="&gt;&gt;FilterText.ZOrder" xml:space="preserve">
<value>4</value>
</data>
<data name="OKBtn.Enabled" type="System.Boolean, mscorlib">
<value>False</value>
</data>
<data name="OKBtn.Location" type="System.Drawing.Point, System.Drawing">
<value>112, 96</value>
</data>
@@ -228,7 +231,7 @@
<value>75, 23</value>
</data>
<data name="OKBtn.TabIndex" type="System.Int32, mscorlib">
<value>4</value>
<value>8</value>
</data>
<data name="OKBtn.Text" xml:space="preserve">
<value>OK</value>
@@ -252,7 +255,7 @@
<value>75, 23</value>
</data>
<data name="CancelBtn.TabIndex" type="System.Int32, mscorlib">
<value>5</value>
<value>9</value>
</data>
<data name="CancelBtn.Text" xml:space="preserve">
<value>Cancel</value>
@@ -279,7 +282,7 @@
<value>146, 17</value>
</data>
<data name="IsRegExp.TabIndex" type="System.Int32, mscorlib">
<value>6</value>
<value>4</value>
</data>
<data name="IsRegExp.Text" xml:space="preserve">
<value>Filter is regular expression</value>
@@ -307,7 +310,7 @@
<value>24, 24</value>
</data>
<data name="BrowseFolderButton.TabIndex" type="System.Int32, mscorlib">
<value>7</value>
<value>6</value>
</data>
<data name="&gt;&gt;BrowseFolderButton.Name" xml:space="preserve">
<value>BrowseFolderButton</value>
@@ -334,7 +337,7 @@
<value>24, 24</value>
</data>
<data name="BrowseFileButton.TabIndex" type="System.Int32, mscorlib">
<value>8</value>
<value>7</value>
</data>
<data name="BrowseFileButton.Text" xml:space="preserve">
<value>...</value>
@@ -376,7 +379,7 @@
<value>52, 13</value>
</data>
<data name="HelpLink.TabIndex" type="System.Int32, mscorlib">
<value>9</value>
<value>1</value>
</data>
<data name="HelpLink.Text" xml:space="preserve">
<value>Filter help</value>
+207 -205
View File
@@ -28,74 +28,76 @@ namespace Duplicati.GUI.HelperControls
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterEditor));
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.listView = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.imageList = new System.Windows.Forms.ImageList(this.components);
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.AddFilterButton = new System.Windows.Forms.ToolStripButton();
this.RemoveFilterButton = new System.Windows.Forms.ToolStripButton();
this.EditFilterButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.IncludeFolderButton = new System.Windows.Forms.ToolStripButton();
this.ExcludeFolderButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.MoveFilterUpButton = new System.Windows.Forms.ToolStripButton();
this.MoveFilterDownButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.MoveFilterTopButton = new System.Windows.Forms.ToolStripButton();
this.MoveFilterBottomButton = new System.Windows.Forms.ToolStripButton();
this.HelpButton = new System.Windows.Forms.ToolStripButton();
this.btnTestSearch = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.FilenameTester = new System.Windows.Forms.TextBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.TestResults = new System.Windows.Forms.PictureBox();
this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
this.groupBox1.SuspendLayout();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.TestResults)).BeginInit();
this.SuspendLayout();
//
// groupBox1
//
resources.ApplyResources(this.groupBox1, "groupBox1");
this.groupBox1.Controls.Add(this.listView);
this.groupBox1.Controls.Add(this.toolStrip1);
this.groupBox1.Name = "groupBox1";
this.groupBox1.TabStop = false;
//
// listView
//
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.components = new System.ComponentModel.Container();
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FilterEditor));
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.listView = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.imageList = new System.Windows.Forms.ImageList(this.components);
this.toolStrip1 = new System.Windows.Forms.ToolStrip();
this.AddFilterButton = new System.Windows.Forms.ToolStripButton();
this.RemoveFilterButton = new System.Windows.Forms.ToolStripButton();
this.EditFilterButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator3 = new System.Windows.Forms.ToolStripSeparator();
this.IncludeFolderButton = new System.Windows.Forms.ToolStripButton();
this.ExcludeFolderButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator1 = new System.Windows.Forms.ToolStripSeparator();
this.MoveFilterUpButton = new System.Windows.Forms.ToolStripButton();
this.MoveFilterDownButton = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator2 = new System.Windows.Forms.ToolStripSeparator();
this.MoveFilterTopButton = new System.Windows.Forms.ToolStripButton();
this.MoveFilterBottomButton = new System.Windows.Forms.ToolStripButton();
this.HelpButton = new System.Windows.Forms.ToolStripButton();
this.btnTestSearch = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.FilenameTester = new System.Windows.Forms.TextBox();
this.toolTip = new System.Windows.Forms.ToolTip(this.components);
this.TestResults = new System.Windows.Forms.PictureBox();
this.folderBrowserDialog = new System.Windows.Forms.FolderBrowserDialog();
this.groupBox1.SuspendLayout();
this.toolStrip1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.TestResults)).BeginInit();
this.SuspendLayout();
//
// groupBox1
//
resources.ApplyResources(this.groupBox1, "groupBox1");
this.groupBox1.Controls.Add(this.listView);
this.groupBox1.Controls.Add(this.toolStrip1);
this.groupBox1.Name = "groupBox1";
this.groupBox1.TabStop = false;
//
// listView
//
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1});
resources.ApplyResources(this.listView, "listView");
this.listView.FullRowSelect = true;
this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
this.listView.Name = "listView";
this.listView.SmallImageList = this.imageList;
this.listView.UseCompatibleStateImageBehavior = false;
this.listView.View = System.Windows.Forms.View.Details;
this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
this.listView.DoubleClick += new System.EventHandler(this.listView_DoubleClick);
//
// columnHeader1
//
resources.ApplyResources(this.columnHeader1, "columnHeader1");
//
// imageList
//
this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream")));
this.imageList.TransparentColor = System.Drawing.Color.Transparent;
this.imageList.Images.SetKeyName(0, "Inclusion.ico");
this.imageList.Images.SetKeyName(1, "Exclusion.ico");
//
// toolStrip1
//
this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
resources.ApplyResources(this.listView, "listView");
this.listView.FullRowSelect = true;
this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
this.listView.Name = "listView";
this.listView.SmallImageList = this.imageList;
this.listView.UseCompatibleStateImageBehavior = false;
this.listView.View = System.Windows.Forms.View.Details;
this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
this.listView.DoubleClick += new System.EventHandler(this.listView_DoubleClick);
//
// columnHeader1
//
resources.ApplyResources(this.columnHeader1, "columnHeader1");
//
// imageList
//
this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream")));
this.imageList.TransparentColor = System.Drawing.Color.Transparent;
this.imageList.Images.SetKeyName(0, "globbing-include");
this.imageList.Images.SetKeyName(1, "globbing-exclude");
this.imageList.Images.SetKeyName(2, "regexp-include");
this.imageList.Images.SetKeyName(3, "regexp-exclude");
//
// toolStrip1
//
this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.AddFilterButton,
this.RemoveFilterButton,
this.EditFilterButton,
@@ -109,144 +111,144 @@ namespace Duplicati.GUI.HelperControls
this.MoveFilterTopButton,
this.MoveFilterBottomButton,
this.HelpButton});
resources.ApplyResources(this.toolStrip1, "toolStrip1");
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
//
// AddFilterButton
//
this.AddFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.AddFilterButton, "AddFilterButton");
this.AddFilterButton.Name = "AddFilterButton";
this.AddFilterButton.Click += new System.EventHandler(this.AddFilterButton_Click);
//
// RemoveFilterButton
//
this.RemoveFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.RemoveFilterButton, "RemoveFilterButton");
this.RemoveFilterButton.Name = "RemoveFilterButton";
this.RemoveFilterButton.Click += new System.EventHandler(this.RemoveFilterButton_Click);
//
// EditFilterButton
//
this.EditFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.EditFilterButton, "EditFilterButton");
this.EditFilterButton.Name = "EditFilterButton";
this.EditFilterButton.Click += new System.EventHandler(this.EditFilterButton_Click);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3");
//
// IncludeFolderButton
//
this.IncludeFolderButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.IncludeFolderButton.Image = global::Duplicati.GUI.Properties.Resources.AddedFolder;
resources.ApplyResources(this.IncludeFolderButton, "IncludeFolderButton");
this.IncludeFolderButton.Name = "IncludeFolderButton";
this.IncludeFolderButton.Click += new System.EventHandler(this.IncludeFolderButton_Click);
//
// ExcludeFolderButton
//
this.ExcludeFolderButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.ExcludeFolderButton.Image = global::Duplicati.GUI.Properties.Resources.DeletedFolder;
resources.ApplyResources(this.ExcludeFolderButton, "ExcludeFolderButton");
this.ExcludeFolderButton.Name = "ExcludeFolderButton";
this.ExcludeFolderButton.Click += new System.EventHandler(this.ExcludeFolderButton_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1");
//
// MoveFilterUpButton
//
this.MoveFilterUpButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterUpButton, "MoveFilterUpButton");
this.MoveFilterUpButton.Name = "MoveFilterUpButton";
this.MoveFilterUpButton.Click += new System.EventHandler(this.MoveFilterUpButton_Click);
//
// MoveFilterDownButton
//
this.MoveFilterDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterDownButton, "MoveFilterDownButton");
this.MoveFilterDownButton.Name = "MoveFilterDownButton";
this.MoveFilterDownButton.Click += new System.EventHandler(this.MoveFilterDownButton_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
resources.ApplyResources(this.toolStripSeparator2, "toolStripSeparator2");
//
// MoveFilterTopButton
//
this.MoveFilterTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterTopButton, "MoveFilterTopButton");
this.MoveFilterTopButton.Name = "MoveFilterTopButton";
this.MoveFilterTopButton.Click += new System.EventHandler(this.MoveFilterTopButton_Click);
//
// MoveFilterBottomButton
//
this.MoveFilterBottomButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterBottomButton, "MoveFilterBottomButton");
this.MoveFilterBottomButton.Name = "MoveFilterBottomButton";
this.MoveFilterBottomButton.Click += new System.EventHandler(this.MoveFilterBottomButton_Click);
//
// HelpButton
//
this.HelpButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.HelpButton.Image = global::Duplicati.GUI.Properties.Resources.help;
resources.ApplyResources(this.HelpButton, "HelpButton");
this.HelpButton.Name = "HelpButton";
this.HelpButton.Click += new System.EventHandler(this.HelpButton_Click);
//
// btnTestSearch
//
resources.ApplyResources(this.btnTestSearch, "btnTestSearch");
this.btnTestSearch.Name = "btnTestSearch";
this.btnTestSearch.UseVisualStyleBackColor = true;
this.btnTestSearch.Click += new System.EventHandler(this.btnTestSearch_Click);
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// FilenameTester
//
resources.ApplyResources(this.FilenameTester, "FilenameTester");
this.FilenameTester.Name = "FilenameTester";
this.FilenameTester.TextChanged += new System.EventHandler(this.FilenameTester_TextChanged);
//
// TestResults
//
resources.ApplyResources(this.TestResults, "TestResults");
this.TestResults.Name = "TestResults";
this.TestResults.TabStop = false;
//
// folderBrowserDialog
//
this.folderBrowserDialog.ShowNewFolderButton = false;
//
// FilterEditor
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnTestSearch);
this.Controls.Add(this.TestResults);
this.Controls.Add(this.FilenameTester);
this.Controls.Add(this.label1);
this.Controls.Add(this.groupBox1);
this.Name = "FilterEditor";
this.Load += new System.EventHandler(this.FilterEditor_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.TestResults)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
resources.ApplyResources(this.toolStrip1, "toolStrip1");
this.toolStrip1.Name = "toolStrip1";
this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
//
// AddFilterButton
//
this.AddFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.AddFilterButton, "AddFilterButton");
this.AddFilterButton.Name = "AddFilterButton";
this.AddFilterButton.Click += new System.EventHandler(this.AddFilterButton_Click);
//
// RemoveFilterButton
//
this.RemoveFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.RemoveFilterButton, "RemoveFilterButton");
this.RemoveFilterButton.Name = "RemoveFilterButton";
this.RemoveFilterButton.Click += new System.EventHandler(this.RemoveFilterButton_Click);
//
// EditFilterButton
//
this.EditFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.EditFilterButton, "EditFilterButton");
this.EditFilterButton.Name = "EditFilterButton";
this.EditFilterButton.Click += new System.EventHandler(this.EditFilterButton_Click);
//
// toolStripSeparator3
//
this.toolStripSeparator3.Name = "toolStripSeparator3";
resources.ApplyResources(this.toolStripSeparator3, "toolStripSeparator3");
//
// IncludeFolderButton
//
this.IncludeFolderButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.IncludeFolderButton.Image = global::Duplicati.GUI.Properties.Resources.AddedFolder;
resources.ApplyResources(this.IncludeFolderButton, "IncludeFolderButton");
this.IncludeFolderButton.Name = "IncludeFolderButton";
this.IncludeFolderButton.Click += new System.EventHandler(this.IncludeFolderButton_Click);
//
// ExcludeFolderButton
//
this.ExcludeFolderButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.ExcludeFolderButton.Image = global::Duplicati.GUI.Properties.Resources.DeletedFolder;
resources.ApplyResources(this.ExcludeFolderButton, "ExcludeFolderButton");
this.ExcludeFolderButton.Name = "ExcludeFolderButton";
this.ExcludeFolderButton.Click += new System.EventHandler(this.ExcludeFolderButton_Click);
//
// toolStripSeparator1
//
this.toolStripSeparator1.Name = "toolStripSeparator1";
resources.ApplyResources(this.toolStripSeparator1, "toolStripSeparator1");
//
// MoveFilterUpButton
//
this.MoveFilterUpButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterUpButton, "MoveFilterUpButton");
this.MoveFilterUpButton.Name = "MoveFilterUpButton";
this.MoveFilterUpButton.Click += new System.EventHandler(this.MoveFilterUpButton_Click);
//
// MoveFilterDownButton
//
this.MoveFilterDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterDownButton, "MoveFilterDownButton");
this.MoveFilterDownButton.Name = "MoveFilterDownButton";
this.MoveFilterDownButton.Click += new System.EventHandler(this.MoveFilterDownButton_Click);
//
// toolStripSeparator2
//
this.toolStripSeparator2.Name = "toolStripSeparator2";
resources.ApplyResources(this.toolStripSeparator2, "toolStripSeparator2");
//
// MoveFilterTopButton
//
this.MoveFilterTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterTopButton, "MoveFilterTopButton");
this.MoveFilterTopButton.Name = "MoveFilterTopButton";
this.MoveFilterTopButton.Click += new System.EventHandler(this.MoveFilterTopButton_Click);
//
// MoveFilterBottomButton
//
this.MoveFilterBottomButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
resources.ApplyResources(this.MoveFilterBottomButton, "MoveFilterBottomButton");
this.MoveFilterBottomButton.Name = "MoveFilterBottomButton";
this.MoveFilterBottomButton.Click += new System.EventHandler(this.MoveFilterBottomButton_Click);
//
// HelpButton
//
this.HelpButton.Alignment = System.Windows.Forms.ToolStripItemAlignment.Right;
this.HelpButton.Image = global::Duplicati.GUI.Properties.Resources.help;
resources.ApplyResources(this.HelpButton, "HelpButton");
this.HelpButton.Name = "HelpButton";
this.HelpButton.Click += new System.EventHandler(this.HelpButton_Click);
//
// btnTestSearch
//
resources.ApplyResources(this.btnTestSearch, "btnTestSearch");
this.btnTestSearch.Name = "btnTestSearch";
this.btnTestSearch.UseVisualStyleBackColor = true;
this.btnTestSearch.Click += new System.EventHandler(this.btnTestSearch_Click);
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// FilenameTester
//
resources.ApplyResources(this.FilenameTester, "FilenameTester");
this.FilenameTester.Name = "FilenameTester";
this.FilenameTester.TextChanged += new System.EventHandler(this.FilenameTester_TextChanged);
//
// TestResults
//
resources.ApplyResources(this.TestResults, "TestResults");
this.TestResults.Name = "TestResults";
this.TestResults.TabStop = false;
//
// folderBrowserDialog
//
this.folderBrowserDialog.ShowNewFolderButton = false;
//
// FilterEditor
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.btnTestSearch);
this.Controls.Add(this.TestResults);
this.Controls.Add(this.FilenameTester);
this.Controls.Add(this.label1);
this.Controls.Add(this.groupBox1);
this.Name = "FilterEditor";
this.Load += new System.EventHandler(this.FilterEditor_Load);
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.toolStrip1.ResumeLayout(false);
this.toolStrip1.PerformLayout();
((System.ComponentModel.ISupportInitialize)(this.TestResults)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
+74 -22
View File
@@ -50,33 +50,61 @@ namespace Duplicati.GUI.HelperControls
/// </summary>
/// <param name="includeDynamicFilters">if set to <c>true</c> include dynamic filters.</param>
/// <returns>A list of filters</returns>
private List<KeyValuePair<bool, string>> GetFilterList(bool includeDynamicFilters)
private List<FilterDialog.FilterEntry> GetFilterList(bool includeDynamicFilters)
{
List<KeyValuePair<bool, string>> filters = new List<KeyValuePair<bool, string>>();
List<FilterDialog.FilterEntry> filters = new List<FilterDialog.FilterEntry>();
foreach (ListViewItem lvi in listView.Items)
filters.Add(new KeyValuePair<bool, string>(lvi.ImageIndex == 0, lvi.Text));
filters.Add(lvi.Tag as FilterDialog.FilterEntry);
if (includeDynamicFilters && !string.IsNullOrEmpty(m_dynamicFilter))
{
List<KeyValuePair<bool, string>> tmp = Library.Utility.FilenameFilter.DecodeFilter(m_dynamicFilter);
tmp.AddRange(filters);
filters = tmp;
List<KeyValuePair<bool, string>> tmp1 = Library.Utility.FilenameFilter.DecodeFilter(m_dynamicFilter);
List<FilterDialog.FilterEntry> tmp2 = new List<FilterDialog.FilterEntry>();
foreach (KeyValuePair<bool, string> k in tmp1)
tmp2.Add(new FilterDialog.FilterEntry(k.Key, k.Value, null));
tmp2.AddRange(filters);
filters = tmp2;
}
return filters;
}
private string EncodeAsFilter(List<FilterDialog.FilterEntry> items)
{
List<KeyValuePair<bool, string>> r = new List<KeyValuePair<bool, string>>();
foreach (FilterDialog.FilterEntry f in items)
r.Add(new KeyValuePair<bool, string>(f.Include, f.Filter));
return Duplicati.Library.Utility.FilenameFilter.EncodeAsFilter(r);
}
/// <summary>
/// Gets or sets the filter string as displayed in the UI
/// </summary>
[DefaultValue("")]
public string Filter
public string FilterXml
{
get { return Library.Utility.FilenameFilter.EncodeAsFilter(GetFilterList(false)); }
get { return EncodeFilterAsXml(GetFilterList(false)); }
set { m_filter = value; RefreshList(); FilenameTester_TextChanged(null, null); }
}
private string EncodeFilterAsXml(List<FilterDialog.FilterEntry> list)
{
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
System.Xml.XmlNode root = doc.AppendChild(doc.CreateElement("root"));
foreach (FilterDialog.FilterEntry f in list)
{
System.Xml.XmlNode filter = root.AppendChild(doc.CreateElement("filter"));
filter.Attributes.Append(doc.CreateAttribute("include")).Value = f.Include.ToString();
filter.Attributes.Append(doc.CreateAttribute("filter")).Value = f.Filter;
filter.Attributes.Append(doc.CreateAttribute("globbing")).Value = f.Globbing;
}
return doc.OuterXml;
}
/// <summary>
/// Gets or sets the dynamic filter, which is applied to the test area, but not visible in the list
/// </summary>
@@ -103,13 +131,33 @@ namespace Duplicati.GUI.HelperControls
private void RefreshList()
{
listView.Items.Clear();
foreach (KeyValuePair<bool, string> f in Library.Utility.FilenameFilter.DecodeFilter(m_filter))
listView.Items.Add(f.Value, f.Key ? 0 : 1);
foreach (FilterDialog.FilterEntry f in DecodeFilter(m_filter))
listView.Items.Add(f.CreateListViewItem());
if (listView.Items.Count > 0)
listView.Items[0].Selected = true;
}
private List<FilterDialog.FilterEntry> DecodeFilter(string filter)
{
List<FilterDialog.FilterEntry> res = new List<FilterDialog.FilterEntry>();
if (string.IsNullOrEmpty(filter))
return res;
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(filter);
foreach (System.Xml.XmlNode n in doc.SelectNodes("root/filter"))
{
res.Add(new FilterDialog.FilterEntry(
bool.Parse(n.Attributes["include"].Value),
n.Attributes["filter"].Value,
n.Attributes["globbing"].Value
));
}
return res;
}
/// <summary>
/// Handles the TextChanged event of the FilenameTester control.
/// Used to update the status and tooltip to show if the current path is included or excluded
@@ -194,7 +242,8 @@ namespace Duplicati.GUI.HelperControls
parentFolders.Reverse();
//Test if any of the parent folders are excluded
Library.Utility.FilenameFilter fn = new Duplicati.Library.Utility.FilenameFilter(GetFilterList(true));
string compact = EncodeAsFilter(GetFilterList(true));
Library.Utility.FilenameFilter fn = new Duplicati.Library.Utility.FilenameFilter(Duplicati.Library.Utility.FilenameFilter.DecodeFilter(compact));
Library.Utility.IFilenameFilter match;
foreach (string s in parentFolders)
{
@@ -275,13 +324,14 @@ namespace Duplicati.GUI.HelperControls
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void EditFilterButton_Click(object sender, EventArgs e)
{
if (listView.SelectedItems.Count == 1)
if (listView.SelectedItems.Count == 1 && listView.SelectedItems[0].Tag is FilterDialog.FilterEntry)
{
FilterDialog dlg = new FilterDialog(new KeyValuePair<bool, string>(listView.SelectedItems[0].ImageIndex == 0, listView.SelectedItems[0].Text));
FilterDialog dlg = new FilterDialog((FilterDialog.FilterEntry)listView.SelectedItems[0].Tag);
if (dlg.ShowDialog(this) == DialogResult.OK)
{
listView.SelectedItems[0].Text = dlg.Filter.Value;
listView.SelectedItems[0].ImageIndex = dlg.Filter.Key ? 0 : 1;
listView.SelectedItems[0].Tag = dlg.Filter;
listView.SelectedItems[0].Text = dlg.Filter.DisplayValue;
listView.SelectedItems[0].ImageKey = dlg.Filter.ImageKey;
FilenameTester_TextChanged(sender, e);
}
}
@@ -366,10 +416,10 @@ namespace Duplicati.GUI.HelperControls
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
private void AddFilterButton_Click(object sender, EventArgs e)
{
FilterDialog dlg = new FilterDialog(new KeyValuePair<bool, string>(true, ""));
FilterDialog dlg = new FilterDialog(new FilterDialog.FilterEntry(false, null, null));
if (dlg.ShowDialog(this) == DialogResult.OK)
{
listView.Items.Add(dlg.Filter.Value, dlg.Filter.Key ? 0 : 1);
listView.Items.Add(dlg.Filter.CreateListViewItem());
FilenameTester_TextChanged(sender, e);
}
}
@@ -417,7 +467,9 @@ namespace Duplicati.GUI.HelperControls
folderBrowserDialog.Description = Strings.FilterEditor.IncludeFolderBrowseTitle;
if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK)
{
listView.Items.Add(Duplicati.Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(Duplicati.Library.Utility.Utility.AppendDirSeparator(folderBrowserDialog.SelectedPath)), 0);
string path = Duplicati.Library.Utility.Utility.AppendDirSeparator(folderBrowserDialog.SelectedPath);
FilterDialog.FilterEntry fe = new FilterDialog.FilterEntry(true, Duplicati.Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(path), path);
listView.Items.Add(fe.CreateListViewItem());
FilenameTester_TextChanged(sender, e);
}
}
@@ -432,7 +484,9 @@ namespace Duplicati.GUI.HelperControls
folderBrowserDialog.Description = Strings.FilterEditor.ExcludeFolderBrowseTitle;
if (folderBrowserDialog.ShowDialog(this) == DialogResult.OK)
{
listView.Items.Add(Duplicati.Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(Duplicati.Library.Utility.Utility.AppendDirSeparator(folderBrowserDialog.SelectedPath)), 1);
string path = Duplicati.Library.Utility.Utility.AppendDirSeparator(folderBrowserDialog.SelectedPath);
FilterDialog.FilterEntry fe = new FilterDialog.FilterEntry(false, Duplicati.Library.Utility.FilenameFilter.ConvertGlobbingToRegExp(path), path);
listView.Items.Add(fe.CreateListViewItem());
FilenameTester_TextChanged(sender, e);
}
}
@@ -447,9 +501,7 @@ namespace Duplicati.GUI.HelperControls
{
listView.Items.Clear();
foreach (var filter in dlg.Filters)
{
listView.Items.Add(filter.Value, filter.Key ? 0 : 1);
}
listView.Items.Add(filter.CreateListViewItem());
}
}
+52 -22
View File
@@ -142,27 +142,57 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACC
BAAAAk1TRnQBSQFMAgEBAgEAATwBAAE8AQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABEAMAAQEBAAEgBgABEP8AKwADEwEaASwCKwFDASwCKwFDASwCKwFD8AADVQGyAVIB4gGMAf8BUQHh
AYkB/wFDAcgBawH/8AADVQGyAUYB1AFmAf8BPQHLAU0B/wFDAckBawH/8AADVQGyAU4B2gFwAf8BPgHM
AU8B/wFDAcoBawH/8AADVQGyAVoB4wGBAf8BSgHUAVwB/wFEAcsBbAH/4AABPgGaATwB/gFNAdMBcgH/
AU0B1AF0Af8BTgHUAXQB/wFNAdMBcwH/AWYB6gGEAf8BWQHfAWwB/wFXAeMBkAH/AUQBygFqAf8BQgHI
AWkB/wFBAcYBZwH/AUEBxQFnAf8DMAFMDAADSAGEAkkB0wH/AksB1AH/Ak0B1AH/Ak4B0wH/Ak0B0AH/
AkoBzAH/AkYBxwH/AkIBwwH/AkABwgH/AkABwgH/Ai8BqAH/kAABQQGfAUEB/gFiAdoBdQH/AWsB5AGB
Af8BcQHsAYYB/wF0AfABigH/AXEB7wGHAf8BaAHqAYEB/wFbAeEBbwH/AU4B1wFgAf8BQgHOAVMB/wE9
AcsBTQH/AVAB4AGHAf8DMAFMDAADSAGEAlsB1wH/AmIB1gH/Am4B5AH/AnYB7gH/AnYB8AH/AmoB6QH/
AlcB3AH/AkcB0AH/AkIBzAH/AkIBzAH/AjkBtwH/kAABQQGgAUEB/gFbAdYBgQH/AWMB3wGFAf8BagHn
AY0B/wFvAe4BkwH/AXQB7wGKAf8BcgHwAYgB/wFqAewBhgH/AV8B5wGCAf8BVAHeAXYB/wFKAdcBawH/
AVEB4QGKAf8DMAFMDAADSAGEAlwB2gH/AmMB3QH/Am0B6AH/AnMB8AH/AnMB8gH/AmoB7AH/AlsB4gH/
Ak0B2AH/AkgB1AH/AkgB1AH/AjkBtwH/kAABVgJVAbEDVQG1A1UBtQNVAbUBVwFSAUkB6AFvAe0BkwH/
AXQB7wGJAf8BUAHWAYEB/wNVAbUDVQG1A1UBtQNVAbUDGAEhDAADLQFGA1UBtQNVAbUDVQG1A1UBtQNV
AbUDVQG1A1UBtQNVAbUDVQG1A1UBtQFWAlUBtKAAA1UBsgFoAeUBiwH/AW8B6AGDAf8BUAHWAYEB//AA
A1UBsgFfAdsBgQH/AWYB3gGAAf8BTwHVAXgB//AAA1UBsgFWAdIBdwH/AVsB0wFuAf8BTgHUAXYB//AA
A1QBqwExAbkBNgH/ATEBuAE2Af8BLwG1ATIB//8A/wDaAAFCAU0BPgcAAT4DAAEoAwABQAMAARADAAEB
AQABAQUAAYAXAAP/AQAE/wQAAfwBPwL/BAAB/AE/Av8EAAH8AT8C/wQAAfwBPwL/BAAB/AE/Av8EAAHA
AQEBwAEDBAABwAEBAcABAwQAAcABAQHAAQMEAAHAAQEBwAEDBAAB/AE/Av8EAAH8AT8C/wQAAfwBPwL/
BAAB/AE/Av8EAAT/BAAE/wQACw==
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACg
CwAAAk1TRnQBSQFMAgEBBAEAAUQBAAFEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABIAMAAQEBAAEgBgABIP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wA7AAMTARoBLAIr
AUMBLAIrAUMBLAIrAUPwAANVAbIBUQHiAYwB/wFQAeEBiQH/AUIByAFqAf/wAANVAbIBRQHUAWUB/wE8
AcsBTAH/AUIByQFqAf9cAAEoAaQBKAH/ASgBpAEoAf8MAAEtAZoBLgH2ASgBpAEoAf8BKgGiASsB/QEo
AaQBKAH/ASIBJgEiATEIAAMIAQsBKAGkASgB/wEoAaQBKAH/BAACKAGkAf8CKAGkAf8MAAItAZ0B9gIo
AaQB/wIqAaMB/QIoAaQB/wIiASYBMQgAAggBCQELAigBpAH/AigBpAH/GAADVQGyAU0B2gFvAf8BPQHM
AU4B/wFCAcoBagH/XAABQgHIAWUB/wFNAdgBfgH/CAABJgErASYBOAFGAdEBaQH/AT4BxQFXAf8BLwGW
ATMB7gFNAdwBeAH/ASoBpwEtAf8IAAEqAaIBKwH9AVsB6wGfAf8BKAGkASgB/wQAAkoByAH/AlsB2gH/
CAACJgErATgCUAHTAf8CRQHGAf8BLwExAZgB7gJZAd0B/wIrAacB/wgAAioBowH9Am0B7AH/AikBogH+
GAADVQGyAVkB4wGBAf8BSQHUAVsB/wFDAcsBawH/XAABQQHHAWIB/wFMAdYBeQH/CAABKAGkASgB/wFK
AdkBcQH/ATABmAEzAfEEAAEtAawBNAH/AUsB2gFzAf8BOgGHAT0BzgFAAWEBRAGMAVIB4AGIAf8BPAHA
AVYB/wEMAQ0BDAEQBAACSgHIAf8CWgHYAf8IAAIoAaQB/wFVAVQB2gH/ATABMQGaAfEEAAIvAa0B/wJX
AdwB/wE6AT0BiAHOAUABQgFhAYwCYgHjAf8CRAHCAf8CDAENARAIAAE+AZgBPAH+AUwB0wFxAf8BTAHU
AXMB/wFNAdQBcwH/AUwB0wFyAf8BZQHqAYQB/wFYAd8BawH/AVYB4wGQAf8BQwHKAWkB/wFBAcgBaAH/
AUABxgFmAf8BQAHFAWYB/wMwAUwMAANIAYQCSAHTAf8CSgHUAf8CTAHUAf8CTQHTAf8CTAHQAf8CSQHM
Af8CRQHHAf8CQQHDAf8CPwHCAf8CPwHCAf8CLgGoAf8MAAFBAcYBYQH/AUsB1QF3Af8BKQExASkCPwF0
AUUBrwFGAdIBaAH/AToBwAFNAf8BDgEPAQ4BEwQAATUBQgE3AVoBQQHMAV4B/wE9AcUBVgH/ATUBtwFF
Af8BUgHgAYcB/wFBAW0BRQGhCAACSgHIAf8CWAHXAf8CKQExAj8BQgF2Aa8CTwHUAf8CPwHCAf8CDgEP
ARMEAAE1ATYBQwFaAkoBzgH/AkUBxwH/AjoBuAH/AmIB4wH/AUEBRAFvAaEMAAFBAZ0BQQH+AWEB2gF0
Af8BagHkAYEB/wFwAewBhgH/AXMB8AGKAf8BcAHvAYcB/wFnAeoBgQH/AVoB4QFuAf8BTQHXAV8B/wFB
Ac4BUgH/ATwBywFMAf8BTwHgAYcB/wMwAUwMAANIAYQCWgHXAf8CYQHWAf8CbQHkAf8CdQHuAf8CdQHw
Af8CaQHpAf8CVgHcAf8CRgHQAf8CQQHMAf8CQQHMAf8COAG3Af8MAAFAAcYBYAH/AVUB5QGPAf8BUQHg
AYQB/wFNAdwBeAH/AUMBzgFgAf8BNAGTATcB5gwAATIBlgE1AesBSwHZAXIB/wFPAd4BfQH/ASgBpAEo
Af8MAAJKAccB/wJnAecB/wJgAeIB/wJZAd4B/wFMAUsB0AH/ATQBNgGUAeYMAAEyATUBlwHrAlcB2wH/
Al0B4AH/AigBpAH/EAABQQGeAUEB/gFaAdYBgQH/AWIB3wGFAf8BaQHnAY0B/wFuAe4BkwH/AXMB7wGK
Af8BcQHwAYgB/wFpAewBhgH/AV4B5wGCAf8BUwHeAXUB/wFJAdcBagH/AVAB4QGKAf8DMAFMDAADSAGE
AlsB2gH/AmIB3QH/AmwB6AH/AnIB8AH/AnIB8gH/AmkB7AH/AloB4gH/AkwB2AH/AkcB1AH/AkcB1AH/
AjgBtwH/DAABQAHGAWAB/wFKAdUBdQH/ASgBpAEoAf8BKAGlASkB/wFHAdUBaQH/ATgBvwFKAf8DCQEM
CAABPwFcAUQBhQFHAdQBagH/AU8B3gF8Af8BLQGeAS8B9wwAAkoBxwH/AlcB1gH/AigBpAH/AikBpQH/
AVIBUQHXAf8CPgHBAf8DCQEMCAABPwFBAV4BhQJSAdYB/wJdAeAB/wEtAS4BnwH3EAABVgJVAbEDVQG1
A1UBtQNVAbUBVwFVAU0B6AFuAe0BkwH/AXMB7wGJAf8BTwHWAYEB/wNVAbUDVQG1A1UBtQNVAbUDGAEh
DAADLQFGA1UBtQNVAbUDVQG1A1UBtQNVAbUDVQG1A1UBtQNVAbUDVQG1A1UBtQFWAlUBtAwAAUEBxgFg
Af8BSgHVAXYB/wgAATEBswE8Af8BRgHVAWYB/wE2AUYBOAFfBAADBAEGATEBswE8Af8BSgHYAXAB/wE7
AcEBUwH/AU4B2wF9Af8BPQFWAUEBeQgAAkoByAH/AlgB1wH/CAACNQG0Af8CUAHXAf8BNgE3AUcBXwQA
AwQBBgI1AbQB/wJXAdsB/wJDAcMB/wJdAd4B/wE9AUABVwF5HAADVQGyAWcB5QGLAf8BbgHoAYMB/wFP
AdYBgQH/XAABQQHHAWIB/wFLAdYBeAH/AUEBcQFBAZ8BOgGGAUAB0AFDAc4BYwH/AUYB0wFnAf8BJgEr
ASYBOAQAASkBnQErAfsBSgHZAXEB/wEoAaQBKAH/AT8BeAFEAbQBVAHjAYwB/wE1AbYBRQH/AwMBBAQA
AkoByAH/AloB2AH/AkEBcQGfAToBPgGJAdACTgHQAf8CUQHVAf8CJgErATgEAAEpASoBngH7AlcB3AH/
AigBpAH/AT8BQgF6AbQCZgHmAf8COgG3Af8DAwEEGAADVQGyAV4B2wGBAf8BZQHeAYAB/wFOAdUBdwH/
XAABQgHIAWQB/wFZAekBmQH/AVUB5QGPAf8BUgHhAYYB/wFOAdwBewH/ASkBoAEqAf4EAAE/AV0BQwGE
AUgB1gFuAf8BOAG8AUsB/wEOAQ8BDgETBAABKAGlASkB/wFbAeoBnQH/ASoBnQErAfkEAAJKAcgB/wJs
AesB/wJoAegB/wJjAeQB/wJdAeAB/wIpAaIB/gQAAT8BQQFeAYQCVQHZAf8CPwG+Af8CDgEPARMEAAIp
AaUB/wJtAewB/wEqASsBngH5GAADVQGyAVUB0gF2Af8BWgHTAW0B/wFNAdQBdQH/XAABPgGBAT4BuwE+
AYQBPgG/AT4BhAE+Ab8BPgF8AUMBuwE4AUoBOgFlCAABMQE9ATMBUQE+AYIBPgG/AT0BVgFAAXgIAAER
ARIBEQEXAT4BggE+Ab8BQQF2AUIBrAQAAj4BgQG7Aj4BhAG/Aj4BhAG/AT4BQAF/AbsBOAE5AUoBZQgA
ATEBMgE9AVECPgGCAb8BPQE/AVcBeAgAAhEBEgEXAj4BggG/AkEBeAGsGAADVAGrATABuQE1Af8BMAG4
ATUB/wEuAbUBMQH//wD/ANoAAUIBTQE+BwABPgMAASgDAAFAAwABIAMAAQEBAAEBBgABARYAA/+BAAj/
AfwBPwb/AfwBPwb/AfwBPwL/AZwBGAGcARgB/AE/Av8BmAEYAZgBGAH8AT8C/wGYAYABmAGAAcABAQHA
AQMBgAGBAYABgQHAAQEBwAEDAYEBwwGBAcMBwAEBAcABAwGAAcMBgAHDAcABAQHAAQMBmAGBAZgBgQH8
AT8C/wSAAfwBPwL/AYEBCAGBAQgB/AE/Av8BgwEYAYMBGAH8AT8W/ws=
</value>
</data>
<data name="listView.TabIndex" type="System.Int32, mscorlib">
@@ -416,7 +446,7 @@
<value>Magenta</value>
</data>
<data name="HelpButton.Size" type="System.Drawing.Size, System.Drawing">
<value>72, 22</value>
<value>79, 22</value>
</data>
<data name="HelpButton.Text" xml:space="preserve">
<value>Filter help</value>
@@ -138,14 +138,16 @@ namespace Duplicati.GUI.HelperControls {
//
this.imageList.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList.ImageStream")));
this.imageList.TransparentColor = System.Drawing.Color.Transparent;
this.imageList.Images.SetKeyName(0, "Inclusion.ico");
this.imageList.Images.SetKeyName(1, "Exclusion.ico");
this.imageList.Images.SetKeyName(0, "globbing-include");
this.imageList.Images.SetKeyName(1, "globbing-exclude");
this.imageList.Images.SetKeyName(2, "icon_up_sort_arrow[1].png");
this.imageList.Images.SetKeyName(3, "icon_down_sort_arrow[1].png");
this.imageList.Images.SetKeyName(4, "sort_ascending[1].png");
this.imageList.Images.SetKeyName(5, "sort_descending[1].png");
this.imageList.Images.SetKeyName(6, "sort_up[1].png");
this.imageList.Images.SetKeyName(7, "sort_down[1].png");
this.imageList.Images.SetKeyName(8, "regexp-include");
this.imageList.Images.SetKeyName(9, "regexp-exclude");
//
// label1
//
@@ -94,11 +94,26 @@ namespace Duplicati.GUI.HelperControls {
bool sortingOrderAsc = true;
private string[] m_paths;
private List<KeyValuePair<bool, string>> m_filters;
private string m_dynamicFilters;
public string[] Paths { get { return m_paths; } set { m_paths = value; } }
public List<KeyValuePair<bool, string>> Filters { get { return m_filters; } set { m_filters = value; } }
public List<FilterDialog.FilterEntry> Filters
{
get
{
List<FilterDialog.FilterEntry> filters = new List<FilterDialog.FilterEntry>();
foreach (ListViewItem lvi in lvFilters.Items)
filters.Add((FilterDialog.FilterEntry)lvi.Tag);
return filters;
}
set
{
lvFilters.Items.Clear();
foreach (FilterDialog.FilterEntry fe in value)
lvFilters.Items.Add(fe.CreateListViewItem());
}
}
public string DynamicFilters { get { return m_dynamicFilters; } set { m_dynamicFilters = value; } }
List<ResultItem> _results = new List<ResultItem>();
@@ -116,9 +131,6 @@ namespace Duplicati.GUI.HelperControls {
currentSortingColumn = 2;
lvFiles.Columns[currentSortingColumn].ImageIndex = SORT_ASC_IMAGEINDEX + ( sortingOrderAsc ? 0 : 1 );
foreach (KeyValuePair<bool, string> f in Filters)
lvFilters.Items.Add(new ListViewItem(f.Value, f.Key ? 0 : 1));
StartScanThread();
}
@@ -194,9 +206,12 @@ namespace Duplicati.GUI.HelperControls {
}
}
private void DoTestSearchSelection() {
private List<ResultItem> DoTestSearchSelection(List<FilterDialog.FilterEntry> filters) {
List<KeyValuePair<bool, string>> dyn_filters = new List<KeyValuePair<bool, string>>();
foreach (FilterDialog.FilterEntry fe in filters)
dyn_filters.Add(new KeyValuePair<bool, string>(fe.Include, fe.Filter));
List<KeyValuePair<bool, string>> dyn_filters = new List<KeyValuePair<bool, string>>(Filters);
if (!string.IsNullOrEmpty(DynamicFilters))
dyn_filters.AddRange(Library.Utility.FilenameFilter.DecodeFilter(DynamicFilters));
@@ -204,30 +219,46 @@ namespace Duplicati.GUI.HelperControls {
try
{
CallbackHandler handler = new CallbackHandler(scanWorker);
foreach (string scanDir in Paths)
{
if (!scanWorker.CancellationPending)
Library.Utility.Utility.EnumerateFileSystemEntries(scanDir, fn, AddFileToList_Callback);
Library.Utility.Utility.EnumerateFileSystemEntries(scanDir, fn, handler.AddFileToList_Callback);
}
return handler.Results;
}
catch (AbortException)
{
return null;
}
}
void AddFileToList_Callback(string rootpath, string path, Duplicati.Library.Utility.Utility.EnumeratedFileStatus status)
private class CallbackHandler
{
public List<ResultItem> Results = new List<ResultItem>();
private BackgroundWorker Worker;
if (scanWorker.CancellationPending)
throw new AbortException();
if (status == Utility.EnumeratedFileStatus.File)
public CallbackHandler(BackgroundWorker worker)
{
_results.Add(new ResultItem(path));
Worker = worker;
}
else if (status == Utility.EnumeratedFileStatus.Folder)
public void AddFileToList_Callback(string rootpath, string path, Duplicati.Library.Utility.Utility.EnumeratedFileStatus status)
{
//Should be displayed in tree so the user can exclude with right click?
if (Worker.CancellationPending)
throw new AbortException();
if (status == Utility.EnumeratedFileStatus.File)
{
Results.Add(new ResultItem(path));
}
else if (status == Utility.EnumeratedFileStatus.Folder)
{
//Should be displayed in tree so the user can exclude with right click?
}
}
}
@@ -291,34 +322,18 @@ namespace Duplicati.GUI.HelperControls {
lvFiles.Invalidate();
}
bool ExtractLastDirectory(StringBuilder path, StringBuilder dest) {
if( path.Length == 0 )
return false;
int i = path.Length;
while( --i > -1 ) {
if( path[i] == '\\' ) {
if( i != path.Length - 1 && i > 3 )
break;
else continue;
}
dest.Insert(0, path[i]);
}
i = i > -1 ? i : 0;
path.Remove(i, path.Length - i);
return true;
}
void AddFilter(bool include, string filter) {
Filters.Add(new KeyValuePair<bool, string>(include, filter));
lvFilters.Items.Add(filter, include ? 0 : 1);
FilterDialog.FilterEntry fe = new FilterDialog.FilterEntry(include, FilenameFilter.ConvertGlobbingToRegExp(filter), filter);
lvFilters.Items.Add(fe.CreateListViewItem());
}
string GetFileFilterStr(string filename, string ext) {
return string.Format(@".*\\{0}.{1}", filename, ext);
if (filename == "*")
return string.Format("*.{0}", ext);
else
return string.Format("*\\{0}.{1}", filename, ext);
}
void _AddSelectedFilter(bool include, bool anyFileName) {
if( lvFiles.SelectedIndices.Count > 0 ) {
foreach( int index in lvFiles.SelectedIndices ) {
@@ -343,7 +358,7 @@ namespace Duplicati.GUI.HelperControls {
_AddSelectedFilter(false, true);
}
// Exlude File Path
// Exclude File Path
private void ctxSelection_Opened(object sender, EventArgs e) {
if( lvFiles.SelectedIndices.Count > 0 ) {
ResultItem itm = GetResultItem(lvFiles.SelectedIndices[0]);
@@ -356,17 +371,38 @@ namespace Duplicati.GUI.HelperControls {
miExcludeFileExt.Text = fileExt;
// Add Path items
StringBuilder completePath = new StringBuilder(itm.Path);
StringBuilder path = new StringBuilder(completePath.Length );
miExludeFilePath.DropDownItems.Clear();
miIncludeFilePath.DropDownItems.Clear();
while( ExtractLastDirectory(completePath, path) ) {
string s = ( completePath.Length > 0 ) ? string.Format(@".*\\{0}\\", path) : path.ToString();
miIncludeFilePath.DropDownItems.Add(s, null, FilterFilePath_Click).Tag = true;
miExludeFilePath.DropDownItems.Add(s, null, FilterFilePath_Click).Tag = false;
string fullpath = Utility.AppendDirSeparator(itm.Path);
string root = System.IO.Path.GetPathRoot(fullpath);
string curpath = System.IO.Path.GetDirectoryName(fullpath);
List<string> folderlist = new List<string>();
path.Insert(0, @"\\");
do
{
if (curpath != System.IO.Path.GetDirectoryName(curpath))
folderlist.Add(Utility.AppendDirSeparator(curpath));
curpath = System.IO.Path.GetDirectoryName(curpath);
} while (root != curpath);
folderlist.Add(root);
foreach (string s in folderlist)
{
if (s.Length >= fullpath.Length)
continue;
string filter = string.Format(@"*\{0}", fullpath.Substring(s.Length));
miIncludeFilePath.DropDownItems.Add(filter, null, FilterFilePath_Click).Tag = true;
miExludeFilePath.DropDownItems.Add(filter, null, FilterFilePath_Click).Tag = false;
}
foreach (string s in folderlist)
{
string filter = string.Format(@"{0}", s);
miIncludeFilePath.DropDownItems.Add(filter, null, FilterFilePath_Click).Tag = true;
miExludeFilePath.DropDownItems.Add(filter, null, FilterFilePath_Click).Tag = false;
}
}
@@ -388,24 +424,26 @@ namespace Duplicati.GUI.HelperControls {
tbSearch.Enabled = false;
lvFiles.Enabled = false;
lvFilters.Enabled = false;
scanWorker.RunWorkerAsync();
scanWorker.RunWorkerAsync(this.Filters);
}
private void scanWorker_DoWork(object sender, DoWorkEventArgs e) {
//if( _results.Count == 0 )
DoTestSearchSelection();
e.Result = DoTestSearchSelection((List<FilterDialog.FilterEntry>)e.Argument);
//else UpdateSearchSelection();
if (scanWorker.CancellationPending)
e.Cancel = true;
}
private void scanWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) {
if (e.Error == null && !e.Cancelled)
if (e.Error == null && !e.Cancelled && e.Result as List<ResultItem> != null)
{
lbLoading.Visible = false;
tbSearch.Enabled = true;
lvFiles.Enabled = true;
lvFilters.Enabled = true;
_results = (List<ResultItem>)e.Result;
LoadFileView();
SortView((ResultItemSortBy)currentSortingColumn, true);
}
@@ -442,7 +480,6 @@ namespace Duplicati.GUI.HelperControls {
if( lvFilters.SelectedItems.Count > 0 ) {
for(int i = lvFilters.SelectedItems.Count-1; i > -1; i--) {
Filters.RemoveAt(lvFilters.SelectedItems[i].Index);
lvFilters.Items.RemoveAt(lvFilters.SelectedItems[i].Index);
}
@@ -493,8 +530,5 @@ namespace Duplicati.GUI.HelperControls {
{
this.DialogResult = DialogResult.OK;
}
}
}
@@ -127,104 +127,134 @@
<value>
AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj00LjAuMC4w
LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAB+
FgAAAk1TRnQBSQFMAgEBCAEAAawBAAGsAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABMAMAAQEBAAEgBgABMP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8A/wD/AP8AKQABAQMhATADIwEz
AyMBMwMhATAMAAMfASwDIwEzAyMBMwMjATMDIwEzAyMBMwMhATAMAAMjATMDIwEzEAADHwEsAyMBMwMj
ATMDIQEwWwAEAQECAwMBBAMFBAcBCQMGAQgDBAEGAwMBBAMBAQIDAAEBEAADAgEDAYsBcAFTAfEBtwGD
ATwB/wG3AYMBPQH/AYwBcgFNAfIMAAFbAWUBWwHhAUIBhQFEAf8BQwGEAUMB/wFDAYQBQwH/AUQBhAFE
Af8BRAGFAUYB/wFWAXUBWQHyCAADIwEzAbcBgwE9Af8BtwGDAT0B/wMjATMMAAFbAWUBWwHhAUIBhQFF
Af8BQwGFAUUB/wFWAXUBWQHyXAADBAEFAwkBDAMNAREDMQFOAxoBJAMPARQDDQERAwkBDAMEAQUUAAG3
AYIBPAH/AfsBzgGIAf8B+QHKAYAB/wG5AYMBPAH/DAABQQGEAUQB/wGeAegByQH/AUkByAGSAf8BSwHI
AZMB/wFMAcgBlAH/AU4BzAGZAf8BQwGFAUUB/wQAAyMBMwG1AYEBOgH/AfQBxAFzAf8B9AHEAXMB/wG1
AYEBOgH/AyMBMwgAAUABhAFEAf8BngHpAcoB/wFMAcwBmAH/AUMBhQFFAf9kAAM3AVsDlgH0A1wBxQMB
AQIgAAG2AYEBOgH/AfQBywGKAf8B8QHAAW4B/wG4AYIBOwH/DAABQAGEAUMB/wG7AeoB3QH/AbgB5gHY
Af8BuQHmAdgB/wG6AecB2QH/Ab0B6wHeAf8BQQGFAUQB/wMjATMBtQGBAToB/wHyAcEBbwH/Ae4BvAFr
Af8B7gG9AWwB/wHyAcEBbwH/AbgBgQE6Af8DIwEzBAABPgGEAUMB/wG8AesB3gH/Ab0B6wHfAf8BQQGF
AUQB/2AAAxYBHgFvAXABbwHiAbwBwwHAAf8BrQGzAbEB+wNMAZAgAAG2AYEBOgH/AfEBygGQAf8B6wG4
AWYB/wG4AYIBOwH/DAADVAGuAUABhAFDAf8BPgGCAUAB/wE+AYIBQAH/AT4BggFAAf8BQAGEAUMB/wFX
AVoBVwHFAbgBhAE9Af8B9wHOAY8B/wHyAckBiQH/Ae0BwgGCAf8B6wG5AWgB/wHyAckBigH/AfkBzgGP
Af8BwgGEATwB/wQAAVQBVgFUAasBQAGEAUMB/wFAAYQBQwH/AVYBWAFWAcFcAAMDAQQDXQHKAcMByQHG
Af8BtgG9AboB/wG6AcEBvgH/AZABkgGQAfEDLgFIHAABtgGBATkB/wHvAc0BmAH/AeYBsgFfAf8BuAGC
ATwB/wwAAxkEIwEzAyMBMwMjATMDGAEiCAABXQFaAVcBxQG3AYIBOwH/AbMBdgE2Af8B8AHIAY4B/wHp
AbgBZQH/AbMBdwE4Af8BuAGCATsB/wJbAVkBxAQAAxkEIwEzAyMBMwMjATMDGQEjEwABAQMCAQMDBQEH
AwgECwEPAw0BEgMNARIDCgEOAwgBCwMFAQcDAgEDHAADUAGbAbYBuQG4AfwBtgG9AboB/wG7AcIBvwH/
AccBzQHLAf8B1QHZAdcB/wN0AeQDDwEUGAABtgGBATkB/wHuAc8BoQH/AeABrAFXAf8BuQGDAT0B/wwA
AVYBWQFWAb4BQgGFAUQB/wFDAYQBQwH/AUQBhQFGAf8BVwFaAVcBvRAAAbYBgAE5Af8B8AHLAZYB/wHn
AbQBYgH/AbYBggE7Af8MAAFXAVoBVwG9AUEBhQFEAf8BQwGEAUMB/wFEAYUBRgH/AVcBWQFXAb8fAAEB
AwQBBQMGAQgDBgEIAwUBBwMCAQMgAAM1AVcBkAGSAZAB8QG5AcABvQH/Ab0BwwHAAf8BwwHIAcYB/wHH
Ac0BywH/Ac0B0gHQAf8B2wHeAd0B/wNcAccDAAEBFAABtgGBATgB/wHvAdMBqgH/AdoBpQFQAf8BuQGD
AT0B/wwAAUABhAFEAf8BngHoAckB/wFKAckBkwH/AU4BzAGYAf8BQwGFAUUB/xAAAbYBgQE5Af8B7wHO
AZ0B/wHkAbEBXQH/AbgBggE8Af8MAAE/AYUBRAH/AZ4B6AHJAf8BSgHJAZMB/wFOAcwBmAH/AUMBhQFF
Af8MAANIAYMBZgFnAWYB1QFmAmcB1QNlAdQDYgHTA2IB0wNhAdIDYwHRA2MB0QNjAdEDYwHRA2EB0gNg
AdEDEgEZDAADFAEbAW4CcQHgAb4BxAHBAf8BtwG+AbsB/wG7AcIBvwH/AcABxgHEAf8BxQHLAckB/wHL
AdABzQH/AdAB1AHSAf8BwgHFAcQB/ANKAY0UAAG2AYEBOAH/AfAB2QG0Af8B1gGfAUkB/wG4AYQBPQH/
DAABPgGEAUMB/wG7AeoB3QH/AbkB5wHZAf8BvQHrAd4B/wFBAYUBRAH/EAABtgGBATgB/wHwAdEBpAH/
AeABrAFXAf8BuAGDATwB/wwAAUABhAFDAf8BuwHqAd0B/wG5AecB2QH/Ab0B6wHeAf8BQQGFAUQB/wwA
Ax0BKQOJAe4B2wHeAd0B/wHSAdcB1QH/Ac4B0wHRAf8ByQHOAcwB/wHFAcoByAH/AcABxgHDAf8BvQHD
AcEB/wG9AcMBwQH/Ab0BwwHBAf8BzAHRAc8B/wNYAbcMAAMCAQMDXgHJAcUBygHIAf8BtwG+AbsB/wG3
Ab4BuwH/AbkBwAG9Af8BvgHFAcIB/wHDAckBxgH/AckBzgHMAf8BzQHSAdAB/wHVAdkB1wH/A5oB8wMs
AUMIAAMhATADIwEzAbcBgQE4Af8B7wHbAb0B/wHQAZoBQgH/AbgBhAE+Af8DIwEzAyEBMAQAAVMBVQFT
Aa0BPwGEAUMB/wE+AYIBQQH/AUABhAFDAf8BVAFuAVQB7hAAAbYBgQE4Af8B7wHUAa0B/wHdAagBUwH/
AbkBgwE9Af8MAANUAa4BQAGEAUMB/wE+AYIBQQH/AUABhAFDAf8BWAFuAVkB6xAAAz8BbAG1ArgB+gHS
AdYB1AH/AcwB0QHPAf8BxwHMAcoB/wHCAcgBxQH/Ab0BwwHAAf8BtwG+AbsB/wG3Ab4BuwH/AcEBxwHF
Af8DaAHaAwoBDgwAA0wBkwG3AbsBuQH8AcUBywHIAf8BxQHLAcgB/wHFAcsByAH/AcUBywHIAf8ByAHO
AcsB/wHMAdEBzgH/Ac8B1AHSAf8B0wHXAdUB/wHWAdoB2AH/Ad8B4gHhAf8DbwHiAwMBBAQAAYsBcgFN
AfIBuQGEATwB/wG3AYEBOQH/AdoBtwGHAf8BxgGPAT4B/wG4AYMBPQH/AboBhAE8Af8BkAFwAVMB8QQA
AxgBIgMjATMDIwEzAxgBIhQAAbYBgQE4Af8B8AHYAbUB/wHZAaMBTQH/AbkBgwE9Af8MAAMZBCMBMwMj
ATMDIwEzAyMBMwMjATMDGQEjDAADVAGuAc4B0gHQAf4BzgHTAdEB/wHJAc4BzAH/AcQBygHHAf8BvwHF
AcIB/wG6AcABvgH/AboBwQG+Af8DgwHtAygBPBAAAyABLgM/AWwDPwFsAz8BbAM+AWsDPgFqAz4BagM+
AWoDPQFpAz0BaQM9AWgDPQFoAzsBZAMEAQYEAAG5AYQBPQH/AegB0QGsAf8BxgGPATcB/wHGAY8BOQH/
AcYBkAE6Af8BxgGPATcB/wHsAdUBsgH/AcMBhAE7Af8EAAFWAVgBVgG8AUIBhQFFAf8BQwGFAUUB/wFX
AVoBVwG9FAABtgGAATcB/wHxAdwBvAH/AdUBnwFIAf8BuQGEAT0B/wwAAVYBWQFWAb4BQgGFAUQB/wFD
AYQBQwH/AUMBhAFDAf8BRAGEAUQB/wFEAYUBRgH/AVgBWgFYAcAMAAMFAQcDZQLZAdwB2wH/AcsB0AHO
Af8BxgHLAckB/wG9AcQBwQH/AbgBvwG8Af8BqQGsAasB+gNIAYNUAAG4AYIBOQH/AegB0AGtAf8BwgGL
ATEB/wHCAYsBMQH/AegB0AGtAf8BuQGCATkB/wgAAT8BhQFEAf8BngHpAcoB/wFMAcwBmAH/AUMBhQFF
Af8UAAG3AYEBNwH/AfAB2wG7Af8B0AGZAUEB/wG6AYMBPAH/DAABQQGEAUQB/wGeAegByQH/AUkByAGS
Af8BSwHIAZMB/wFMAcgBlAH/AU4BzAGZAf8BQwGFAUUB/xAAAxwBJwGDAYQBgwHrAcsB0AHOAf8BuQHA
Ab0B/wG2Ab0BugH/AcUBygHIAf8DWQG/XAABtwGBATkB/wHoAdEBsAH/AegB0QGwAf8BuAGBATkB/wwA
AT8BhAFDAf8BvAHrAd4B/wG9AesB3wH/AUEBhQFEAf8UAAG4AYIBOQH/Ae8B2wG7Af8B6gHQAakB/wG6
AYMBOwH/DAABQAGEAUMB/wG7AeoB3QH/AbgB5gHYAf8BuQHmAdgB/wG6AecB2QH/Ab0B6wHeAf8BQQGF
AUQB/xQAAz0BaAGXAZsBmQH1AbcBvgG7Af8BvgHFAcIB/wNpAd4DDQESYAABuAGDATsB/wG4AYMBOwH/
EAABUwFVAVMBsAFAAYQBQwH/AUABhAFDAf8BVQFuAVgB7xQAAlUBUwGwAbgBggE6Af8BuAGDAToB/wJV
AVMBsAwAAVMBVQFTAbABQAGEAUMB/wE+AYIBQAH/AT4BggFAAf8BPgGCAUAB/wFAAYQBQwH/AVUBbgFY
Ae8YAANSAakBuwHAAb4B/gGGAYcBhgHvAy0BRvAAAwUBBwNbAcQDRgF+/wB1AAMTARoBLAIrAUMBLAIr
AUMBLAIrAUPwAANVAbIBRAHiAYwB/wFDAeEBiQH/ATUByAFdAf/wAANVAbIBOAHUAVgB/wEvAcsBPwH/
ATUByQFdAf+wAAMMARADPQFoAyoBQDQAA1UBsgFAAdoBYgH/ATABzAFBAf8BNQHKAV0B/1wAAxABFgMX
ASADFwEgAxcBIAMXASADFwEgAxcBIAMXASADFwEgAxcBIAMXASADFwEgAxcBIAMJAQwYAAMKAQ4DKAE8
A14B1QNMAZADEwEaAwMBBCwAA1UBsgFMAeMBgQH/ATwB1AFOAf8BNgHLAV4B/1wAA0gBgwNZAb8DWQG/
A1kBvwNZAb8DWQG/A1kBvwNZAb8DWQG/A1kBvwNZAb8DWQG/A1kBvwMuAUgYAAM0AVQDWQHHA18B8wNd
Ad8DUAGbAxIBGBwAAT4BfwE8Af4BPwHTAWQB/wE/AdQBZgH/AUAB1AFmAf8BPwHTAWUB/wFYAeoBhAH/
AUsB3wFeAf8BSQHjAZAB/wE2AcoBXAH/ATQByAFbAf8BMwHGAVkB/wEzAcUBWQH/AzABTAwAA0gBhAI7
AdMB/wI9AdQB/wI/AdQB/wJAAdMB/wI/AdAB/wI8AcwB/wI4AccB/wI0AcMB/wIyAcIB/wIyAcIB/wIh
AagB/wwAAz8BbQNbAcMDXwH/A18B/wNfAf8DXwH/A18B/wNfAf8DXwH/A18B/wNfAf8DZAHnA1MBpQMo
ATwQAAMEAQYDLgFIA1QBpgNfAf8DXwH/A18B/wNhAeEDQgF0Ax0BKhgAAUEBgwFBAf4BVAHaAWcB/wFd
AeQBgQH/AWMB7AGGAf8BZgHwAYoB/wFjAe8BhwH/AVoB6gGBAf8BTQHhAWEB/wFAAdcBUgH/ATQBzgFF
Af8BLwHLAT8B/wFCAeABhwH/AzABTAwAA0gBhAJNAdcB/wJUAdYB/wJgAeQB/wJoAe4B/wJoAfAB/wJc
AekB/wJJAdwB/wI5AdAB/wI0AcwB/wI0AcwB/wIrAbcB/xAAAzoBYANfAf8DXwH/A18B/wNfAf8DXwH/
A18B/wNfAf8DXwH/A18B/wNZAb8DDAEQFAADDAEQA1kBvwNfAf8DXwH/A18B/wNfAf8DXwH/A18B/wNA
AXAYAAFBAYQBQQH+AU0B1gGBAf8BVQHfAYUB/wFcAecBjQH/AWEB7gGTAf8BZgHvAYoB/wFkAfABiAH/
AVwB7AGGAf8BUQHnAYIB/wFGAd4BaAH/ATwB1wFdAf8BQwHhAYoB/wMwAUwMAANIAYQCTgHaAf8CVQHd
Af8CXwHoAf8CZQHwAf8CZQHyAf8CXAHsAf8CTQHiAf8CPwHYAf8COgHUAf8COgHUAf8CKwG3Af8QAAMa
ASQDPgFqA10B1wNfAf8DXwH/A18B/wNfAf8DXwH/A18B/wNUAaYDLgFIAwQBBhAAAygBPANTAaUDZAHn
A18B/wNfAf8DXwH/A18B/wNfAf8DXwH/A1wByQNDAXcDBwEKEAABVgJVAbEDVQG1A1UBtQNVAbUDVwHo
AWEB7QGTAf8BZgHvAYkB/wFCAdYBgQH/A1UBtQNVAbUDVQG1A1UBtQMYASEMAAMtAUYDVQG1A1UBtQNV
AbUDVQG1A1UBtQNVAbUDVQG1A1UBtQNVAbUDVQG1AVYCVQG0FAADCQEMA0wBjwNfAdsDXwH/A18B/wNf
Af8DXwHzA1kBxwM0AVQUAAMfASwDSQGIA18B/wNfAf8DXwH/A18B/wNfAf8DXwH/A18B/wNfAf8DXwH/
A1wBzwMwAUwDEgEYHAADVQGyAVoB5QGLAf8BYQHoAYMB/wFCAdYBgQH/ZAADAQECAxIBGANHAYIDXwH/
A18B/wNfAf8DXgHVAygBPAMKAQ4UAANOAZkDYAHrA18B/wNfAf8DXwH/A18B/wNfAf8DXwH/A18B/wNf
Af8DXwH/A2YB9wNhAeEDNAFUHAADVQGyAVEB2wGBAf8BWAHeAYAB/wFBAdUBagH/bAADJgE4A0wBkANk
AecDWgHAAz0BaAMMARAYAAM2AVgDRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGA
A0cBgANHAYADIQEwHAADVQGyAUgB0gFpAf8BTQHTAWAB/wFAAdQBaAH/cAADFAEcA1UBtQNAAXB0AANU
AasBIwG5ASgB/wEjAbgBKAH/ASEBtQEkAf9wAAMGAQgDIwE0AxcBIP8A/wBeAAFCAU0BPgcAAT4DAAEo
AwABQAMAATADAAEBAQABAQUAAYABARYAA/+BAAGDAYAB5wGHAv8B4AEHAYMBgAHDAYcC/wHwAQcBwwGA
AYEBhwL/AfwBPwHDAYABAAGHAv8B+AE/AcMBgAEAAYcC/wHwAR8BwwGDAQABgwHAAQcB8AEPAcMBgwHD
AYMB+AEfAeABBwHDAYMBwwGDAYABAQHAAQcBwwGDAcMBgwGAAQMBgAEDAQABgwHDAYMBwAEDAYABAQEA
AYcBwwGAAeABBwGAAQEBAAGHAcMBgAHgAQ8C/wGBAYcBwwGAAfABHwL/AcMBhwHDAYAB+AEfAv8B5wGH
AcMBgAH8AT8G/wH8AX8K/wH8AT8G/wH8AT8G/wH8AT8E/wH8AX8B/AE/Av8BgAEBAfgBHwH8AT8C/wGA
AQEB+AEfAcABAQHAAQMBgAEBAeABDwHAAQEBwAEDAcABAwHgAQ8BwAEBAcABAwHAAQMBwAEDAcABAQHA
AQMB4AEPAYABAQH8AT8C/wHgAQ8BgAEBAfwBPwL/AfgBHwGAAQEB/AE/Av8B/AF/Av8B/AE/Av8B/AF/
Ev8L
ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAACy
HQAAAk1TRnQBSQFMAgEBCgEAAbQBAAG0AQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
AwABMAMAAQEBAAEgBgABMP8A/wD/ABkAASgBpAEoAf8BKAGkASgB/wwAAS0BmgEuAfYBKAGkASgB/wEq
AaIBKwH9ASgBpAEoAf8BIgEmASIBMQgAAwgBCwEoAaQBKAH/ASgBpAEoAf8EAAIoAaQB/wIoAaQB/wwA
Ai0BnQH2AigBpAH/AioBowH9AigBpAH/AiIBJgExCAACCAEJAQsCKAGkAf8CKAGkAf+EAAFCAcgBZQH/
AU0B2AF+Af8IAAEmASsBJgE4AUYB0QFpAf8BPgHFAVcB/wEvAZYBMwHuAU0B3AF4Af8BKgGnAS0B/wgA
ASoBogErAf0BWwHrAZ8B/wEoAaQBKAH/BAACSgHIAf8CWwHaAf8IAAImASsBOAJQAdMB/wJFAcYB/wEv
ATEBmAHuAlkB3QH/AisBpwH/CAACKgGjAf0CbQHsAf8CKQGiAf6EAAFBAccBYgH/AUwB1gF5Af8IAAEo
AaQBKAH/AUoB2QFxAf8BMAGYATMB8QQAAS0BrAE0Af8BSwHaAXMB/wE6AYcBPQHOAUABYQFEAYwBUgHg
AYgB/wE8AcABVgH/AQwBDQEMARAEAAJKAcgB/wJaAdgB/wgAAigBpAH/AVUBVAHaAf8BMAExAZoB8QQA
Ai8BrQH/AlcB3AH/AToBPQGIAc4BQAFCAWEBjAJiAeMB/wJEAcIB/wIMAQ0BEIQAAUEBxgFhAf8BSwHV
AXcB/wEpATEBKQI/AXQBRQGvAUYB0gFoAf8BOgHAAU0B/wEOAQ8BDgETBAABNQFCATcBWgFBAcwBXgH/
AT0BxQFWAf8BNQG3AUUB/wFSAeABhwH/AUEBbQFFAaEIAAJKAcgB/wJYAdcB/wIpATECPwFCAXYBrwJP
AdQB/wI/AcIB/wIOAQ8BEwQAATUBNgFDAVoCSgHOAf8CRQHHAf8COgG4Af8CYgHjAf8BQQFEAW8BoYgA
AUABxgFgAf8BVQHlAY8B/wFRAeABhAH/AU0B3AF4Af8BQwHOAWAB/wE0AZMBNwHmDAABMgGWATUB6wFL
AdkBcgH/AU8B3gF9Af8BKAGkASgB/wwAAkoBxwH/AmcB5wH/AmAB4gH/AlkB3gH/AUwBSwHQAf8BNAE2
AZQB5gwAATIBNQGXAesCVwHbAf8CXQHgAf8CKAGkAf+MAAFAAcYBYAH/AUoB1QF1Af8BKAGkASgB/wEo
AaUBKQH/AUcB1QFpAf8BOAG/AUoB/wMJAQwIAAE/AVwBRAGFAUcB1AFqAf8BTwHeAXwB/wEtAZ4BLwH3
DAACSgHHAf8CVwHWAf8CKAGkAf8CKQGlAf8BUgFRAdcB/wI+AcEB/wMJAQwIAAE/AUEBXgGFAlIB1gH/
Al0B4AH/AS0BLgGfAfeMAAFBAcYBYAH/AUoB1QF2Af8IAAExAbMBPAH/AUYB1QFmAf8BNgFGATgBXwQA
AwQBBgExAbMBPAH/AUoB2AFwAf8BOwHBAVMB/wFOAdsBfQH/AT0BVgFBAXkIAAJKAcgB/wJYAdcB/wgA
AjUBtAH/AlAB1wH/ATYBNwFHAV8EAAMEAQYCNQG0Af8CVwHbAf8CQwHDAf8CXQHeAf8BPQFAAVcBeYgA
AUEBxwFiAf8BSwHWAXgB/wFBAXEBQQGfAToBhgFAAdABQwHOAWMB/wFGAdMBZwH/ASYBKwEmATgEAAEp
AZ0BKwH7AUoB2QFxAf8BKAGkASgB/wE/AXgBRAG0AVQB4wGMAf8BNQG2AUUB/wMDAQQEAAJKAcgB/wJa
AdgB/wJBAXEBnwE6AT4BiQHQAk4B0AH/AlEB1QH/AiYBKwE4BAABKQEqAZ4B+wJXAdwB/wIoAaQB/wE/
AUIBegG0AmYB5gH/AjoBtwH/AwMBBIQAAUIByAFkAf8BWQHpAZkB/wFVAeUBjwH/AVIB4QGGAf8BTgHc
AXsB/wEpAaABKgH+BAABPwFdAUMBhAFIAdYBbgH/ATgBvAFLAf8BDgEPAQ4BEwQAASgBpQEpAf8BWwHq
AZ0B/wEqAZ0BKwH5BAACSgHIAf8CbAHrAf8CaAHoAf8CYwHkAf8CXQHgAf8CKQGiAf4EAAE/AUEBXgGE
AlUB2QH/Aj8BvgH/Ag4BDwETBAACKQGlAf8CbQHsAf8BKgErAZ4B+YQAAT4BgQE+AbsBPgGEAT4BvwE+
AYQBPgG/AT4BfAFDAbsBOAFKAToBZQgAATEBPQEzAVEBPgGCAT4BvwE9AVYBQAF4CAABEQESAREBFwE+
AYIBPgG/AUEBdgFCAawEAAI+AYEBuwI+AYQBvwI+AYQBvwE+AUABfwG7ATgBOQFKAWUIAAExATIBPQFR
Aj4BggG/AT0BPwFXAXgIAAIRARIBFwI+AYIBvwJBAXgBrP8A/wD/AIoAAQEDIQEwAyMBMwMjATMDIQEw
DAADHwEsAyMBMwMjATMDIwEzAyMBMwMjATMDIQEwDAADIwEzAyMBMxAAAx8BLAMjATMDIwEzAyEBMFsA
BAEBAgMDAQQDBQQHAQkDBgEIAwQBBgMDAQQDAQECAwABARAAAwIBAwGGAW8BUwHxAbcBgwE7Af8BtwGD
ATwB/wGJAW8BTgHyDAABWwFjAVsB4QFBAYUBQwH/AUIBhAFCAf8BQgGEAUIB/wFDAYQBQwH/AUMBhQFF
Af8BVwFyAVkB8ggAAyMBMwG3AYMBPAH/AbcBgwE8Af8DIwEzDAABWwFjAVsB4QFBAYUBRAH/AUIBhQFE
Af8BVwFyAVkB8lwAAwQBBQMJAQwDDQERAzEBTgMaASQDDwEUAw0BEQMJAQwDBAEFFAABtwGCATsB/wH7
Ac4BiAH/AfkBygGAAf8BuQGDATsB/wwAAUABhAFDAf8BngHoAckB/wFIAcgBkgH/AUoByAGTAf8BSwHI
AZQB/wFNAcwBmQH/AUIBhQFEAf8EAAMjATMBtQGBATkB/wH0AcQBcgH/AfQBxAFyAf8BtQGBATkB/wMj
ATMIAAE/AYQBQwH/AZ4B6QHKAf8BSwHMAZgB/wFCAYUBRAH/ZAADNwFbA5IB9ANaAcUDAQECIAABtgGB
ATkB/wH0AcsBigH/AfEBwAFtAf8BuAGCAToB/wwAAT8BhAFCAf8BuwHqAd0B/wG4AeYB2AH/AbkB5gHY
Af8BugHnAdkB/wG9AesB3gH/AUABhQFDAf8DIwEzAbUBgQE5Af8B8gHBAW4B/wHuAbwBagH/Ae4BvQFr
Af8B8gHBAW4B/wG4AYEBOQH/AyMBMwQAAT0BhAFCAf8BvAHrAd4B/wG9AesB3wH/AUABhQFDAf9gAAMW
AR4BagFrAWoB4gG8AcMBwAH/AakBrwGtAfsDTAGQIAABtgGBATkB/wHxAcoBkAH/AesBuAFlAf8BuAGC
AToB/wwAA1QBrgE/AYQBQgH/AT0BggE/Af8BPQGCAT8B/wE9AYIBPwH/AT8BhAFCAf8BVwFaAVcBxQG4
AYQBPAH/AfcBzgGPAf8B8gHJAYkB/wHtAcIBggH/AesBuQFnAf8B8gHJAYoB/wH5Ac4BjwH/AcIBhAE7
Af8EAAFUAVYBVAGrAT8BhAFCAf8BPwGEAUIB/wFWAVgBVgHBXAADAwEEA10BygHDAckBxgH/AbYBvQG6
Af8BugHBAb4B/wGLAY4BiwHxAy4BSBwAAbYBgQE4Af8B7wHNAZgB/wHmAbIBXgH/AbgBggE7Af8MAAMZ
BCMBMwMjATMDIwEzAxgBIggAAVwBWgFXAcUBtwGCAToB/wGzAXUBNQH/AfAByAGOAf8B6QG4AWQB/wGz
AXYBNwH/AbgBggE6Af8CWwFZAcQEAAMZBCMBMwMjATMDIwEzAxkBIxMAAQEDAgEDAwUBBwMIBAsBDwMN
ARIDDQESAwoBDgMIAQsDBQEHAwIBAxwAA1ABmwG0AbcBtgH8AbYBvQG6Af8BuwHCAb8B/wHHAc0BywH/
AdUB2QHXAf8DcAHkAw8BFBgAAbYBgQE4Af8B7gHPAaEB/wHgAawBVgH/AbkBgwE8Af8MAAFWAVkBVgG+
AUEBhQFDAf8BQgGEAUIB/wFDAYUBRQH/AVcBWgFXAb0QAAG2AYABOAH/AfABywGWAf8B5wG0AWEB/wG2
AYIBOgH/DAABVwFaAVcBvQFAAYUBQwH/AUIBhAFCAf8BQwGFAUUB/wFXAVkBVwG/HwABAQMEAQUDBgEI
AwYBCAMFAQcDAgEDIAADNQFXAYsBjgGLAfEBuQHAAb0B/wG9AcMBwAH/AcMByAHGAf8BxwHNAcsB/wHN
AdIB0AH/AdsB3gHdAf8DWwHHAwABARQAAbYBgQE3Af8B7wHTAaoB/wHaAaUBTwH/AbkBgwE8Af8MAAE/
AYQBQwH/AZ4B6AHJAf8BSQHJAZMB/wFNAcwBmAH/AUIBhQFEAf8QAAG2AYEBOAH/Ae8BzgGdAf8B5AGx
AVwB/wG4AYIBOwH/DAABPgGFAUMB/wGeAegByQH/AUkByQGTAf8BTQHMAZgB/wFCAYUBRAH/DAADSAGD
A2MB1QNjAdUDYwHUA18B0wNfAdMDXwHSA2AB0QNgAdEDYAHRA2AB0QNfAdIDXwHRAxIBGQwAAxQBGwFr
AmwB4AG+AcQBwQH/AbcBvgG7Af8BuwHCAb8B/wHAAcYBxAH/AcUBywHJAf8BywHQAc0B/wHQAdQB0gH/
Ab8BwgHBAfwDSgGNFAABtgGBATcB/wHwAdkBtAH/AdYBnwFIAf8BuAGEATwB/wwAAT0BhAFCAf8BuwHq
Ad0B/wG5AecB2QH/Ab0B6wHeAf8BQAGFAUMB/xAAAbYBgQE3Af8B8AHRAaQB/wHgAawBVgH/AbgBgwE7
Af8MAAE/AYQBQgH/AbsB6gHdAf8BuQHnAdkB/wG9AesB3gH/AUABhQFDAf8MAAMdASkDhAHuAdsB3gHd
Af8B0gHXAdUB/wHOAdMB0QH/AckBzgHMAf8BxQHKAcgB/wHAAcYBwwH/Ab0BwwHBAf8BvQHDAcEB/wG9
AcMBwQH/AcwB0QHPAf8DVwG3DAADAgEDA1wByQHFAcoByAH/AbcBvgG7Af8BtwG+AbsB/wG5AcABvQH/
Ab4BxQHCAf8BwwHJAcYB/wHJAc4BzAH/Ac0B0gHQAf8B1QHZAdcB/wOVAfMDLAFDCAADIQEwAyMBMwG3
AYEBNwH/Ae8B2wG9Af8B0AGaAUEB/wG4AYQBPQH/AyMBMwMhATAEAAFTAVUBUwGtAT4BhAFCAf8BPQGC
AUAB/wE/AYQBQgH/AVQBbAFUAe4QAAG2AYEBNwH/Ae8B1AGtAf8B3QGoAVIB/wG5AYMBPAH/DAADVAGu
AT8BhAFCAf8BPQGCAUAB/wE/AYQBQgH/AVkBawFZAesQAAM/AWwBsAKzAfoB0gHWAdQB/wHMAdEBzwH/
AccBzAHKAf8BwgHIAcUB/wG9AcMBwAH/AbcBvgG7Af8BtwG+AbsB/wHBAccBxQH/A2YB2gMKAQ4MAANM
AZMBtQG5AbcB/AHFAcsByAH/AcUBywHIAf8BxQHLAcgB/wHFAcsByAH/AcgBzgHLAf8BzAHRAc4B/wHP
AdQB0gH/AdMB1wHVAf8B1gHaAdgB/wHfAeIB4QH/A2oB4gMDAQQEAAGIAW8BTgHyAbkBhAE7Af8BtwGB
ATgB/wHaAbcBhwH/AcYBjwE9Af8BuAGDATwB/wG6AYQBOwH/AYsBbwFTAfEEAAMYASIDIwEzAyMBMwMY
ASIUAAG2AYEBNwH/AfAB2AG1Af8B2QGjAUwB/wG5AYMBPAH/DAADGQQjATMDIwEzAyMBMwMjATMDIwEz
AxkBIwwAA1QBrgHMAdABzgH+Ac4B0wHRAf8ByQHOAcwB/wHEAcoBxwH/Ab8BxQHCAf8BugHAAb4B/wG6
AcEBvgH/A38B7QMoATwQAAMgAS4DPwFsAz8BbAM/AWwDPgFrAz4BagM+AWoDPgFqAz0BaQM9AWkDPQFo
Az0BaAM7AWQDBAEGBAABuQGEATwB/wHoAdEBrAH/AcYBjwE2Af8BxgGPATgB/wHGAZABOQH/AcYBjwE2
Af8B7AHVAbIB/wHDAYQBOgH/BAABVgFYAVYBvAFBAYUBRAH/AUIBhQFEAf8BVwFaAVcBvRQAAbYBgAE2
Af8B8QHcAbwB/wHVAZ8BRwH/AbkBhAE8Af8MAAFWAVkBVgG+AUEBhQFDAf8BQgGEAUIB/wFCAYQBQgH/
AUMBhAFDAf8BQwGFAUUB/wFYAVoBWAHADAADBQEHA2MC2QHcAdsB/wHLAdABzgH/AcYBywHJAf8BvQHE
AcEB/wG4Ab8BvAH/AaYBqQGoAfoDSAGDVAABuAGCATgB/wHoAdABrQH/AcIBiwEwAf8BwgGLATAB/wHo
AdABrQH/AbkBggE4Af8IAAE+AYUBQwH/AZ4B6QHKAf8BSwHMAZgB/wFCAYUBRAH/FAABtwGBATYB/wHw
AdsBuwH/AdABmQFAAf8BugGDATsB/wwAAUABhAFDAf8BngHoAckB/wFIAcgBkgH/AUoByAGTAf8BSwHI
AZQB/wFNAcwBmQH/AUIBhQFEAf8QAAMcAScBfwGAAX8B6wHLAdABzgH/AbkBwAG9Af8BtgG9AboB/wHF
AcoByAH/A1kBv1wAAbcBgQE4Af8B6AHRAbAB/wHoAdEBsAH/AbgBgQE4Af8MAAE+AYQBQgH/AbwB6wHe
Af8BvQHrAd8B/wFAAYUBQwH/FAABuAGCATgB/wHvAdsBuwH/AeoB0AGpAf8BugGDAToB/wwAAT8BhAFC
Af8BuwHqAd0B/wG4AeYB2AH/AbkB5gHYAf8BugHnAdkB/wG9AesB3gH/AUABhQFDAf8UAAM9AWgBkgGX
AZQB9QG3Ab4BuwH/Ab4BxQHCAf8DZgHeAw0BEmAAAbgBgwE6Af8BuAGDAToB/xAAAVMBVQFTAbABPwGE
AUIB/wE/AYQBQgH/AVYBawFYAe8UAAJVAVMBsAG4AYIBOQH/AbgBgwE5Af8CVQFTAbAMAAFTAVUBUwGw
AT8BhAFCAf8BPQGCAT8B/wE9AYIBPwH/AT0BggE/Af8BPwGEAUIB/wFWAWsBWAHvGAADUgGpAbkBvgG8
Af4BggGDAYIB7wMtAUbwAAMFAQcDWwHEA0YBfv8AdQADEwEaASwCKwFDASwCKwFDASwCKwFD8AADVQGy
AUMB4gGMAf8BQgHhAYkB/wE0AcgBXAH/8AADVQGyATcB1AFXAf8BLgHLAT4B/wE0AckBXAH/sAADDAEQ
Az0BaAMqAUA0AANVAbIBPwHaAWEB/wEvAcwBQAH/ATQBygFcAf9cAAMQARYDFwEgAxcBIAMXASADFwEg
AxcBIAMXASADFwEgAxcBIAMXASADFwEgAxcBIAMXASADCQEMGAADCgEOAygBPANeAdUDTAGQAxMBGgMD
AQQsAANVAbIBSwHjAYEB/wE7AdQBTQH/ATUBywFdAf9cAANIAYMDWQG/A1kBvwNZAb8DWQG/A1kBvwNZ
Ab8DWQG/A1kBvwNZAb8DWQG/A1kBvwNZAb8DLgFIGAADNAFUA1kBxwNfAfMDXAHfA1ABmwMSARgcAAE+
AX8BPAH+AT4B0wFjAf8BPgHUAWUB/wE/AdQBZQH/AT4B0wFkAf8BVwHqAYQB/wFKAd8BXQH/AUgB4wGQ
Af8BNQHKAVsB/wEzAcgBWgH/ATIBxgFYAf8BMgHFAVgB/wMwAUwMAANIAYQCOgHTAf8CPAHUAf8CPgHU
Af8CPwHTAf8CPgHQAf8COwHMAf8CNwHHAf8CMwHDAf8CMQHCAf8CMQHCAf8CIAGoAf8MAAM/AW0DWwHD
A14B/wNeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNeAf8DXgH/A2QB5wNTAaUDKAE8EAADBAEGAy4BSANU
AaYDXgH/A14B/wNeAf8DYQHhA0IBdAMdASoYAAFBAYEBQQH+AVMB2gFmAf8BXAHkAYEB/wFiAewBhgH/
AWUB8AGKAf8BYgHvAYcB/wFZAeoBgQH/AUwB4QFgAf8BPwHXAVEB/wEzAc4BRAH/AS4BywE+Af8BQQHg
AYcB/wMwAUwMAANIAYQCTAHXAf8CUwHWAf8CXwHkAf8CZwHuAf8CZwHwAf8CWwHpAf8CSAHcAf8COAHQ
Af8CMwHMAf8CMwHMAf8CKgG3Af8QAAM6AWADXgH/A14B/wNeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNe
Af8DWQG/AwwBEBQAAwwBEANZAb8DXgH/A14B/wNeAf8DXgH/A14B/wNeAf8DQAFwGAABQQGCAUEB/gFM
AdYBgQH/AVQB3wGFAf8BWwHnAY0B/wFgAe4BkwH/AWUB7wGKAf8BYwHwAYgB/wFbAewBhgH/AVAB5wGC
Af8BRQHeAWcB/wE7AdcBXAH/AUIB4QGKAf8DMAFMDAADSAGEAk0B2gH/AlQB3QH/Al4B6AH/AmQB8AH/
AmQB8gH/AlsB7AH/AkwB4gH/Aj4B2AH/AjkB1AH/AjkB1AH/AioBtwH/EAADGgEkAz4BagNdAdcDXgH/
A14B/wNeAf8DXgH/A14B/wNeAf8DVAGmAy4BSAMEAQYQAAMoATwDUwGlA2QB5wNeAf8DXgH/A14B/wNe
Af8DXgH/A14B/wNcAckDQwF3AwcBChAAAVYCVQGxA1UBtQNVAbUDVQG1A1cB6AFgAe0BkwH/AWUB7wGJ
Af8BQQHWAYEB/wNVAbUDVQG1A1UBtQNVAbUDGAEhDAADLQFGA1UBtQNVAbUDVQG1A1UBtQNVAbUDVQG1
A1UBtQNVAbUDVQG1A1UBtQFWAlUBtBQAAwkBDANMAY8DXwHbA14B/wNeAf8DXgH/A18B8wNZAccDNAFU
FAADHwEsA0kBiANeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNcAc8DMAFMAxIBGBwA
A1UBsgFZAeUBiwH/AWAB6AGDAf8BQQHWAYEB/2QAAwEBAgMSARgDRwGCA14B/wNeAf8DXgH/A14B1QMo
ATwDCgEOFAADTgGZA2AB6wNeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNeAf8DXgH/A14B/wNmAfcDYQHh
AzQBVBwAA1UBsgFQAdsBgQH/AVcB3gGAAf8BQAHVAWkB/2wAAyYBOANMAZADZAHnA1oBwAM9AWgDDAEQ
GAADNgFYA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAA0cBgANHAYADRwGAAyEBMBwA
A1UBsgFHAdIBaAH/AUwB0wFfAf8BPwHUAWcB/3AAAxQBHANVAbUDQAFwdAADVAGrASIBuQEnAf8BIgG4
AScB/wEgAbUBIwH/cAADBgEIAyMBNAMXASD/AP8AXgABQgFNAT4HAAE+AwABKAMAAUADAAEwAwABAQEA
AQEFAAGAAQEWAAP/AQAE/wQABP8EAAT/BAABnAEYAZwBGAQAAZgBGAGYARgEAAGYAYABmAGABAABgAGB
AYABgQQAAYEBwwGBAcMEAAGAAcMBgAHDBAABmAGBAZgBgQQABIAEAAGBAQgBgQEIBAABgwEYAYMBGAQA
BP8EAAT/BAAE/wQAAYMBgAHnAYcC/wHgAQcBgwGAAcMBhwL/AfABBwHDAYABgQGHAv8B/AE/AcMBgAEA
AYcC/wH4AT8BwwGAAQABhwL/AfABHwHDAYMBAAGDAcABBwHwAQ8BwwGDAcMBgwH4AR8B4AEHAcMBgwHD
AYMBgAEBAcABBwHDAYMBwwGDAYABAwGAAQMBAAGDAcMBgwHAAQMBgAEBAQABhwHDAYAB4AEHAYABAQEA
AYcBwwGAAeABDwL/AYEBhwHDAYAB8AEfAv8BwwGHAcMBgAH4AR8C/wHnAYcBwwGAAfwBPwb/AfwBfwr/
AfwBPwb/AfwBPwb/AfwBPwT/AfwBfwH8AT8C/wGAAQEB+AEfAfwBPwL/AYABAQH4AR8BwAEBAcABAwGA
AQEB4AEPAcABAQHAAQMBwAEDAeABDwHAAQEBwAEDAcABAwHAAQMBwAEBAcABAwHgAQ8BgAEBAfwBPwL/
AeABDwGAAQEB/AE/Av8B+AEfAYABAQH8AT8C/wH8AX8C/wH8AT8C/wH8AX8S/ws=
</value>
</data>
<metadata name="ctxFilters.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
@@ -46,7 +46,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
if (args.Direction == System.Windows.Forms.Wizard.PageChangedDirection.Back)
return;
m_wrapper.EncodedFilters = filterEditor1.Filter;
m_wrapper.EncodedFilterXml = filterEditor1.FilterXml;
//Don't set args.NextPage, it runs on a list
}
@@ -55,7 +55,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
{
m_wrapper = new WizardSettingsWrapper(m_settings);
filterEditor1.Filter = m_wrapper.EncodedFilters;
filterEditor1.FilterXml = m_wrapper.EncodedFilterXml;
List<KeyValuePair<bool, string>> lst = new List<KeyValuePair<bool, string>>();
filterEditor1.BasePath = DynamicSetupHelper.GetSourceFolders(m_wrapper, new ApplicationSettings(m_wrapper.DataConnection ?? Program.DataConnection), lst);
@@ -205,7 +205,12 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
MessageBox.Show(this, Strings.SelectFiles.UpgradeWarning, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
string p = Library.Utility.Utility.AppendDirSeparator(m_wrapper.SourcePath);
List<KeyValuePair<bool, string>> filters = Library.Utility.FilenameFilter.DecodeFilter(m_wrapper.EncodedFilters);
System.Xml.XmlDocument doc = new System.Xml.XmlDocument();
doc.LoadXml(m_wrapper.EncodedFilterXml);
List<KeyValuePair<bool, string>> filters = new List<KeyValuePair<bool,string>>();
foreach (System.Xml.XmlNode n in doc.SelectNodes("root/filter"))
filters.Add(new KeyValuePair<bool, string>(bool.Parse(n.Attributes["include"].Value), n.Attributes["filter"].Value));
//See what folders are included with the current setup
Library.Utility.FilenameFilter filter = new Duplicati.Library.Utility.FilenameFilter(filters);
@@ -253,7 +258,19 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
//Make sure the extra filters are not included
if (!unsupported)
m_wrapper.EncodedFilters = Library.Utility.FilenameFilter.EncodeAsFilter(filters);
{
doc = new System.Xml.XmlDocument();
System.Xml.XmlNode root = doc.AppendChild(doc.CreateElement("root"));
foreach (KeyValuePair<bool, string> f in filters)
{
System.Xml.XmlNode n = root.AppendChild(doc.CreateElement("filter"));
n.Attributes.Append(doc.CreateAttribute("include")).Value = f.Key.ToString();
n.Attributes.Append(doc.CreateAttribute("filter")).Value = f.Value;
n.Attributes.Append(doc.CreateAttribute("globbing")).Value = "";
}
m_wrapper.EncodedFilterXml = doc.OuterXml;
}
if (unsupported)
FolderRadio.Checked = true;
@@ -120,7 +120,7 @@ namespace Duplicati.GUI.Wizard_pages
this.ScheduleName = schedule.Name;
this.SchedulePath = schedule.Path;
this.SourcePath = schedule.Task.SourcePath;
this.EncodedFilters = schedule.Task.EncodedFilter;
this.EncodedFilterXml = schedule.Task.FilterXml;
this.BackupPassword = schedule.Task.Encryptionkey;
this.Backend = schedule.Task.Service;
@@ -181,7 +181,7 @@ namespace Duplicati.GUI.Wizard_pages
if (schedule.Task == null)
schedule.Task = schedule.DataParent.Add<Datamodel.Task>();
schedule.Task.SourcePath = this.SourcePath;
schedule.Task.EncodedFilter = this.EncodedFilters;
schedule.Task.FilterXml = this.EncodedFilterXml;
schedule.Task.Encryptionkey = this.BackupPassword;
schedule.Task.Service = this.Backend;
@@ -471,10 +471,10 @@ namespace Duplicati.GUI.Wizard_pages
/// <summary>
/// The filter applied to files being backed up
/// </summary>
public string EncodedFilters
public string EncodedFilterXml
{
get { return GetItem<string>("EncodedFilters", ""); }
set { SetItem("EncodedFilters", value); }
get { return GetItem<string>("EncodedFilterXml", ""); }
set { SetItem("EncodedFilterXml", value); }
}
/// <summary>