diff --git a/Duplicati.sln b/Duplicati.sln
index 8d9fb766e..13f14c3cb 100644
--- a/Duplicati.sln
+++ b/Duplicati.sln
@@ -31,6 +31,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Logging",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Duplicati.Library.Backend.S3", "Duplicati\Library\Backend\S3\Duplicati.Library.Backend.S3.csproj", "{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "LightDatamodel", "..\LightDatamodel\LightDatamodel\LightDatamodel.csproj", "{CAE8433B-F013-474E-B7FC-4DE0D5933AD1}"
+EndProject
Global
GlobalSection(SubversionScc) = preSolution
Svn-Managed = True
@@ -39,68 +41,105 @@ Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
+ Test|Any CPU = Test|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Release|Any CPU.Build.0 = Release|Any CPU
+ {B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {B60D0993-B0C5-457A-90D9-DB6EEB33CE47}.Test|Any CPU.Build.0 = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}.Test|Any CPU.Build.0 = Release|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Debug|Any CPU.Build.0 = Debug|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|Any CPU.ActiveCfg = Release|Any CPU
{1470F75F-D364-4010-91D0-FD4DDA1C5159}.Release|Any CPU.Build.0 = Release|Any CPU
+ {1470F75F-D364-4010-91D0-FD4DDA1C5159}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {1470F75F-D364-4010-91D0-FD4DDA1C5159}.Test|Any CPU.Build.0 = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Release|Any CPU.Build.0 = Release|Any CPU
+ {DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}.Test|Any CPU.Build.0 = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Debug|Any CPU.Build.0 = Debug|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.ActiveCfg = Release|Any CPU
{10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {10D2D1B7-C664-41D8-9B3A-00040C3D421B}.Test|Any CPU.Build.0 = Release|Any CPU
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Debug|Any CPU.Build.0 = Debug|Any CPU
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Release|Any CPU.ActiveCfg = Release|Any CPU
{994F3D0A-E91E-4EEE-80EE-064485E09909}.Release|Any CPU.Build.0 = Release|Any CPU
+ {994F3D0A-E91E-4EEE-80EE-064485E09909}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {994F3D0A-E91E-4EEE-80EE-064485E09909}.Test|Any CPU.Build.0 = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Debug|Any CPU.Build.0 = Debug|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.ActiveCfg = Release|Any CPU
{0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Release|Any CPU.Build.0 = Release|Any CPU
+ {0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {0CA86ECF-5BEC-4909-B4F6-110A03B30B92}.Test|Any CPU.Build.0 = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Debug|Any CPU.Build.0 = Debug|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.ActiveCfg = Release|Any CPU
{FC9B7611-836F-4127-8B44-A7C31F506807}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC9B7611-836F-4127-8B44-A7C31F506807}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {FC9B7611-836F-4127-8B44-A7C31F506807}.Test|Any CPU.Build.0 = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {F61679A9-E5DE-468A-B5A4-05F92D0143D2}.Test|Any CPU.Build.0 = Release|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {6BA21DCB-1701-4936-B177-3B6D4DE3474E}.Test|Any CPU.Build.0 = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Debug|Any CPU.Build.0 = Debug|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.ActiveCfg = Release|Any CPU
{19ECCE09-B5EB-406C-8C57-BAC66997D469}.Release|Any CPU.Build.0 = Release|Any CPU
+ {19ECCE09-B5EB-406C-8C57-BAC66997D469}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {19ECCE09-B5EB-406C-8C57-BAC66997D469}.Test|Any CPU.Build.0 = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Debug|Any CPU.Build.0 = Debug|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.ActiveCfg = Release|Any CPU
{94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Release|Any CPU.Build.0 = Release|Any CPU
+ {94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {94484FDB-2EFA-4CF0-9BE6-A561157B4F87}.Test|Any CPU.Build.0 = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{47FE73E1-0832-44F7-96B9-2580273206C3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {47FE73E1-0832-44F7-96B9-2580273206C3}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {47FE73E1-0832-44F7-96B9-2580273206C3}.Test|Any CPU.Build.0 = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {D10A5FC0-11B4-4E70-86AA-8AEA52BD9798}.Test|Any CPU.Build.0 = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Test|Any CPU.ActiveCfg = Release|Any CPU
+ {C03F6DFD-805A-4BE0-9338-64870ADDB4A2}.Test|Any CPU.Build.0 = Release|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Release|Any CPU.Build.0 = Release|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Test|Any CPU.ActiveCfg = Test|Any CPU
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}.Test|Any CPU.Build.0 = Test|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/Duplicati/GUI/Database schema/2.Filter support.sql b/Duplicati/GUI/Database schema/2.Filter support.sql
new file mode 100644
index 000000000..c5afc5faf
--- /dev/null
+++ b/Duplicati/GUI/Database schema/2.Filter support.sql
@@ -0,0 +1,7 @@
+CREATE TABLE "TaskFilter" (
+ "ID" INTEGER PRIMARY KEY,
+ "SortOrder" INTEGER NULL,
+ "Include" BOOLEAN NULL,
+ "Filter" TEXT NULL,
+ "TaskID" INTEGER NULL
+);
diff --git a/Duplicati/GUI/Database schema/Schema.sql b/Duplicati/GUI/Database schema/Schema.sql
index 0d3c7d06b..a4f63567d 100644
--- a/Duplicati/GUI/Database schema/Schema.sql
+++ b/Duplicati/GUI/Database schema/Schema.sql
@@ -66,5 +66,13 @@ CREATE TABLE "ApplicationSetting" (
"Value" TEXT NULL
);
+CREATE TABLE "TaskFilter" (
+ "ID" INTEGER PRIMARY KEY,
+ "SortOrder" INTEGER NULL,
+ "Include" BOOLEAN NULL,
+ "Filter" TEXT NULL,
+ "TaskID" INTEGER NULL
+);
-INSERT INTO "Version" ("Version") VALUES (1);
\ No newline at end of file
+
+INSERT INTO "Version" ("Version") VALUES (2);
\ No newline at end of file
diff --git a/Duplicati/GUI/DatabaseUpgrader.cs b/Duplicati/GUI/DatabaseUpgrader.cs
index 6642c0b56..4d4535015 100644
--- a/Duplicati/GUI/DatabaseUpgrader.cs
+++ b/Duplicati/GUI/DatabaseUpgrader.cs
@@ -133,13 +133,14 @@ namespace Duplicati.GUI
if (upgrades.Count > 0)
{
- string backupfile = System.IO.Path.Combine(System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), System.Windows.Forms.Application.ProductName);
+ string backupfile = System.IO.Path.Combine(System.IO.Path.GetDirectoryName(sourcefile), "backup " + DateTime.Now.ToString("yyyyMMddhhmmss") + ".sqlite");
try
{
- //Keep a backup
- backupfile = System.IO.Path.Combine(backupfile, "backup " + DateTime.Now.ToString("yyyyMMddhhmmss") + ".sqlite");
+ if (!System.IO.Directory.Exists(System.IO.Path.GetDirectoryName(backupfile)))
+ System.IO.Directory.CreateDirectory(System.IO.Path.GetDirectoryName(backupfile));
+ //Keep a backup
System.IO.File.Copy(sourcefile, backupfile, false);
int newversion = -1;
diff --git a/Duplicati/GUI/Datamodel/Datamodel.csproj b/Duplicati/GUI/Datamodel/Datamodel.csproj
index 42a49a68d..ef3656f1d 100644
--- a/Duplicati/GUI/Datamodel/Datamodel.csproj
+++ b/Duplicati/GUI/Datamodel/Datamodel.csproj
@@ -70,10 +70,6 @@
prompt
-
- False
- .\LightDatamodel.dll
-
System
@@ -100,6 +96,7 @@
+
@@ -109,6 +106,10 @@
+
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}
+ LightDatamodel
+
{DE3E5D4C-51AB-4E5E-BEE8-E636CEBFBA65}
Duplicati.Library.Core
diff --git a/Duplicati/GUI/Datamodel/Duplicati.sqlite b/Duplicati/GUI/Datamodel/Duplicati.sqlite
index 1059b9def..4454ec0ed 100644
Binary files a/Duplicati/GUI/Datamodel/Duplicati.sqlite and b/Duplicati/GUI/Datamodel/Duplicati.sqlite differ
diff --git a/Duplicati/GUI/Datamodel/LightDataModel.Mapping.xml b/Duplicati/GUI/Datamodel/LightDataModel.Mapping.xml
index 9c453f728..85f884fb6 100644
--- a/Duplicati/GUI/Datamodel/LightDataModel.Mapping.xml
+++ b/Duplicati/GUI/Datamodel/LightDataModel.Mapping.xml
@@ -592,5 +592,80 @@
false
+
+ TaskFilter
+ TaskFilter
+ ID
+
+
+ System.Int64
+ ID
+ ID
+ true
+ true
+ false
+ false
+ false
+ true
+
+
+ System.Int64
+ SortOrder
+ SortOrder
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ System.Boolean
+ Include
+ Include
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ System.String
+ Filter
+ Filter
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ System.Int64
+ TaskID
+ TaskID
+ false
+ false
+ false
+ false
+ false
+ false
+
+
+ false
+
+
+ TaskFilterTask
+ TaskID
+ Task
+ OneToMany
+ Task
+ ID
+ Filters
+ TaskFilter
+
+
+
\ No newline at end of file
diff --git a/Duplicati/GUI/Datamodel/LightDatamodel.dll b/Duplicati/GUI/Datamodel/LightDatamodel.dll
index 08fec021d..41807e2e5 100644
Binary files a/Duplicati/GUI/Datamodel/LightDatamodel.dll and b/Duplicati/GUI/Datamodel/LightDatamodel.dll differ
diff --git a/Duplicati/GUI/Datamodel/Task.Extension.cs b/Duplicati/GUI/Datamodel/Task.Extension.cs
index 8830af196..e6a57805e 100644
--- a/Duplicati/GUI/Datamodel/Task.Extension.cs
+++ b/Duplicati/GUI/Datamodel/Task.Extension.cs
@@ -69,6 +69,17 @@ namespace Duplicati.Datamodel
public void GetOptions(Dictionary options)
{
this.Backend.GetOptions(options);
+
+ List> filters = new List>();
+ foreach (TaskFilter f in this.SortedFilters)
+ filters.Add(new KeyValuePair(f.Include, f.Filter));
+ if (filters.Count > 0)
+ {
+ string o = Library.Core.FilenameFilter.EncodeAsFilter(filters);
+ if (!o.StartsWith("--filter=")) throw new Exception("What happend here?");
+ o = o.Substring("--filter=".Length);
+ options["filter"] = o;
+ }
}
public bool ExistsInDb
@@ -76,5 +87,29 @@ namespace Duplicati.Datamodel
get { return this.ID > 0; }
}
- }
+
+ public TaskFilter[] SortedFilters
+ {
+ get
+ {
+ return System.Data.LightDatamodel.Query.Parse("ORDER BY SortOrder").EvaluateList(this.Filters).ToArray();
+ }
+ set
+ {
+ foreach (TaskFilter t in this.SortedFilters)
+ if (Array.IndexOf(value, t) >= 0)
+ this.Filters.Remove(t);
+ else
+ t.DataParent.DeleteObject(t);
+
+ int index = 0;
+ foreach (TaskFilter t in value)
+ {
+ t.SortOrder = index++;
+ this.Filters.Add(t);
+ }
+ }
+ }
+
+ }
}
diff --git a/Duplicati/GUI/Datamodel/Task.cs b/Duplicati/GUI/Datamodel/Task.cs
index 268d0a77a..1cebdd533 100644
--- a/Duplicati/GUI/Datamodel/Task.cs
+++ b/Duplicati/GUI/Datamodel/Task.cs
@@ -19,7 +19,7 @@ namespace Duplicati.Datamodel
#region " private members "
- [AutoIncrement, PrimaryKey, Relation("TaskSettingTask", typeof(TaskSetting), "TaskID", false), Relation("LogTask", typeof(Log), "TaskID", false), DatabaseField("ID")]
+ [AutoIncrement, PrimaryKey, Relation("TaskSettingTask", typeof(TaskSetting), "TaskID", false), Relation("LogTask", typeof(Log), "TaskID", false), Relation("TaskFilterTask", typeof(TaskFilter), "TaskID", false), DatabaseField("ID")]
private System.Int64 m_ID = long.MinValue;
[DatabaseField("Service")]
private System.String m_Service = "";
@@ -100,6 +100,15 @@ namespace Duplicati.Datamodel
}
}
+ [Affects(typeof(TaskFilter))]
+ public System.Collections.Generic.IList Filters
+ {
+ get
+ {
+ return ((DataFetcherWithRelations)m_dataparent).GetRelatedObjects("TaskFilterTask", this);
+ }
+ }
+
#endregion
}
diff --git a/Duplicati/GUI/Datamodel/TaskFilter.cs b/Duplicati/GUI/Datamodel/TaskFilter.cs
new file mode 100644
index 000000000..dd9fb5d2a
--- /dev/null
+++ b/Duplicati/GUI/Datamodel/TaskFilter.cs
@@ -0,0 +1,81 @@
+///
+/// This class was created by DataClassFileBuilder (LightDatamodel)
+///
+/// Table
+/// Duplicati.Datamodel
+/// TaskFilter
+///
+///
+
+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("TaskFilterTask", this); }
+ set{ ((DataFetcherWithRelations)m_dataparent).SetRelatedObject("TaskFilterTask", this, value); }
+ }
+
+#endregion
+
+ }
+
+}
\ No newline at end of file
diff --git a/Duplicati/GUI/Duplicati.csproj b/Duplicati/GUI/Duplicati.csproj
index e62207003..b4c990ae3 100644
--- a/Duplicati/GUI/Duplicati.csproj
+++ b/Duplicati/GUI/Duplicati.csproj
@@ -31,10 +31,6 @@
4
-
- False
- Datamodel\LightDatamodel.dll
-
@@ -159,6 +155,18 @@
AdvancedOptions.cs
+
+ Form
+
+
+ FilterDialog.cs
+
+
+ UserControl
+
+
+ FilterEditor.cs
+
UserControl
@@ -283,6 +291,10 @@
+
+ {CAE8433B-F013-474E-B7FC-4DE0D5933AD1}
+ LightDatamodel
+
{F2854848-BF78-4A6D-9A2A-2AE2AFB70DF1}
WizardForm
@@ -397,6 +409,14 @@
Designer
AdvancedOptions.cs
+
+ Designer
+ FilterDialog.cs
+
+
+ Designer
+ FilterEditor.cs
+
Designer
FinishedAdd.cs
@@ -478,6 +498,7 @@
SelectBackup.cs
+
diff --git a/Duplicati/GUI/HelperControls/BackupTreeView.cs b/Duplicati/GUI/HelperControls/BackupTreeView.cs
index 28bdc7a78..0a3ba0b56 100644
--- a/Duplicati/GUI/HelperControls/BackupTreeView.cs
+++ b/Duplicati/GUI/HelperControls/BackupTreeView.cs
@@ -77,6 +77,17 @@ namespace Duplicati.GUI.HelperControls
else
return treeView.SelectedNode.Tag as Schedule;
}
+ set
+ {
+ if (value == null)
+ treeView.SelectedNode = null;
+ else
+ {
+ TreeNode t;
+ FindNode((string.IsNullOrEmpty(value.Path) ? "" : value.Path + treeView.PathSeparator) + value.Name, false, out t);
+ treeView.SelectedNode = t;
+ }
+ }
}
diff --git a/Duplicati/GUI/HelperControls/DurationEditor.cs b/Duplicati/GUI/HelperControls/DurationEditor.cs
index 1896407d2..bd5ad5930 100644
--- a/Duplicati/GUI/HelperControls/DurationEditor.cs
+++ b/Duplicati/GUI/HelperControls/DurationEditor.cs
@@ -23,14 +23,19 @@ namespace Duplicati.GUI.HelperControls
/// Sets the avalible intervals
///
/// A dictionary where the key is the string to display and the value is the duplicity time string
- public void SetIntervals(Dictionary values)
+ public void SetIntervals(List> values)
{
- List vx = new List(values.Values);
- vx.Add("");
-
- m_values = vx.ToArray();
EasyDuration.Items.Clear();
- EasyDuration.Items.AddRange(new List(values.Keys).ToArray());
+
+ if (values[values.Count - 1].Key != "")
+ values.Add(new KeyValuePair("", ""));
+
+ m_values = new string[values.Count];
+ for (int i = 0; i < values.Count; i++)
+ {
+ m_values[i] = values[i].Value;
+ EasyDuration.Items.Add(values[i].Key);
+ }
}
private void EasyDuration_SelectedIndexChanged(object sender, EventArgs e)
diff --git a/Duplicati/GUI/Program.cs b/Duplicati/GUI/Program.cs
index 027cb99dd..3a1b6e936 100644
--- a/Duplicati/GUI/Program.cs
+++ b/Duplicati/GUI/Program.cs
@@ -147,7 +147,11 @@ namespace Duplicati.GUI
TrayIcon.DoubleClick += new EventHandler(TrayIcon_DoubleClick);
TrayIcon.Visible = true;
- if (Program.DataConnection.GetObjects().Length == 0)
+ long count = 0;
+ lock (MainLock)
+ count = Program.DataConnection.GetObjects().Length;
+
+ if (count == 0)
{
MessageBox.Show("Since this is the first time Duplicati is being run, the Wizard will now be shown.\r\nIf you wish to access the wizard again at some other time, you can right click the Duplicati icon in your system tray.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
ShowWizard();
diff --git a/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.Designer.cs b/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.Designer.cs
index 30e80cae1..5a163afba 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.Designer.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.Designer.cs
@@ -31,6 +31,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.SelectWhen = new System.Windows.Forms.CheckBox();
this.SelectIncremental = new System.Windows.Forms.CheckBox();
this.ThrottleOptions = new System.Windows.Forms.CheckBox();
+ this.EditFilters = new System.Windows.Forms.CheckBox();
this.SuspendLayout();
//
// SelectWhen
@@ -64,10 +65,21 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.ThrottleOptions.Text = "Select options that limit machine usage, such as bandwidth limits";
this.ThrottleOptions.UseVisualStyleBackColor = true;
//
+ // EditFilters
+ //
+ this.EditFilters.AutoSize = true;
+ this.EditFilters.Location = new System.Drawing.Point(32, 128);
+ this.EditFilters.Name = "EditFilters";
+ this.EditFilters.Size = new System.Drawing.Size(316, 17);
+ this.EditFilters.TabIndex = 4;
+ this.EditFilters.Text = "Modify filters that control what files are included in the backup";
+ this.EditFilters.UseVisualStyleBackColor = true;
+ //
// AdvancedOptions
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.Controls.Add(this.EditFilters);
this.Controls.Add(this.ThrottleOptions);
this.Controls.Add(this.SelectIncremental);
this.Controls.Add(this.SelectWhen);
@@ -83,5 +95,6 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
private System.Windows.Forms.CheckBox SelectWhen;
private System.Windows.Forms.CheckBox SelectIncremental;
private System.Windows.Forms.CheckBox ThrottleOptions;
+ private System.Windows.Forms.CheckBox EditFilters;
}
}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.cs b/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.cs
index 9aa3846fa..124810c1d 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/AdvancedOptions.cs
@@ -24,6 +24,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
m_settings["Advanced:When"] = SelectWhen.Checked;
m_settings["Advanced:Incremental"] = SelectIncremental.Checked;
m_settings["Advanced:Throttle"] = ThrottleOptions.Checked;
+ m_settings["Advanced:Filters"] = EditFilters.Checked;
if (args.Direction == PageChangedDirection.Back)
return;
@@ -34,6 +35,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
args.NextPage = new Wizard_pages.Add_backup.IncrementalSettings();
else if (ThrottleOptions.Checked)
args.NextPage = new Wizard_pages.Add_backup.ThrottleOptions();
+ else if (EditFilters.Checked)
+ args.NextPage = new Wizard_pages.Add_backup.FilterEditor();
else
args.NextPage = new Wizard_pages.Add_backup.FinishedAdd();
}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.Designer.cs b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.Designer.cs
new file mode 100644
index 000000000..64a133455
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.Designer.cs
@@ -0,0 +1,144 @@
+namespace Duplicati.GUI.Wizard_pages.Add_backup
+{
+ partial class FilterDialog
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ private void InitializeComponent()
+ {
+ this.Inclusive = new System.Windows.Forms.RadioButton();
+ this.Exclusive = new System.Windows.Forms.RadioButton();
+ this.label1 = new System.Windows.Forms.Label();
+ this.Filter = new System.Windows.Forms.TextBox();
+ this.OKBtn = new System.Windows.Forms.Button();
+ this.CancelBtn = new System.Windows.Forms.Button();
+ this.IsRegExp = new System.Windows.Forms.CheckBox();
+ this.SuspendLayout();
+ //
+ // Inclusive
+ //
+ this.Inclusive.AutoSize = true;
+ this.Inclusive.Checked = true;
+ this.Inclusive.Location = new System.Drawing.Point(8, 8);
+ this.Inclusive.Name = "Inclusive";
+ this.Inclusive.Size = new System.Drawing.Size(167, 17);
+ this.Inclusive.TabIndex = 0;
+ this.Inclusive.TabStop = true;
+ this.Inclusive.Text = "Include files matching the filter";
+ this.Inclusive.UseVisualStyleBackColor = true;
+ //
+ // Exclusive
+ //
+ this.Exclusive.AutoSize = true;
+ this.Exclusive.Location = new System.Drawing.Point(8, 32);
+ this.Exclusive.Name = "Exclusive";
+ this.Exclusive.Size = new System.Drawing.Size(170, 17);
+ this.Exclusive.TabIndex = 1;
+ this.Exclusive.Text = "Exclude files matching the filter";
+ this.Exclusive.UseVisualStyleBackColor = true;
+ //
+ // label1
+ //
+ this.label1.AutoSize = true;
+ this.label1.Location = new System.Drawing.Point(8, 64);
+ this.label1.Name = "label1";
+ this.label1.Size = new System.Drawing.Size(29, 13);
+ this.label1.TabIndex = 2;
+ this.label1.Text = "Filter";
+ //
+ // Filter
+ //
+ this.Filter.Location = new System.Drawing.Point(56, 64);
+ this.Filter.Name = "Filter";
+ this.Filter.Size = new System.Drawing.Size(320, 20);
+ this.Filter.TabIndex = 3;
+ //
+ // OKBtn
+ //
+ this.OKBtn.Location = new System.Drawing.Point(112, 96);
+ this.OKBtn.Name = "OKBtn";
+ this.OKBtn.Size = new System.Drawing.Size(75, 23);
+ this.OKBtn.TabIndex = 4;
+ this.OKBtn.Text = "OK";
+ this.OKBtn.UseVisualStyleBackColor = true;
+ this.OKBtn.Click += new System.EventHandler(this.OKBtn_Click);
+ //
+ // CancelBtn
+ //
+ this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel;
+ this.CancelBtn.Location = new System.Drawing.Point(200, 96);
+ this.CancelBtn.Name = "CancelBtn";
+ this.CancelBtn.Size = new System.Drawing.Size(75, 23);
+ this.CancelBtn.TabIndex = 5;
+ this.CancelBtn.Text = "Cancel";
+ this.CancelBtn.UseVisualStyleBackColor = true;
+ //
+ // IsRegExp
+ //
+ this.IsRegExp.AutoSize = true;
+ this.IsRegExp.Checked = true;
+ this.IsRegExp.CheckState = System.Windows.Forms.CheckState.Checked;
+ this.IsRegExp.Location = new System.Drawing.Point(224, 48);
+ this.IsRegExp.Name = "IsRegExp";
+ this.IsRegExp.Size = new System.Drawing.Size(146, 17);
+ this.IsRegExp.TabIndex = 6;
+ this.IsRegExp.Text = "Filter is regular expression";
+ this.IsRegExp.UseVisualStyleBackColor = true;
+ //
+ // FilterDialog
+ //
+ this.AcceptButton = this.OKBtn;
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
+ this.CancelButton = this.CancelBtn;
+ this.ClientSize = new System.Drawing.Size(389, 126);
+ this.Controls.Add(this.Filter);
+ this.Controls.Add(this.IsRegExp);
+ this.Controls.Add(this.CancelBtn);
+ this.Controls.Add(this.OKBtn);
+ this.Controls.Add(this.label1);
+ this.Controls.Add(this.Exclusive);
+ this.Controls.Add(this.Inclusive);
+ this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedToolWindow;
+ this.Name = "FilterDialog";
+ this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent;
+ this.Text = "FilterDialog";
+ this.Load += new System.EventHandler(this.FilterDialog_Load);
+ this.ResumeLayout(false);
+ this.PerformLayout();
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.RadioButton Inclusive;
+ private System.Windows.Forms.RadioButton Exclusive;
+ private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.TextBox Filter;
+ private System.Windows.Forms.Button OKBtn;
+ private System.Windows.Forms.Button CancelBtn;
+ private System.Windows.Forms.CheckBox IsRegExp;
+ }
+}
\ No newline at end of file
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.cs b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.cs
new file mode 100644
index 000000000..ce3e130fd
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.cs
@@ -0,0 +1,68 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using Duplicati.Datamodel;
+
+namespace Duplicati.GUI.Wizard_pages.Add_backup
+{
+ public partial class FilterDialog : Form
+ {
+ TaskFilter m_filter;
+
+ public FilterDialog(TaskFilter filter)
+ : this()
+ {
+ m_filter = filter;
+ }
+
+ private FilterDialog()
+ {
+ InitializeComponent();
+ }
+
+ private void OKBtn_Click(object sender, EventArgs e)
+ {
+ m_filter.Include = Inclusive.Checked;
+ if (IsRegExp.Checked)
+ {
+ try
+ {
+ System.Text.RegularExpressions.Regex re = new System.Text.RegularExpressions.Regex(Filter.Text);
+ }
+ catch (Exception ex)
+ {
+ MessageBox.Show(this, "The expression is not a valid regular expression: " + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error);
+ return;
+ }
+ m_filter.Filter = Filter.Text;
+ }
+ else
+ m_filter.Filter = Library.Core.FilenameFilter.ConvertGlobbingToRegExp(Filter.Text);
+
+ this.DialogResult = DialogResult.OK;
+ this.Close();
+ }
+
+ private void FilterDialog_Load(object sender, EventArgs e)
+ {
+ if (m_filter != null)
+ {
+ Inclusive.Checked = m_filter.Include;
+ Exclusive.Checked = !m_filter.Include;
+ Filter.Text = m_filter.Filter;
+ if (!string.IsNullOrEmpty(m_filter.Filter))
+ IsRegExp.Checked = true;
+ else
+ IsRegExp.Checked = false;
+ }
+
+ try { Filter.Focus(); }
+ catch { }
+
+ }
+ }
+}
\ No newline at end of file
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.resx b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.resx
new file mode 100644
index 000000000..ff31a6db5
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterDialog.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.Designer.cs b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.Designer.cs
new file mode 100644
index 000000000..ce028ddbc
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.Designer.cs
@@ -0,0 +1,232 @@
+namespace Duplicati.GUI.Wizard_pages.Add_backup
+{
+ partial class FilterEditor
+ {
+ ///
+ /// Required designer variable.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Clean up any resources being used.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing && (components != null))
+ {
+ components.Dispose();
+ }
+ base.Dispose(disposing);
+ }
+
+ #region Windows Form Designer generated code
+
+ ///
+ /// Required method for Designer support - do not modify
+ /// the contents of this method with the code editor.
+ ///
+ 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.toolStrip1 = new System.Windows.Forms.ToolStrip();
+ this.AddFilterButton = new System.Windows.Forms.ToolStripButton();
+ this.RemoveFilterButton = 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.EditFilterButton = new System.Windows.Forms.ToolStripButton();
+ this.listView = new System.Windows.Forms.ListView();
+ this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
+ this.imageList1 = new System.Windows.Forms.ImageList(this.components);
+ this.groupBox1.SuspendLayout();
+ this.toolStrip1.SuspendLayout();
+ this.SuspendLayout();
+ //
+ // groupBox1
+ //
+ this.groupBox1.Controls.Add(this.listView);
+ this.groupBox1.Controls.Add(this.toolStrip1);
+ this.groupBox1.Location = new System.Drawing.Point(16, 16);
+ this.groupBox1.Name = "groupBox1";
+ this.groupBox1.Size = new System.Drawing.Size(464, 200);
+ this.groupBox1.TabIndex = 0;
+ this.groupBox1.TabStop = false;
+ this.groupBox1.Text = "Filters";
+ //
+ // toolStrip1
+ //
+ this.toolStrip1.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
+ this.toolStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
+ this.AddFilterButton,
+ this.RemoveFilterButton,
+ this.EditFilterButton,
+ this.toolStripSeparator1,
+ this.MoveFilterUpButton,
+ this.MoveFilterDownButton,
+ this.toolStripSeparator2,
+ this.MoveFilterTopButton,
+ this.MoveFilterBottomButton});
+ this.toolStrip1.Location = new System.Drawing.Point(3, 16);
+ this.toolStrip1.Name = "toolStrip1";
+ this.toolStrip1.RenderMode = System.Windows.Forms.ToolStripRenderMode.System;
+ this.toolStrip1.Size = new System.Drawing.Size(458, 25);
+ this.toolStrip1.TabIndex = 0;
+ this.toolStrip1.Text = "toolStrip1";
+ //
+ // AddFilterButton
+ //
+ this.AddFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.AddFilterButton.Image = ((System.Drawing.Image)(resources.GetObject("AddFilterButton.Image")));
+ this.AddFilterButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.AddFilterButton.Name = "AddFilterButton";
+ this.AddFilterButton.Size = new System.Drawing.Size(23, 22);
+ this.AddFilterButton.Text = "toolStripButton1";
+ this.AddFilterButton.ToolTipText = "Add a new filter";
+ this.AddFilterButton.Click += new System.EventHandler(this.AddFilterButton_Click);
+ //
+ // RemoveFilterButton
+ //
+ this.RemoveFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.RemoveFilterButton.Enabled = false;
+ this.RemoveFilterButton.Image = ((System.Drawing.Image)(resources.GetObject("RemoveFilterButton.Image")));
+ this.RemoveFilterButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.RemoveFilterButton.Name = "RemoveFilterButton";
+ this.RemoveFilterButton.Size = new System.Drawing.Size(23, 22);
+ this.RemoveFilterButton.Text = "toolStripButton2";
+ this.RemoveFilterButton.ToolTipText = "Remove the selected filter";
+ this.RemoveFilterButton.Click += new System.EventHandler(this.RemoveFilterButton_Click);
+ //
+ // toolStripSeparator1
+ //
+ this.toolStripSeparator1.Name = "toolStripSeparator1";
+ this.toolStripSeparator1.Size = new System.Drawing.Size(6, 25);
+ //
+ // MoveFilterUpButton
+ //
+ this.MoveFilterUpButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.MoveFilterUpButton.Enabled = false;
+ this.MoveFilterUpButton.Image = ((System.Drawing.Image)(resources.GetObject("MoveFilterUpButton.Image")));
+ this.MoveFilterUpButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.MoveFilterUpButton.Name = "MoveFilterUpButton";
+ this.MoveFilterUpButton.Size = new System.Drawing.Size(23, 22);
+ this.MoveFilterUpButton.Text = "toolStripButton3";
+ this.MoveFilterUpButton.ToolTipText = "Move the selected filter up";
+ this.MoveFilterUpButton.Click += new System.EventHandler(this.MoveFilterUpButton_Click);
+ //
+ // MoveFilterDownButton
+ //
+ this.MoveFilterDownButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.MoveFilterDownButton.Enabled = false;
+ this.MoveFilterDownButton.Image = ((System.Drawing.Image)(resources.GetObject("MoveFilterDownButton.Image")));
+ this.MoveFilterDownButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.MoveFilterDownButton.Name = "MoveFilterDownButton";
+ this.MoveFilterDownButton.Size = new System.Drawing.Size(23, 22);
+ this.MoveFilterDownButton.Text = "toolStripButton4";
+ this.MoveFilterDownButton.ToolTipText = "Move the selected filter down";
+ this.MoveFilterDownButton.Click += new System.EventHandler(this.MoveFilterDownButton_Click);
+ //
+ // toolStripSeparator2
+ //
+ this.toolStripSeparator2.Name = "toolStripSeparator2";
+ this.toolStripSeparator2.Size = new System.Drawing.Size(6, 25);
+ //
+ // MoveFilterTopButton
+ //
+ this.MoveFilterTopButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.MoveFilterTopButton.Enabled = false;
+ this.MoveFilterTopButton.Image = ((System.Drawing.Image)(resources.GetObject("MoveFilterTopButton.Image")));
+ this.MoveFilterTopButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.MoveFilterTopButton.Name = "MoveFilterTopButton";
+ this.MoveFilterTopButton.Size = new System.Drawing.Size(23, 22);
+ this.MoveFilterTopButton.Text = "toolStripButton5";
+ this.MoveFilterTopButton.ToolTipText = "Move the selected filter to the top";
+ this.MoveFilterTopButton.Click += new System.EventHandler(this.MoveFilterTopButton_Click);
+ //
+ // MoveFilterBottomButton
+ //
+ this.MoveFilterBottomButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.MoveFilterBottomButton.Enabled = false;
+ this.MoveFilterBottomButton.Image = ((System.Drawing.Image)(resources.GetObject("MoveFilterBottomButton.Image")));
+ this.MoveFilterBottomButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.MoveFilterBottomButton.Name = "MoveFilterBottomButton";
+ this.MoveFilterBottomButton.Size = new System.Drawing.Size(23, 22);
+ this.MoveFilterBottomButton.Text = "toolStripButton6";
+ this.MoveFilterBottomButton.ToolTipText = "Move the selected filter to the bottom";
+ this.MoveFilterBottomButton.Click += new System.EventHandler(this.MoveFilterBottomButton_Click);
+ //
+ // EditFilterButton
+ //
+ this.EditFilterButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
+ this.EditFilterButton.Enabled = false;
+ this.EditFilterButton.Image = ((System.Drawing.Image)(resources.GetObject("EditFilterButton.Image")));
+ this.EditFilterButton.ImageTransparentColor = System.Drawing.Color.Magenta;
+ this.EditFilterButton.Name = "EditFilterButton";
+ this.EditFilterButton.Size = new System.Drawing.Size(23, 22);
+ this.EditFilterButton.Text = "toolStripButton1";
+ this.EditFilterButton.ToolTipText = "Edit the selected filter";
+ this.EditFilterButton.Click += new System.EventHandler(this.EditFilterButton_Click);
+ //
+ // listView
+ //
+ this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
+ this.columnHeader1});
+ this.listView.Dock = System.Windows.Forms.DockStyle.Fill;
+ this.listView.FullRowSelect = true;
+ this.listView.HeaderStyle = System.Windows.Forms.ColumnHeaderStyle.None;
+ this.listView.Location = new System.Drawing.Point(3, 41);
+ this.listView.Name = "listView";
+ this.listView.Size = new System.Drawing.Size(458, 156);
+ this.listView.SmallImageList = this.imageList1;
+ this.listView.TabIndex = 1;
+ this.listView.UseCompatibleStateImageBehavior = false;
+ this.listView.View = System.Windows.Forms.View.Details;
+ this.listView.SelectedIndexChanged += new System.EventHandler(this.listView_SelectedIndexChanged);
+ //
+ // columnHeader1
+ //
+ this.columnHeader1.Width = 420;
+ //
+ // imageList1
+ //
+ this.imageList1.ImageStream = ((System.Windows.Forms.ImageListStreamer)(resources.GetObject("imageList1.ImageStream")));
+ this.imageList1.TransparentColor = System.Drawing.Color.Transparent;
+ this.imageList1.Images.SetKeyName(0, "Inclusion.ico");
+ this.imageList1.Images.SetKeyName(1, "Exclusion.ico");
+ //
+ // FilterEditor
+ //
+ this.Controls.Add(this.groupBox1);
+ this.Name = "FilterEditor";
+ this.Size = new System.Drawing.Size(506, 242);
+ this.groupBox1.ResumeLayout(false);
+ this.groupBox1.PerformLayout();
+ this.toolStrip1.ResumeLayout(false);
+ this.toolStrip1.PerformLayout();
+ this.ResumeLayout(false);
+
+ }
+
+ #endregion
+
+ private System.Windows.Forms.GroupBox groupBox1;
+ private System.Windows.Forms.ToolStrip toolStrip1;
+ private System.Windows.Forms.ToolStripButton AddFilterButton;
+ private System.Windows.Forms.ToolStripButton RemoveFilterButton;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
+ private System.Windows.Forms.ToolStripButton MoveFilterUpButton;
+ private System.Windows.Forms.ToolStripButton MoveFilterDownButton;
+ private System.Windows.Forms.ToolStripSeparator toolStripSeparator2;
+ private System.Windows.Forms.ToolStripButton MoveFilterTopButton;
+ private System.Windows.Forms.ToolStripButton MoveFilterBottomButton;
+ private System.Windows.Forms.ToolStripButton EditFilterButton;
+ private System.Windows.Forms.ListView listView;
+ private System.Windows.Forms.ColumnHeader columnHeader1;
+ private System.Windows.Forms.ImageList imageList1;
+ }
+}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.cs b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.cs
new file mode 100644
index 000000000..9d4efe9f6
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.cs
@@ -0,0 +1,153 @@
+using System;
+using System.Collections.Generic;
+using System.ComponentModel;
+using System.Data;
+using System.Drawing;
+using System.Text;
+using System.Windows.Forms;
+using Duplicati.Datamodel;
+
+namespace Duplicati.GUI.Wizard_pages.Add_backup
+{
+ public partial class FilterEditor : System.Windows.Forms.Wizard.WizardControl
+ {
+ Task m_task;
+
+ public FilterEditor()
+ : base("Edit filters", "On this page you can modify filters that control what files are included in the backup.")
+ {
+ InitializeComponent();
+
+ base.PageEnter += new System.Windows.Forms.Wizard.PageChangeHandler(FilterEditor_PageEnter);
+ base.PageLeave += new System.Windows.Forms.Wizard.PageChangeHandler(FilterEditor_PageLeave);
+ }
+
+ void FilterEditor_PageLeave(object sender, System.Windows.Forms.Wizard.PageChangedArgs args)
+ {
+ if (args.Direction == System.Windows.Forms.Wizard.PageChangedDirection.Back)
+ return;
+
+ List filters = new List();
+ foreach (ListViewItem lvi in listView.Items)
+ {
+ if ((lvi.Tag as TaskFilter).DataParent == null)
+ m_task.DataParent.Add(lvi.Tag as TaskFilter);
+ filters.Add(lvi.Tag as TaskFilter);
+ }
+
+ m_task.SortedFilters = filters.ToArray();
+
+ args.NextPage = new Wizard_pages.Add_backup.FinishedAdd();
+ }
+
+ void FilterEditor_PageEnter(object sender, System.Windows.Forms.Wizard.PageChangedArgs args)
+ {
+ m_task = m_task = ((Schedule)m_settings["Schedule"]).Tasks[0];
+
+ listView.Items.Clear();
+ foreach (TaskFilter tf in m_task.SortedFilters)
+ {
+ ListViewItem lvi = new ListViewItem(tf.Filter, tf.Include ? 0 : 1);
+ lvi.Tag = tf;
+ listView.Items.Add(lvi);
+ }
+
+ if (listView.Items.Count > 0)
+ listView.Items[0].Selected = true;
+ }
+
+ private void listView_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ RemoveFilterButton.Enabled =
+ EditFilterButton.Enabled = listView.SelectedItems.Count == 1;
+
+ MoveFilterUpButton.Enabled =
+ MoveFilterTopButton.Enabled = listView.SelectedItems.Count == 1 && listView.SelectedItems[0].Index != 0;
+
+ MoveFilterDownButton.Enabled =
+ MoveFilterBottomButton.Enabled = listView.SelectedItems.Count == 1 && listView.SelectedItems[0].Index != listView.Items.Count - 1;
+ }
+
+ private void RemoveFilterButton_Click(object sender, EventArgs e)
+ {
+ while(listView.SelectedItems.Count > 0)
+ listView.Items.Remove(listView.SelectedItems[0]);
+ }
+
+ private void EditFilterButton_Click(object sender, EventArgs e)
+ {
+ if (listView.SelectedItems.Count == 1 && listView.SelectedItems[0].Tag is TaskFilter)
+ {
+ TaskFilter tf = listView.SelectedItems[0].Tag as TaskFilter;
+ FilterDialog dlg = new FilterDialog(tf);
+ if (dlg.ShowDialog(this) == DialogResult.OK)
+ {
+ listView.SelectedItems[0].Text = tf.Filter;
+ listView.SelectedItems[0].ImageIndex = tf.Include ? 0 : 1;
+ }
+ }
+ }
+
+ private void MoveFilterUpButton_Click(object sender, EventArgs e)
+ {
+ if (listView.SelectedItems.Count == 1)
+ {
+ ListViewItem lvi = listView.SelectedItems[0];
+ int index = listView.SelectedItems[0].Index;
+ listView.Items.RemoveAt(index);
+ listView.Items.Insert(index - 1, lvi);
+ lvi.Selected = true;
+ }
+ }
+
+ private void MoveFilterDownButton_Click(object sender, EventArgs e)
+ {
+ if (listView.SelectedItems.Count == 1)
+ {
+ ListViewItem lvi = listView.SelectedItems[0];
+ int index = listView.SelectedItems[0].Index;
+ listView.Items.RemoveAt(index);
+ listView.Items.Insert(index + 1, lvi);
+ lvi.Selected = true;
+ }
+ }
+
+ private void MoveFilterTopButton_Click(object sender, EventArgs e)
+ {
+ if (listView.SelectedItems.Count == 1)
+ {
+ ListViewItem lvi = listView.SelectedItems[0];
+ int index = listView.SelectedItems[0].Index;
+ listView.Items.RemoveAt(index);
+ listView.Items.Insert(0, lvi);
+ lvi.Selected = true;
+ }
+ }
+
+ private void MoveFilterBottomButton_Click(object sender, EventArgs e)
+ {
+ if (listView.SelectedItems.Count == 1)
+ {
+ ListViewItem lvi = listView.SelectedItems[0];
+ int index = listView.SelectedItems[0].Index;
+ listView.Items.RemoveAt(index);
+ listView.Items.Insert(listView.Items.Count, lvi);
+ lvi.Selected = true;
+ }
+ }
+
+ private void AddFilterButton_Click(object sender, EventArgs e)
+ {
+ TaskFilter tf = new TaskFilter();
+ FilterDialog dlg = new FilterDialog(tf);
+ if (dlg.ShowDialog(this) == DialogResult.OK)
+ {
+ ListViewItem lvi = new ListViewItem(tf.Filter, tf.Include ? 0 : 1);
+ lvi.Tag = tf;
+ listView.Items.Add(lvi);
+ }
+
+ }
+ }
+}
+
diff --git a/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.resx b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.resx
new file mode 100644
index 000000000..eddab68d2
--- /dev/null
+++ b/Duplicati/GUI/Wizard pages/Add backup/FilterEditor.resx
@@ -0,0 +1,253 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ 116, 17
+
+
+
+ AAEAAAD/////AQAAAAAAAAAMAgAAAFdTeXN0ZW0uV2luZG93cy5Gb3JtcywgVmVyc2lvbj0yLjAuMC4w
+ LCBDdWx0dXJlPW5ldXRyYWwsIFB1YmxpY0tleVRva2VuPWI3N2E1YzU2MTkzNGUwODkFAQAAACZTeXN0
+ ZW0uV2luZG93cy5Gb3Jtcy5JbWFnZUxpc3RTdHJlYW1lcgEAAAAERGF0YQcCAgAAAAkDAAAADwMAAAAU
+ BQAAAk1TRnQBSQFMAgEBAgEAAQQBAAEEAQABEAEAARABAAT/ASEBAAj/AUIBTQE2BwABNgMAASgDAAFA
+ AwABEAMAAQEBAAEgBgABEP8AKwABFQEDAQEBGgEsAQwBBAFDASwBDAEEAUMBLAEMAQQBQ/AAAUEBUAEU
+ AbIBUwHiAYwB/wFSAeEBiQH/AUQByAFsAf/wAAFCAVABFQGyAUcB1AFnAf8BPgHLAU4B/wFEAckBbAH/
+ 8AABQgFSARUBsgFPAdoBcQH/AT8BzAFQAf8BRAHKAWwB//AAAUIBUwEVAbIBWwHjAX4B/wFLAdQBXQH/
+ AUUBywFtAf/gAAEyAbQBNgH+AU4B0wFzAf8BTgHUAXUB/wFPAdQBdQH/AU4B0wF0Af8BZwHqAYQB/wFa
+ Ad8BbQH/AVgB4wGQAf8BRQHKAWsB/wFDAcgBagH/AUIBxgFoAf8BQgHFAWgB/wExAQ8BBQFMDAABQgEN
+ ATMBhAJKAdMB/wJMAdQB/wJOAdQB/wJPAdMB/wJOAdAB/wJLAcwB/wJHAccB/wJDAcMB/wJBAcIB/wJB
+ AcIB/wIwAagB/5AAATYBuQE+Af4BYwHaAXYB/wFsAeQBgAH/AXIB7AGGAf8BdQHwAYoB/wFyAe8BhwH/
+ AWkB6gF+Af8BXAHhAXAB/wFPAdcBYQH/AUMBzgFUAf8BPgHLAU4B/wFRAeABhwH/ATEBDwEFAUwMAAFC
+ AQ0BMwGEAlwB1wH/AmMB1gH/Am8B5AH/AncB7gH/AncB8AH/AmsB6QH/AlgB3AH/AkgB0AH/AkMBzAH/
+ AkMBzAH/AjoBtwH/kAABNgG6AT4B/gFcAdYBfQH/AWQB3wGFAf8BawHnAY0B/wFwAe4BkwH/AXUB7wGK
+ Af8BcwHwAYgB/wFrAewBhgH/AWAB5wGCAf8BVQHeAXcB/wFLAdcBbAH/AVIB4QGKAf8BMQEPAQUBTAwA
+ AUIBDQEzAYQCXQHaAf8CZAHdAf8CbgHoAf8CdAHwAf8CdAHyAf8CawHsAf8CXAHiAf8CTgHYAf8CSQHU
+ Af8CSQHUAf8COgG3Af+QAAFEAVgBFgGxAUMBXAEYAbUBQwFcARgBtQFDAVoBFwG1ATYBkQEkAegBcAHt
+ AZMB/wF1Ae8BiQH/AVEB1gF7Af8BQQFWARYBtQFAAVUBFQG1AUABUwEVAbUBQAFTARUBtQEZAQQBAgEh
+ DAABLgEFAQ8BRgFDARgBXwG1AUMBGAFfAbUBQwEYAV8BtQFDARgBXwG1AUMBGAFeAbUBQgEXAVoBtQFB
+ ARYBVwG1AUABFQFUAbUBQAEVAVIBtQE/ARQBTgG1AUABFAFMAbSgAAFDAVcBFwGyAWkB5QGLAf8BcAHo
+ AYMB/wFRAdYBewH/8AABQwFZARcBsgFgAdsBgQH/AWcB3gF6Af8BUAHVAXkB//AAAUMBWQEXAbIBVwHS
+ AXgB/wFcAdMBbwH/AU8B1AF3Af/wAAFEAVMBFgGrATIBuQE3Af8BMgG4ATcB/wEwAbUBMwH//wD/ANoA
+ AUIBTQE+BwABPgMAASgDAAFAAwABEAMAAQEBAAEBBQABgBcAA/8BAAT/BAAB/AE/Av8EAAH8AT8C/wQA
+ AfwBPwL/BAAB/AE/Av8EAAH8AT8C/wQAAcABAQHAAQMEAAHAAQEBwAEDBAABwAEBAcABAwQAAcABAQHA
+ AQMEAAH8AT8C/wQAAfwBPwL/BAAB/AE/Av8EAAH8AT8C/wQABP8EAAT/BAAL
+
+
+
+ 17, 17
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAiNJREFUOE+Fk29L
+ U3EUx+cr6AVES+e8btVEcwUlKWZI0IOQLIaNYrJqgc7sUrlCbG0oxmrhkpRkVGQM+ocPKpoRxHJXcW61
+ SX8IZBA9CXrQK/jW98BuXebqwIHfPfd8P/ec8zu3ylTB3DEXvv38Km83bthkut+fqKqUa4hvDdRi/+12
+ qMl+jKaD4jzvm96DLRetqAhR753BtjErBpI+RHNXMbkaxdTHCdzKTSC2eg2R7Ch8zz2Sw9wyUH3IDM+z
+ HowsD2GscBnj2RAWi2lxQsL5YVxZ9qNn7hCUsNkIYNm77zahL3UCQ9lBjOQDCGqXULJ4fhrD789DXenD
+ 6de92Bl3gBq9CnukBh2PdsG74IY/c1IggZSqA6ZyMYnxnSflQsuTJlAjAE67YaYOrU+dOD7fjYE3PlxY
+ +O0vB3XATe2GxPl15hBADbWm9nCLPDgf23EnP6OLKh04k+aHNtFQqwMY5LD+Z1rxrRFQaoGA7vlOBNI+
+ hDJ+jGtnddZsYVJugK2xhVIF0gKNA9mRULD3lQ1dSw4cyzXCqzl1QPRTL46uNOKg5kBb0o7mB8qfIRLA
+ K9ket6IzWQdXTsGpzzb43zkMAO8HGw5n6tHxQpH+DddICBepLWGBe8kC/5oF6lo1ij8K4te/dEnsiFYr
+ Ocwt20Sup+0vyLniZgS/m8UJI7h1tkZy1l3lEpGlNUTMknxgrlqcZ8bKyv7X78kJ857p+rTXEfwChEDw
+ QjpqrrIAAAAASUVORK5CYII=
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAe9JREFUOE+FU99L
+ U3EU3976G6SnoIcpk5rU7AebFjFBaRkRCCJEOmbqMmoOUxwLVhuBbhLLBhUVCD7aS5BPPokPQRDU7CGN
+ 2noI79xcbNa8n+7nyBa3280vfOB7P+dzPpxz7vlaLSZn0deHSu6rRA80HLR408+tZlodP9/ajJXLXdgI
+ j+FbIi5Yn7wp3AunHaYmryeCWDplE/HWo1n8eDqH8rO0oPQ4BSU1jY3gEF6dsINag9HL4zZ8uT6A7ft3
+ gNkYdtNJHX4m76EYm8LnwT5Qayh7rdOFwsQoqtHbUGeidRPMzcidnBoJYis0jIznpL6dZa2s3CUPdm75
+ RYR4uG5SSxZOi5UCV5DtPgvmSBWc9ju3A5sayaCiVaHcnTQiEoIyHsD3G/2iZQ5zLQtdZ+Sj4nVi88lD
+ 7HeUN6tQPK3ItDvAXDH41HFESE56v2MwYBnvNTcaFK5eRD42jnxiag8P9GBrbIHaegucAweSPXcMOxec
+ UHtPAz43MOL6g2va3dcmMbZKbX2INOD2sY28twXV3qNQfQ5gqEUHcoxRQ61hK7kcDBR77KgO2PArcAjq
+ 6GEB7+QYo8awSKyC68nAx/ONUHqaUPbvJRK8k/vQYRfNP1e5tposjW/iradJzAjeyf33Mf39OPh3+IsJ
+ WRiT8xtNQweCAHQ6FwAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAcZJREFUOE+VU0sv
+ Q0EYvR4bP8HCxg+w6Fq6FhIhIiFWFpZlK7FkxaKJV6RCsChtpBpBKPqMtqlalDaVEpS6RVUrDW2jevQb
+ pqq9bWKSk7kz957znfPN3CrhZ7jdPmSzSaGmtlb4zGSE6uo6gdZ8iKIodHS0V+U3ih9S6Q+8JtJlYTI7
+ YDRaUFEgGk+BQEKR2PfM9+x2B0J3ofIi5ICTC2cu4DkLQLexDe2sCoae3lInPAJV5iQ+P0XfQLi8EmFr
+ bUOgpQVmufyvCHcgPsTZh+eB2zz42uc9g3VOBb1MBt3AQKkAZQ7ev+QFODHgNuDaMgjqg1a7Ds2EUjoC
+ WS52EPRa8WqSIayvh1/dx5ooeRo8AndA1alydL+JkR9VDYhou5lDclJynFwgHHlnEQorE/l2uQ102S6D
+ z5UF7sNxULNiO7+VH1a7YHd4sHd4DJvTC71+U9oBHSFZ9J9qEDnpwstKI3xTzVCr1zA5swTl1CI0G0bW
+ yJIIydQHmP2cRdeBAj5zPzTjnRhUDGF4ZJQJEPnYcyPdxLxALv+0cgyzcwuYX1zF1u4RI3kvnuG/iuM6
+ lJDugcvlRiGcTheKQd0nUKSyP9V/X3wBzfZGZumMH9MAAAAASUVORK5CYII=
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAVlJREFUOE9jYCAA
+ pt6c+p+QGpzySWdc/2ec8/jfd7WPdENAmjseJINx3kWf/10Xu4g3BKa5+kH6/4anOf+nvMv/n3PN/X/X
+ aSIMQdfcAtTc+b7k/8zPhRCX4DMEprn2YQbYZpjmjg9FYHbfu8z/IDVYDUHXDLIVhGGaa15l/C9/lvy/
+ 7lHE/5QTTqiGOO41+19zPfB/zf3g/233o8B+BmkE4aa3uf9BmkEaQfIFFzz/F553/++4wQi7S7z3uID9
+ C9Nc9SLtf96DKLAB7ltsCcdE2IEAsAEgmyuep4A1J98M+F92J+C/7xYn4gyY9iEL7N+c+5H/E2/4/w+7
+ 4Po//4YXcQYE7/T93/c6+X/WvfD/Cdf9wJp9T9uC0wFRLgAZ0PI0+n/cNR+4ZpINAIV2yHlnsM0wDHKB
+ z0ZHwmEAdsGDQLCTkXHtXV/iDEjemwT2KzoG2R6+KQzDBQBtp08dH0E7jQAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAY9JREFUOE+Vk8tL
+ AlEUxsdaBf01bdr0zhAjTAQVe5FNGJNWGvmojRFlVqBTUFCL+hPatQhcFPSiJLNEhVKJHhIi5r6+OBNj
+ ZpnTwF3cmfl933fOuVfGlDz2kB0P+VTh7TvzxlQx1cK+pqqW2W7YkZUy3/aGIy1WYjq4omrMx/uwnDSC
+ fzRhKzsGdUCOP2H6aDjUYu5Oj5GgDtbIAKYTJrgfzFhPc9IFvLf9BXjhxQpam6826QK+e1ZwJnA2Y4Yn
+ Y/ufAMUlmMCl3JSwNvITUO23SesBNYxgUWAxNwl/lpMmoAp0CnFFZyphJm2CJ22Ecq/xZ4LV2BraAvXC
+ 2JxRjTABiksCIjye6oEjoYHjuhPsqRzcWTtaduvgPnZ/CvoiPliuun44u56HQTAbV8MQVkB90YyhsBym
+ k9YvWDwY/hteECF3cnY+sbAkDTDGuqELdUB13lQeFkX4MA8uqIT3hcVoQo/BqEo6XCxCdVLNkp1Lzzcl
+ 6T1oBBdRVI5d7nLwl6uCyK8Nq3ijin4ojKoM9AHxq1tZT9V7JgAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAZJJREFUOE+Vk81L
+ AmEQxv2vvETWQepiHyBEGZqRkliblUmYGEQHs8yPQAMpLPSQdIq6RElBnjTJyENGdKgWywSrP2ByZnl1
+ pV22FoY97Pv8nmfmnVWpFJ5o8h6Uzsh+73XnQLdShOBO6f8QFE/uVYCL1Qiyvn37dwgTzwXewLFVA2fq
+ S4BEb5QhPZ4COaPY5HkAs/cRXNE6zB4KEH/4Wh6CzlzkA7i1FzAtlaHTloUue5ZAmGQm+Ql4RhLCnB1+
+ XhBPXIBtvwZTySpBDO4ywS277wQJBHOtJGpjBvSRMtWgrwTdlkyzDWxlPv1NEN1yEfr9d1TqgaN2CN6l
+ y5cHjfkMxg54wCQoxv7ZDBA8vXApPwN0sceFAWI5Q9UmACFcuk7pJBcHxVLOLAEOkWaQqlLKNggODMXW
+ BE+Dw8NMiG8SNxYKxcbEK1WH/rgFcW8UgJVm9JTuXOyMAASjaNF71axQOP+7nT7reRsAY9s2K3R92uET
+ 5U0UA8i5IR7HxYrzoB0SxZb7BRlALDasPsFI7FkS8AOfmJ+7r3cchAAAAABJRU5ErkJggg==
+
+
+
+
+ iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
+ YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAAbBJREFUOE9jZEAD
+ oYVH/osaajKwv/zFwMzCwsDEwszAwMzE8EuMieHKlpMMexa4MqLrQeGH5B36n7/s3f+S/tf/C6e8+182
+ 7QMYly77/N8lYfd/vJpBkiADCtZ8+l82GaEZZABIzCl2F3YD2qdd+g/DIEVgA6A2g2iQS7IWvf1vHb79
+ f1vXSTBuaj6GMMw2ftf/+GVP/6ctewPGZXM/wg3Im/TmPwinTnz+P37ms/+hU+/+D517D2wYinecM4F+
+ X/kexWaQ7SDNyZ1P/se1Pvwf1nD7f/j0B/9BFmINC5AhyM6HaU5of0RYM8jE2u6zYNNBhoA0p/U8+4+s
+ 2S5h1//84n2otk9aeOO/eeze/2F99/4HdV//79N44T9IISgsIvsf/I9svAv2O8hg14Kj/70azoKxmd8G
+ RED2z70K1giKa5C/E6tvgQ0BaYRp9k45ATYMZJFHzen/tXWH0Vwy6xKKIfGVN8EhDTKIoGZYiE4CGgIy
+ HeQSUBhElFz575dxGr/N6NEBMwSUcEDRB3I2KCywOhtXugYZ4l5yAux/kjXDvTP9PDjUSbIZm4tQ0jwW
+ BQBGf59N9yfyuQAAAABJRU5ErkJggg==
+
+
+
\ No newline at end of file
diff --git a/Duplicati/GUI/Wizard pages/Add backup/IncrementalSettings.cs b/Duplicati/GUI/Wizard pages/Add backup/IncrementalSettings.cs
index 9fbfac453..a29384b7a 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/IncrementalSettings.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/IncrementalSettings.cs
@@ -44,6 +44,13 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
base.PageEnter += new PageChangeHandler(IncrementalSettings_PageEnter);
base.PageLeave += new PageChangeHandler(IncrementalSettings_PageLeave);
+
+ List> ix = new List>();
+ ix.Add(new KeyValuePair("One day", "1D"));
+ ix.Add(new KeyValuePair("One week", "1W"));
+ ix.Add(new KeyValuePair("Two weeks", "2W"));
+ ix.Add(new KeyValuePair("One month", "1M"));
+ CleanupDuration.SetIntervals(ix);
}
void IncrementalSettings_PageLeave(object sender, PageChangedArgs args)
@@ -116,6 +123,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
if ((bool)m_settings["Advanced:Throttle"])
args.NextPage = new Wizard_pages.Add_backup.ThrottleOptions();
+ else if ((bool)m_settings["Advanced:Filters"])
+ args.NextPage = new Wizard_pages.Add_backup.FilterEditor();
else
args.NextPage = new Wizard_pages.Add_backup.FinishedAdd();
}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.Designer.cs b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.Designer.cs
index 09ea6ce85..46f0fd186 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.Designer.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.Designer.cs
@@ -28,6 +28,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
///
private void InitializeComponent()
{
+ this.components = new System.ComponentModel.Container();
this.label1 = new System.Windows.Forms.Label();
this.TargetFolder = new System.Windows.Forms.TextBox();
this.BrowseFolderButton = new System.Windows.Forms.Button();
@@ -35,14 +36,12 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.DocumentGroup = new System.Windows.Forms.GroupBox();
this.appdataSize = new System.Windows.Forms.Label();
this.desktopSize = new System.Windows.Forms.Label();
- this.myMoviesSize = new System.Windows.Forms.Label();
this.myMusicSize = new System.Windows.Forms.Label();
this.myPicturesSize = new System.Windows.Forms.Label();
this.myDocumentsSize = new System.Windows.Forms.Label();
this.IncludeDocuments = new System.Windows.Forms.CheckBox();
this.IncludeSettings = new System.Windows.Forms.CheckBox();
this.IncludeDesktop = new System.Windows.Forms.CheckBox();
- this.IncludeMovies = new System.Windows.Forms.CheckBox();
this.IncludeMusic = new System.Windows.Forms.CheckBox();
this.IncludeImages = new System.Windows.Forms.CheckBox();
this.DocumentsRadio = new System.Windows.Forms.RadioButton();
@@ -50,6 +49,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.customSize = new System.Windows.Forms.Label();
this.FolderRadio = new System.Windows.Forms.RadioButton();
this.totalSize = new System.Windows.Forms.Label();
+ this.FolderTooltip = new System.Windows.Forms.ToolTip(this.components);
this.DocumentGroup.SuspendLayout();
this.FolderGroup.SuspendLayout();
this.SuspendLayout();
@@ -65,9 +65,9 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
//
// TargetFolder
//
- this.TargetFolder.Location = new System.Drawing.Point(152, 24);
+ this.TargetFolder.Location = new System.Drawing.Point(192, 24);
this.TargetFolder.Name = "TargetFolder";
- this.TargetFolder.Size = new System.Drawing.Size(248, 20);
+ this.TargetFolder.Size = new System.Drawing.Size(208, 20);
this.TargetFolder.TabIndex = 1;
this.TargetFolder.Leave += new System.EventHandler(this.TargetFolder_Leave);
//
@@ -85,14 +85,12 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
//
this.DocumentGroup.Controls.Add(this.appdataSize);
this.DocumentGroup.Controls.Add(this.desktopSize);
- this.DocumentGroup.Controls.Add(this.myMoviesSize);
this.DocumentGroup.Controls.Add(this.myMusicSize);
this.DocumentGroup.Controls.Add(this.myPicturesSize);
this.DocumentGroup.Controls.Add(this.myDocumentsSize);
this.DocumentGroup.Controls.Add(this.IncludeDocuments);
this.DocumentGroup.Controls.Add(this.IncludeSettings);
this.DocumentGroup.Controls.Add(this.IncludeDesktop);
- this.DocumentGroup.Controls.Add(this.IncludeMovies);
this.DocumentGroup.Controls.Add(this.IncludeMusic);
this.DocumentGroup.Controls.Add(this.IncludeImages);
this.DocumentGroup.Location = new System.Drawing.Point(24, 8);
@@ -104,7 +102,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
// appdataSize
//
this.appdataSize.AutoSize = true;
- this.appdataSize.Location = new System.Drawing.Point(392, 72);
+ this.appdataSize.Location = new System.Drawing.Point(392, 48);
this.appdataSize.Name = "appdataSize";
this.appdataSize.Size = new System.Drawing.Size(22, 13);
this.appdataSize.TabIndex = 11;
@@ -113,21 +111,12 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
// desktopSize
//
this.desktopSize.AutoSize = true;
- this.desktopSize.Location = new System.Drawing.Point(392, 48);
+ this.desktopSize.Location = new System.Drawing.Point(392, 24);
this.desktopSize.Name = "desktopSize";
this.desktopSize.Size = new System.Drawing.Size(22, 13);
this.desktopSize.TabIndex = 10;
this.desktopSize.Text = "(...)";
//
- // myMoviesSize
- //
- this.myMoviesSize.AutoSize = true;
- this.myMoviesSize.Location = new System.Drawing.Point(392, 24);
- this.myMoviesSize.Name = "myMoviesSize";
- this.myMoviesSize.Size = new System.Drawing.Size(22, 13);
- this.myMoviesSize.TabIndex = 9;
- this.myMoviesSize.Text = "(...)";
- //
// myMusicSize
//
this.myMusicSize.AutoSize = true;
@@ -166,38 +155,31 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.IncludeDocuments.TabIndex = 5;
this.IncludeDocuments.Text = "Include documents";
this.IncludeDocuments.UseVisualStyleBackColor = true;
+ this.IncludeDocuments.CheckedChanged += new System.EventHandler(this.m_calculator_CompletedWork);
//
// IncludeSettings
//
this.IncludeSettings.AutoSize = true;
- this.IncludeSettings.Location = new System.Drawing.Point(224, 72);
+ this.IncludeSettings.Location = new System.Drawing.Point(224, 48);
this.IncludeSettings.Name = "IncludeSettings";
this.IncludeSettings.Size = new System.Drawing.Size(154, 17);
this.IncludeSettings.TabIndex = 4;
this.IncludeSettings.Text = "Include application settings";
this.IncludeSettings.UseVisualStyleBackColor = true;
+ this.IncludeSettings.CheckedChanged += new System.EventHandler(this.m_calculator_CompletedWork);
//
// IncludeDesktop
//
this.IncludeDesktop.AutoSize = true;
this.IncludeDesktop.Checked = true;
this.IncludeDesktop.CheckState = System.Windows.Forms.CheckState.Checked;
- this.IncludeDesktop.Location = new System.Drawing.Point(224, 48);
+ this.IncludeDesktop.Location = new System.Drawing.Point(224, 24);
this.IncludeDesktop.Name = "IncludeDesktop";
this.IncludeDesktop.Size = new System.Drawing.Size(156, 17);
this.IncludeDesktop.TabIndex = 3;
this.IncludeDesktop.Text = "Include files on the desktop";
this.IncludeDesktop.UseVisualStyleBackColor = true;
- //
- // IncludeMovies
- //
- this.IncludeMovies.AutoSize = true;
- this.IncludeMovies.Location = new System.Drawing.Point(224, 24);
- this.IncludeMovies.Name = "IncludeMovies";
- this.IncludeMovies.Size = new System.Drawing.Size(113, 17);
- this.IncludeMovies.TabIndex = 2;
- this.IncludeMovies.Text = "Include my movies";
- this.IncludeMovies.UseVisualStyleBackColor = true;
+ this.IncludeDesktop.CheckedChanged += new System.EventHandler(this.m_calculator_CompletedWork);
//
// IncludeMusic
//
@@ -208,6 +190,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.IncludeMusic.TabIndex = 1;
this.IncludeMusic.Text = "Include my music";
this.IncludeMusic.UseVisualStyleBackColor = true;
+ this.IncludeMusic.CheckedChanged += new System.EventHandler(this.m_calculator_CompletedWork);
//
// IncludeImages
//
@@ -220,6 +203,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
this.IncludeImages.TabIndex = 0;
this.IncludeImages.Text = "Include my images";
this.IncludeImages.UseVisualStyleBackColor = true;
+ this.IncludeImages.CheckedChanged += new System.EventHandler(this.m_calculator_CompletedWork);
//
// DocumentsRadio
//
@@ -309,19 +293,18 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
private System.Windows.Forms.RadioButton DocumentsRadio;
private System.Windows.Forms.Label appdataSize;
private System.Windows.Forms.Label desktopSize;
- private System.Windows.Forms.Label myMoviesSize;
private System.Windows.Forms.Label myMusicSize;
private System.Windows.Forms.Label myPicturesSize;
private System.Windows.Forms.Label myDocumentsSize;
private System.Windows.Forms.CheckBox IncludeDocuments;
private System.Windows.Forms.CheckBox IncludeSettings;
private System.Windows.Forms.CheckBox IncludeDesktop;
- private System.Windows.Forms.CheckBox IncludeMovies;
private System.Windows.Forms.CheckBox IncludeMusic;
private System.Windows.Forms.CheckBox IncludeImages;
private System.Windows.Forms.GroupBox FolderGroup;
private System.Windows.Forms.Label customSize;
private System.Windows.Forms.RadioButton FolderRadio;
private System.Windows.Forms.Label totalSize;
+ private System.Windows.Forms.ToolTip FolderTooltip;
}
}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.cs b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.cs
index 98b6a5de2..19c4d0811 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.cs
@@ -42,17 +42,33 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
private string m_appData;
private string m_myDocuments;
+ private string[] m_specialFolders;
+
public SelectFiles()
: base("Select files to backup", "On this page you must select the folder and files you wish to backup")
{
InitializeComponent();
m_sizes = new Dictionary();
- m_myPictures = System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures);
- m_myMusic = System.Environment.GetFolderPath(Environment.SpecialFolder.MyMusic);
- m_desktop = System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
- m_appData = System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
- m_myDocuments = System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
+ m_myPictures = Library.Core.Utility.AppendDirSeperator("!" + System.Environment.GetFolderPath(Environment.SpecialFolder.MyPictures));
+ m_myMusic = Library.Core.Utility.AppendDirSeperator("!" + System.Environment.GetFolderPath(Environment.SpecialFolder.MyMusic));
+ m_desktop = Library.Core.Utility.AppendDirSeperator("!" + System.Environment.GetFolderPath(Environment.SpecialFolder.Desktop));
+ m_appData = Library.Core.Utility.AppendDirSeperator("!" + System.Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData));
+ m_myDocuments = Library.Core.Utility.AppendDirSeperator("!" + System.Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments));
+
+ FolderTooltip.SetToolTip(IncludeDocuments, m_myDocuments.Substring(1));
+ FolderTooltip.SetToolTip(IncludeMusic, m_myMusic.Substring(1));
+ FolderTooltip.SetToolTip(IncludeImages, m_myPictures.Substring(1));
+ FolderTooltip.SetToolTip(IncludeDesktop, m_desktop.Substring(1));
+ FolderTooltip.SetToolTip(IncludeSettings, m_appData.Substring(1));
+
+ m_specialFolders = new string[] {
+ m_myDocuments.Substring(1),
+ m_myMusic.Substring(1),
+ m_myPictures.Substring(1),
+ m_appData.Substring(1),
+ m_desktop.Substring(1)
+ };
base.PageEnter += new PageChangeHandler(SelectFiles_PageEnter);
base.PageLeave += new PageChangeHandler(SelectFiles_PageLeave);
@@ -60,14 +76,119 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
void SelectFiles_PageLeave(object sender, PageChangedArgs args)
{
+ m_settings["Files:Sizes"] = m_sizes;
+
if (args.Direction == PageChangedDirection.Back)
return;
if (DocumentsRadio.Checked)
{
- MessageBox.Show(this, "This feature is not ready. Please manually point out the folder to back up.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
- args.Cancel = true;
- return;
+ List folders = new List();
+ List exfolders = new List();
+ if (IncludeDocuments.Checked)
+ folders.Add(m_myDocuments.Substring(1));
+ else
+ exfolders.Add(m_myDocuments.Substring(1));
+
+ if (IncludeImages.Checked)
+ folders.Add(m_myPictures.Substring(1));
+ else
+ exfolders.Add(m_myPictures.Substring(1));
+
+ if (IncludeMusic.Checked)
+ folders.Add(m_myMusic.Substring(1));
+ else
+ exfolders.Add(m_myMusic.Substring(1));
+
+ if (IncludeDesktop.Checked)
+ folders.Add(m_desktop.Substring(1));
+ else
+ exfolders.Add(m_desktop.Substring(1));
+
+ if (IncludeSettings.Checked)
+ folders.Add(m_appData.Substring(1));
+ else
+ exfolders.Add(m_appData.Substring(1));
+
+ if (folders.Count == 0)
+ {
+ MessageBox.Show(this, "You have not included any files.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ args.Cancel = true;
+ return;
+ }
+
+ //Find the most common root
+ string basefolder = folders[0];
+ bool hasCommonParent = false;
+
+ foreach (string f in folders)
+ if (basefolder.StartsWith(f))
+ basefolder = f;
+ else if (!f.StartsWith(basefolder))
+ {
+ string[] p1 = basefolder.Split(System.IO.Path.DirectorySeparatorChar);
+ string[] p2 = f.Split(System.IO.Path.DirectorySeparatorChar);
+
+ int ix = 0;
+ while (p1.Length > ix && p2.Length > ix && p1[ix] == p2[ix])
+ ix++;
+
+ if (ix == 0)
+ {
+ MessageBox.Show(this, "Due to your machine setup, it is not possible to backup\nthe selected folders in the same backup.\nTry unchecking some items, and create more than one backup.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
+ args.Cancel = true;
+ return;
+ }
+
+ hasCommonParent = true;
+ basefolder = Library.Core.Utility.AppendDirSeperator(string.Join(System.IO.Path.DirectorySeparatorChar.ToString(), p1, 0, ix));
+ }
+
+ m_schedule.Tasks[0].SourcePath = basefolder;
+
+ List filters = new List();
+
+ //Exclude everything if they have a non-included parent
+ if (hasCommonParent)
+ {
+ TaskFilter tf = m_schedule.DataParent.Add();
+ tf.Include = false;
+ tf.Filter = Library.Core.FilenameFilter.ConvertGlobbingToRegExp(basefolder + "*");
+ filters.Add(tf);
+ }
+
+ //Include selected folders
+ foreach (string f in folders)
+ {
+ TaskFilter tfx = m_schedule.DataParent.Add();
+ tfx.Include = true;
+ tfx.Filter = Library.Core.FilenameFilter.ConvertGlobbingToRegExp(f + "*");
+ filters.Add(tfx);
+
+ //Exclude subfolders
+ foreach (string s in exfolders)
+ if (s.StartsWith(f) && (basefolder == s || s.StartsWith(basefolder)))
+ {
+ TaskFilter tfp = m_schedule.DataParent.Add();
+ tfp.Include = false;
+ tfp.Filter = Library.Core.FilenameFilter.ConvertGlobbingToRegExp(s + "*");
+ filters.Add(tfp);
+ }
+ }
+
+ List extras = new List();
+ string key = Library.Core.FilenameFilter.ConvertGlobbingToRegExp(basefolder);
+ foreach(TaskFilter tf in m_schedule.Tasks[0].Filters)
+ if (!tf.Filter.StartsWith(key))
+ extras.Add(tf);
+
+ if (filters.Count < 2)
+ m_schedule.Tasks[0].SortedFilters = extras.ToArray();
+ else
+ {
+ filters.AddRange(extras);
+ m_schedule.Tasks[0].SortedFilters = filters.ToArray();
+ }
}
else
{
@@ -77,13 +198,13 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
args.Cancel = true;
return;
}
+
+ m_schedule.Tasks[0].SourcePath = TargetFolder.Text;
}
if (m_calculator != null)
m_calculator.ClearQueue(true);
- m_schedule.Path = m_schedule.Tasks[0].SourcePath;
-
args.NextPage = new SelectBackend();
}
@@ -91,10 +212,46 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
{
m_schedule = (Schedule)m_settings["Schedule"];
+ if (m_settings.ContainsKey("Files:Sizes"))
+ m_sizes = (Dictionary)m_settings["Files:Sizes"];
+
+
if (!m_valuesAutoLoaded)
{
- FolderRadio.Checked = true;
- TargetFolder.Text = m_schedule.Path;
+ List filters = new List();
+ foreach (TaskFilter tf in m_schedule.Tasks[0].Filters)
+ if (tf.Include && tf.Filter.StartsWith(Library.Core.FilenameFilter.ConvertGlobbingToRegExp(m_schedule.Tasks[0].SourcePath)))
+ filters.Add(tf.Filter);
+
+ if (filters.Count == 0)
+ TargetFolder.Text = m_schedule.Path;
+
+ List included = new List();
+ foreach (string s in m_specialFolders)
+ if (filters.Contains(Library.Core.FilenameFilter.ConvertGlobbingToRegExp(s + "*")))
+ included.Add(s);
+
+ if (included.Count == 0)
+ {
+ FolderRadio.Checked = true;
+ TargetFolder.Text = m_schedule.Path;
+ }
+ else
+ {
+ DocumentsRadio.Checked = true;
+ IncludeDocuments.Checked = included.Contains(m_myDocuments.Substring(1));
+ IncludeImages.Checked = included.Contains(m_myPictures.Substring(1));
+ IncludeMusic.Checked = included.Contains(m_myMusic.Substring(1));
+ IncludeDesktop.Checked = included.Contains(m_desktop.Substring(1));
+ IncludeSettings.Checked = included.Contains(m_appData.Substring(1));
+
+ if (!(IncludeDocuments.Checked || IncludeMusic.Checked || IncludeImages.Checked || IncludeDesktop.Checked || IncludeSettings.Checked))
+ {
+ FolderRadio.Checked = true;
+ TargetFolder.Text = m_schedule.Path;
+ }
+ }
+
}
if (FolderRadio.Checked)
@@ -107,6 +264,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
{
if (m_calculator == null)
{
+ totalSize.Text = "Calculating size ...";
m_calculator = new WorkerThread(CalculateFolderSize);
m_calculator.CompletedWork += new EventHandler(m_calculator_CompletedWork);
}
@@ -114,19 +272,36 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
void m_calculator_CompletedWork(object sender, EventArgs e)
{
+
if (this.InvokeRequired)
this.Invoke(new EventHandler(m_calculator_CompletedWork), sender, e);
else
{
+ if (m_calculator == null)
+ return;
+
long s = 0;
if (DocumentsRadio.Checked)
- foreach (long l in m_sizes.Values)
- s += l;
+ {
+ if (m_sizes.ContainsKey(m_myDocuments) && IncludeDocuments.Checked)
+ s += m_sizes[m_myDocuments];
+ if (m_sizes.ContainsKey(m_myMusic) && IncludeMusic.Checked)
+ s += m_sizes[m_myMusic];
+ if (m_sizes.ContainsKey(m_myPictures) && IncludeImages.Checked)
+ s += m_sizes[m_myPictures];
+ if (m_sizes.ContainsKey(m_appData) && IncludeSettings.Checked)
+ s += m_sizes[m_appData];
+ if (m_sizes.ContainsKey(m_desktop) && IncludeDesktop.Checked)
+ s += m_sizes[m_desktop];
+ }
else
s = m_sizes.ContainsKey(TargetFolder.Text) ? m_sizes[TargetFolder.Text] : 0;
-
- totalSize.Text = string.Format("The selected items take up {0} of space", Library.Core.Utility.FormatSizeString(s));
+
+ if (m_calculator.CurrentTasks.Count == 0 && !m_calculator.Active)
+ totalSize.Text = string.Format("The selected items take up {0} of space", Library.Core.Utility.FormatSizeString(s));
+ else
+ totalSize.Text = string.Format("Calculating ... (using more than {0} of space)", Library.Core.Utility.FormatSizeString(s));
if (m_sizes.ContainsKey(m_myMusic))
myMusicSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[m_myMusic]);
@@ -136,10 +311,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
desktopSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[m_desktop]);
if (m_sizes.ContainsKey(m_appData))
appdataSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[m_appData]);
-
- //TODO: Do not count myMusic and myPictures, if they are inside myDocuments
if (m_sizes.ContainsKey(m_myDocuments))
- myMusicSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[m_myDocuments]);
+ myDocumentsSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[m_myDocuments]);
if (m_sizes.ContainsKey(TargetFolder.Text))
customSize.Text = Library.Core.Utility.FormatSizeString(m_sizes[TargetFolder.Text]);
@@ -161,6 +334,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
m_calculator.AddTask(m_appData);
if (!m_sizes.ContainsKey(m_myDocuments))
m_calculator.AddTask(m_myDocuments);
+
+ m_calculator_CompletedWork(null, null);
}
}
@@ -179,6 +354,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
FolderGroup.Enabled = FolderRadio.Checked;
if (DocumentsRadio.Checked)
Rescan();
+ else
+ TargetFolder_Leave(sender, e);
}
private void CalculateFolderSize(string folder)
@@ -188,46 +365,60 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
return;
long size = 0;
+
+ Library.Core.FilenameFilter fnf = null;
+ string folderkey = folder;
+
+ //Special folders, extended logic
+ if (folder.StartsWith("!"))
+ {
+ folder = folder.Substring(1);
+ List> filters = new List>();
+
+ filters.Add(new KeyValuePair(true, Library.Core.FilenameFilter.ConvertGlobbingToRegExp(folder + "*")));
+
+ foreach (string s in m_specialFolders)
+ if (s != folder && s.StartsWith(folder))
+ filters.Add(new KeyValuePair(false, Library.Core.FilenameFilter.ConvertGlobbingToRegExp(s + "*")));
+
+
+ if (filters.Count > 1)
+ fnf = new Duplicati.Library.Core.FilenameFilter(filters);
+ }
+
if (System.IO.Directory.Exists(folder))
{
- Queue work = new Queue();
- work.Enqueue(folder);
try
{
- while(work.Count > 0)
- try
- {
- string f = work.Dequeue();
- foreach (string s in System.IO.Directory.GetDirectories(f))
- work.Enqueue(s);
- foreach (string s in System.IO.Directory.GetFiles(f))
- try { size += new System.IO.FileInfo(s).Length; }
- catch { }
- }
- catch
- {
- }
- }
- catch
- {
+ foreach (string file in Duplicati.Library.Core.Utility.EnumerateFiles(folder, fnf))
+ try { size += new System.IO.FileInfo(file).Length; }
+ catch { }
}
+ catch { }
}
lock (m_lock)
- m_sizes[folder] = size;
+ m_sizes[folderkey] = size;
}
private void TargetFolder_Leave(object sender, EventArgs e)
{
- lock(m_lock)
+ lock (m_lock)
if (TargetFolder.Text.Trim().Length > 0 && !m_sizes.ContainsKey(TargetFolder.Text))
{
StartCalculator();
m_calculator.ClearQueue(true);
m_calculator.AddTask(TargetFolder.Text);
+ m_calculator_CompletedWork(null, null);
+ }
+ else if (TargetFolder.Text == "")
+ totalSize.Text = "";
+ else if (m_sizes.ContainsKey(TargetFolder.Text))
+ {
+ StartCalculator();
+ m_calculator.ClearQueue(true);
+ m_calculator_CompletedWork(null, null);
}
-
- m_schedule.Tasks[0].SourcePath = TargetFolder.Text;
}
private void SelectFiles_VisibleChanged(object sender, EventArgs e)
diff --git a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.resx b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.resx
index 89c3d872b..6279282b3 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.resx
+++ b/Duplicati/GUI/Wizard pages/Add backup/SelectFiles.resx
@@ -120,4 +120,7 @@
17, 17
+
+ 168, 17
+
\ No newline at end of file
diff --git a/Duplicati/GUI/Wizard pages/Add backup/SelectName.cs b/Duplicati/GUI/Wizard pages/Add backup/SelectName.cs
index cb46def85..eccbe9561 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/SelectName.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/SelectName.cs
@@ -95,6 +95,9 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
if (m_schedule != null && m_schedule.ExistsInDb)
BackupName.Text = m_schedule.Name;
+
+ try { BackupName.Focus(); }
+ catch { }
}
private void button1_Click(object sender, EventArgs e)
diff --git a/Duplicati/GUI/Wizard pages/Add backup/SelectWhen.cs b/Duplicati/GUI/Wizard pages/Add backup/SelectWhen.cs
index d3cae0f97..9f5042b4f 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/SelectWhen.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/SelectWhen.cs
@@ -103,6 +103,8 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
args.NextPage = new Wizard_pages.Add_backup.IncrementalSettings();
else if ((bool)m_settings["Advanced:Throttle"])
args.NextPage = new Wizard_pages.Add_backup.ThrottleOptions();
+ else if ((bool)m_settings["Advanced:Filters"])
+ args.NextPage = new Wizard_pages.Add_backup.FilterEditor();
else
args.NextPage = new Wizard_pages.Add_backup.FinishedAdd();
}
diff --git a/Duplicati/GUI/Wizard pages/Add backup/ThrottleOptions.cs b/Duplicati/GUI/Wizard pages/Add backup/ThrottleOptions.cs
index 865c393a9..324a17f8d 100644
--- a/Duplicati/GUI/Wizard pages/Add backup/ThrottleOptions.cs
+++ b/Duplicati/GUI/Wizard pages/Add backup/ThrottleOptions.cs
@@ -42,7 +42,7 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
if (size != 0)
{
for (int i = 0; i < combo.Items.Count; i++)
- if (size < Math.Pow(2, 10 * i + 1))
+ if (size < Math.Pow(2, 10 * (i + 1)))
{
combo.SelectedIndex = i;
number.Value = (int)(size / (long)Math.Pow(2, 10 * i));
@@ -94,7 +94,10 @@ namespace Duplicati.GUI.Wizard_pages.Add_backup
m_schedule.VolumeSize = VolumeSizeLimitNumber.Value.ToString() + VolumeSizeLimitSuffix.Text;
- args.NextPage = new FinishedAdd();
+ if ((bool)m_settings["Advanced:Filters"])
+ args.NextPage = new Wizard_pages.Add_backup.FilterEditor();
+ else
+ args.NextPage = new FinishedAdd();
}
diff --git a/Duplicati/GUI/Wizard pages/MainPage.cs b/Duplicati/GUI/Wizard pages/MainPage.cs
index b35238ddc..6063fdfbd 100644
--- a/Duplicati/GUI/Wizard pages/MainPage.cs
+++ b/Duplicati/GUI/Wizard pages/MainPage.cs
@@ -30,17 +30,6 @@ namespace Duplicati.GUI.Wizard_pages
{
public partial class MainPage : WizardControl
{
- public enum Action
- {
- Unknown,
- Add,
- Edit,
- Delete,
- Restore,
- Backup,
- Rearrange
- }
-
public MainPage()
: base("Welcome to the Duplicati Wizard", "Please select the action you want to perform below")
{
@@ -109,26 +98,6 @@ namespace Duplicati.GUI.Wizard_pages
UpdateButtonState();
}
- public Action SelectedAction
- {
- get
- {
- if (CreateNew.Checked)
- return Action.Add;
- else if (Edit.Checked)
- return Action.Edit;
- else if (Restore.Checked)
- return Action.Restore;
- else if (Backup.Checked)
- return Action.Backup;
- else if (Remove.Checked)
- return Action.Delete;
- else
- return Action.Unknown;
-
- }
- }
-
private void ShowAdvanced_Click(object sender, EventArgs e)
{
Program.ShowSetup();
diff --git a/Duplicati/GUI/Wizard pages/SelectBackend.cs b/Duplicati/GUI/Wizard pages/SelectBackend.cs
index 79c28af99..f5dc95adc 100644
--- a/Duplicati/GUI/Wizard pages/SelectBackend.cs
+++ b/Duplicati/GUI/Wizard pages/SelectBackend.cs
@@ -104,8 +104,32 @@ namespace Duplicati.GUI.Wizard_pages
void SelectBackend_PageEnter(object sender, PageChangedArgs args)
{
m_task = ((Schedule)m_settings["Schedule"]).Tasks[0];
+
+ if (!m_valuesAutoLoaded)
+ {
+ switch (m_task.Service)
+ {
+ case "file":
+ File.Checked = true;
+ break;
+ case "ftp":
+ FTP.Checked = true;
+ break;
+ case "ssh":
+ SSH.Checked = true;
+ break;
+ case "webdav":
+ WebDAV.Checked = true;
+ break;
+ case "s3":
+ S3.Checked = true;
+ break;
+ }
+ }
+
Item_CheckChanged(null, null);
+
}
private void Item_CheckChanged(object sender, EventArgs e)
diff --git a/Duplicati/GUI/Wizard pages/SelectBackup.cs b/Duplicati/GUI/Wizard pages/SelectBackup.cs
index 628996480..059dbe60f 100644
--- a/Duplicati/GUI/Wizard pages/SelectBackup.cs
+++ b/Duplicati/GUI/Wizard pages/SelectBackup.cs
@@ -32,8 +32,6 @@ namespace Duplicati.GUI.Wizard_pages
{
public partial class SelectBackup : WizardControl
{
- private MainPage.Action m_selectType;
-
public SelectBackup()
: base ("", "")
{
@@ -41,31 +39,45 @@ namespace Duplicati.GUI.Wizard_pages
BackupList.treeView.HideSelection = false;
base.PageLeave += new PageChangeHandler(SelectBackup_PageLeave);
+ base.PageEnter += new PageChangeHandler(SelectBackup_PageEnter);
+ }
+
+ void SelectBackup_PageEnter(object sender, PageChangedArgs args)
+ {
+ BackupList.Setup((IDataFetcher)m_settings["Connection"], false, false);
+ if (m_settings.ContainsKey("Schedule"))
+ BackupList.SelectedBackup = (Schedule)m_settings["Schedule"];
}
void SelectBackup_PageLeave(object sender, PageChangedArgs args)
{
+ if (args.Direction == PageChangedDirection.Back)
+ return;
+
if (BackupList.SelectedBackup == null)
{
MessageBox.Show(this, "You must select a backup before you can continue", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Information);
args.Cancel = true;
return;
}
+
+ m_settings["Schedule"] = BackupList.SelectedBackup;
+ args.NextPage = new Add_backup.SelectName();
}
public override string Title
{
get
{
- switch (m_selectType)
+ switch ((string)m_settings["Main:Action"])
{
- case MainPage.Action.Backup:
+ case "backup":
return "Select the backup to run now";
- case MainPage.Action.Delete:
+ case "delete":
return "Select the backup to remove";
- case MainPage.Action.Edit:
+ case "edit":
return "Select the backup to modify";
- case MainPage.Action.Restore:
+ case "restore":
return "Select the backup to restore";
default:
return "Unknown action";
@@ -78,34 +90,20 @@ namespace Duplicati.GUI.Wizard_pages
{
get
{
- switch (m_selectType)
+ switch ((string)m_settings["Main:Action"])
{
- case MainPage.Action.Backup:
+ case "backup":
return "In the list below, select the backup you want to run immediately";
- case MainPage.Action.Delete:
+ case "delete":
return "In the list below, select the backup you want to delete";
- case MainPage.Action.Edit:
+ case "edit":
return "In the list below, select the backup you want to modify";
- case MainPage.Action.Restore:
+ case "restore":
return "In the list below, select the backup you want to restore";
default:
return "Unknown action";
}
}
}
-
- public void Setup(IDataFetcher connection, MainPage.Action selectType)
- {
- m_selectType = selectType;
- BackupList.Setup(connection, false, false);
- }
-
- public MainPage.Action SelectType
- {
- get { return m_selectType; }
- set { m_selectType = value; }
- }
-
- public Schedule SelectedBackup { get { return BackupList.SelectedBackup; } }
}
}
diff --git a/Duplicati/GUI/WizardHandler.cs b/Duplicati/GUI/WizardHandler.cs
index 41ddf4692..984c45bdb 100644
--- a/Duplicati/GUI/WizardHandler.cs
+++ b/Duplicati/GUI/WizardHandler.cs
@@ -100,9 +100,8 @@ namespace Duplicati.GUI
if (m_form.CurrentPage is Wizard_pages.Add_backup.FinishedAdd)
{
- //TODO: Implement CommitRecursive
- m_connection.CommitAll();
- Program.DataConnection.CommitAll();
+ Schedule schedule = (Schedule)m_form.Settings["Schedule"];
+ ((IDataFetcherCached)schedule.DataParent).CommitRecursiveWithRelations(schedule);
if ((m_form.CurrentPage as Duplicati.GUI.Wizard_pages.Add_backup.FinishedAdd).RunNow.Checked)
if (m_addedItem != null)
diff --git a/Duplicati/GUI/WorkerThread.cs b/Duplicati/GUI/WorkerThread.cs
index 513d266a6..f4d4d661e 100644
--- a/Duplicati/GUI/WorkerThread.cs
+++ b/Duplicati/GUI/WorkerThread.cs
@@ -32,6 +32,8 @@ namespace Duplicati.GUI
private volatile bool m_terminate;
private Thread m_thread;
+ private volatile bool m_active;
+
private Tx m_currentTask;
private ProcessItemDelegate m_delegate;
@@ -65,6 +67,14 @@ namespace Duplicati.GUI
}
+ ///
+ /// Gets a value indicating if the worker is running
+ ///
+ public bool Active
+ {
+ get { return m_active; }
+ }
+
///
/// Adds a task to the queue
///
@@ -161,7 +171,9 @@ namespace Duplicati.GUI
if (StartingWork != null)
StartingWork(this, null);
+ m_active = true;
m_delegate(m_currentTask);
+ m_active = false;
if (CompletedWork != null)
CompletedWork(this, null);
diff --git a/Duplicati/Library/Core/FilenameFilter.cs b/Duplicati/Library/Core/FilenameFilter.cs
index 040e9ced2..a55c4f588 100644
--- a/Duplicati/Library/Core/FilenameFilter.cs
+++ b/Duplicati/Library/Core/FilenameFilter.cs
@@ -148,7 +148,7 @@ namespace Duplicati.Library.Core
///
///
///
- private static string ConvertGlobbingToRegExp(string globexp)
+ public static string ConvertGlobbingToRegExp(string globexp)
{
//First escape all special characters
globexp = Regex.Replace(globexp, BADCHARS, "\\$&");
diff --git a/WizardForm/Dialog.Designer.cs b/WizardForm/Dialog.Designer.cs
index 40c6bc40f..f2b1aa97f 100644
--- a/WizardForm/Dialog.Designer.cs
+++ b/WizardForm/Dialog.Designer.cs
@@ -132,6 +132,7 @@ namespace System.Windows.Forms.Wizard
//
// Dialog
//
+ this.AcceptButton = this._NextButton;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this._CancelButton;
diff --git a/WizardForm/Dialog.cs b/WizardForm/Dialog.cs
index ae0ea3b5c..0514d8765 100644
--- a/WizardForm/Dialog.cs
+++ b/WizardForm/Dialog.cs
@@ -34,6 +34,10 @@ namespace System.Windows.Forms.Wizard
private string m_title;
private IWizardControl m_currentPage;
private bool m_isLastPage = false;
+ private Dictionary m_settings;
+
+ //The path the user has chosen
+ private Stack m_visited;
public event CancelEventHandler Finished;
public event CancelEventHandler Cancelled;
@@ -64,6 +68,8 @@ namespace System.Windows.Forms.Wizard
InitializeComponent();
m_pages = new List();
m_defaultImage = null;
+ m_settings = new Dictionary();
+ m_visited = new Stack();
}
public virtual string Title
@@ -83,6 +89,8 @@ namespace System.Windows.Forms.Wizard
get { return m_pages; }
}
+ public virtual Dictionary Settings { get { return m_settings; } }
+
public virtual IWizardControl CurrentPage
{
get { return m_currentPage; }
@@ -95,15 +103,15 @@ namespace System.Windows.Forms.Wizard
public virtual void UpdateButtons()
{
- if (Pages.Count == 0)
+ /*if (Pages.Count == 0)
{
_NextButton.Enabled = false;
_BackButton.Enabled = false;
return;
- }
+ }*/
_NextButton.Enabled = true;
- _BackButton.Enabled = m_currentPage != Pages[0];
+ _BackButton.Enabled = m_visited.Count > 0;
if (m_isLastPage)
_NextButton.Text = "Finish";
@@ -113,12 +121,18 @@ namespace System.Windows.Forms.Wizard
public virtual void UpdateDisplay()
{
- UpdateButtons();
DisplayPage(CurrentPage);
+ UpdateButtons();
}
protected virtual void DisplayPage(IWizardControl page)
{
+ PageChangedArgs args = new PageChangedArgs(this, this.Pages.IndexOf(page) == this.Pages.Count - 1, PageChangedDirection.Next);
+
+ page.Enter(this, args);
+ if (page.Control as IControl != null)
+ (page.Control as IControl).Displayed(this);
+
InfoPanel.Visible = !page.FullSize;
TitleLabel.Text = page.Title;
InfoLabel.Text = page.HelpText;
@@ -126,24 +140,21 @@ namespace System.Windows.Forms.Wizard
ContentPanel.Controls.Clear();
ContentPanel.Controls.Add(page.Control);
page.Control.Dock = DockStyle.Fill;
- UpdateButtons();
+ m_isLastPage = args.TreatAsLast;
- page.Enter(this);
- if (page.Control as IControl != null)
- (page.Control as IControl).Displayed(this);
+ UpdateButtons();
}
private void BackBtn_Click(object sender, EventArgs e)
{
- PageChangedArgs args = new PageChangedArgs();
- args.Cancel = false;
- args.NextPage = null;
- int pos = Pages.IndexOf(CurrentPage);
- if (pos > 0)
- args.NextPage = Pages[pos - 1];
- args.TreatAsLast = false;
- args.Direction = PageChangedDirection.Back;
+ PageChangedArgs args = new PageChangedArgs(this, false, PageChangedDirection.Back);
+ if (m_visited.Count > 0)
+ args.NextPage = m_visited.Pop();
+
+ if (this.CurrentPage != null)
+ this.CurrentPage.Leave(this, args);
+
if (BackPressed != null)
BackPressed(this, args);
@@ -156,11 +167,18 @@ namespace System.Windows.Forms.Wizard
private void NextBtn_Click(object sender, EventArgs e)
{
+ IWizardControl nextpage = null;
+ int pos = Pages.IndexOf(CurrentPage);
+ if (pos >= 0 && pos < Pages.Count - 1)
+ nextpage = Pages[pos + 1];
+
+ PageChangedArgs args = new PageChangedArgs(this, Pages.IndexOf(nextpage) == Pages.Count - 1 && Pages.Count != 0, PageChangedDirection.Next);
+ args.NextPage = nextpage;
+
if (m_currentPage != null)
{
- bool cancel = false;
- m_currentPage.Leave(this, ref cancel);
- if (cancel)
+ m_currentPage.Leave(this, args);
+ if (args.Cancel)
return;
}
@@ -180,23 +198,16 @@ namespace System.Windows.Forms.Wizard
return;
}
- PageChangedArgs args = new PageChangedArgs();
- args.Cancel = false;
- args.Direction = PageChangedDirection.Next;
- args.NextPage = null;
-
- int pos = Pages.IndexOf(CurrentPage);
- if (pos >= 0)
- args.NextPage = Pages[pos + 1];
- args.TreatAsLast = Pages.IndexOf(args.NextPage) == Pages.Count - 1;
-
if (NextPressed != null)
NextPressed(this, args);
if (args.Cancel || args.NextPage == null)
return;
+ if (CurrentPage != null)
+ m_visited.Push(CurrentPage);
m_isLastPage = args.TreatAsLast;
CurrentPage = args.NextPage;
+ UpdateButtons();
}
private void CancelBtn_Click(object sender, EventArgs e)
@@ -212,7 +223,6 @@ namespace System.Windows.Forms.Wizard
this.Close();
}
-
#region IWizardForm Members
public Button NextButton
diff --git a/WizardForm/IWizardControl.cs b/WizardForm/IWizardControl.cs
index 729a713df..662f0f60b 100644
--- a/WizardForm/IWizardControl.cs
+++ b/WizardForm/IWizardControl.cs
@@ -31,7 +31,7 @@ namespace System.Windows.Forms.Wizard
string HelpText { get; }
Image Image { get; }
bool FullSize { get; }
- void Enter(IWizardForm owner);
- void Leave(IWizardForm owner, ref bool cancel);
+ void Enter(IWizardForm owner, PageChangedArgs args);
+ void Leave(IWizardForm owner, PageChangedArgs args);
}
}
diff --git a/WizardForm/IWizardForm.cs b/WizardForm/IWizardForm.cs
index add714d2e..1d230bcd9 100644
--- a/WizardForm/IWizardForm.cs
+++ b/WizardForm/IWizardForm.cs
@@ -33,9 +33,20 @@ namespace System.Windows.Forms.Wizard
public class PageChangedArgs : CancelEventArgs
{
+ public PageChangedArgs(IWizardForm owner, bool treatAsLast, PageChangedDirection direction)
+ : base()
+ {
+ this.Owner = owner;
+ this.Settings = owner.Settings;
+ this.Direction = direction;
+ this.TreatAsLast = treatAsLast;
+ }
+
public IWizardControl NextPage;
public bool TreatAsLast;
public PageChangedDirection Direction;
+ public Dictionary Settings;
+ public IWizardForm Owner;
}
@@ -59,6 +70,7 @@ namespace System.Windows.Forms.Wizard
Image DefaultImage { get; set; }
void UpdateButtons();
void UpdateDisplay();
+ Dictionary Settings { get; }
event PageChangeHandler NextPressed;
event PageChangeHandler BackPressed;
diff --git a/WizardForm/StartPage.cs b/WizardForm/StartPage.cs
index 58df16951..598dd8307 100644
--- a/WizardForm/StartPage.cs
+++ b/WizardForm/StartPage.cs
@@ -68,12 +68,12 @@ namespace System.Windows.Forms.Wizard
get { return true; }
}
- void IWizardControl.Enter(IWizardForm owner)
+ void IWizardControl.Enter(IWizardForm owner, PageChangedArgs args)
{
}
- void IWizardControl.Leave(IWizardForm owner, ref bool cancel)
+ void IWizardControl.Leave(IWizardForm owner, PageChangedArgs args)
{
}
diff --git a/WizardForm/WizardControl.Designer.cs b/WizardForm/WizardControl.Designer.cs
new file mode 100644
index 000000000..e69de29bb
diff --git a/WizardForm/WizardControl.cs b/WizardForm/WizardControl.cs
index accf825a9..8284eed7d 100644
--- a/WizardForm/WizardControl.cs
+++ b/WizardForm/WizardControl.cs
@@ -24,27 +24,39 @@ using System.Drawing;
namespace System.Windows.Forms.Wizard
{
- public class WizardControl : IWizardControl
+ public class WizardControl : UserControl, IWizardControl
{
- private Control m_control;
- private string m_title;
- private string m_helpText;
- private Image m_image;
- private bool m_fullSize;
+ protected string m_title;
+ protected string m_helpText;
+ protected Image m_image;
+ protected bool m_fullSize;
- public WizardControl(Control control, string title, string helptext)
- : this(control, title, helptext, null)
+ protected bool m_autoFillValues = true;
+ protected bool m_valuesAutoLoaded = false;
+
+ protected IWizardForm m_owner;
+ protected Dictionary m_settings;
+
+ protected event PageChangeHandler PageEnter;
+ protected event PageChangeHandler PageLeave;
+
+ //Windows forms designer support
+ private WizardControl()
{
}
- public WizardControl(Control control, string title, string helptext, Image image)
- : this(control, title, helptext, image, false)
+ public WizardControl(string title, string helptext)
+ : this(title, helptext, null)
{
}
- public WizardControl(Control control, string title, string helptext, Image image, bool fullsize)
+ public WizardControl(string title, string helptext, Image image)
+ : this(title, helptext, image, false)
+ {
+ }
+
+ public WizardControl(string title, string helptext, Image image, bool fullsize)
{
- m_control = control;
m_title = title;
m_helpText = helptext;
m_image = image;
@@ -53,39 +65,175 @@ namespace System.Windows.Forms.Wizard
#region IWizardControl Members
- Control IWizardControl.Control
+ public virtual Control Control
{
- get { return m_control; }
+ get { return this; }
}
- string IWizardControl.Title
+ public virtual string Title
{
get { return m_title; }
}
- string IWizardControl.HelpText
+ public virtual string HelpText
{
get { return m_helpText; }
}
- Image IWizardControl.Image
+ public virtual Image Image
{
get { return m_image; }
}
- bool IWizardControl.FullSize
+ public virtual bool FullSize
{
get { return m_fullSize; }
}
- void IWizardControl.Enter(IWizardForm owner)
+ void IWizardControl.Enter(IWizardForm owner, PageChangedArgs args)
{
+ m_owner = args.Owner;
+ m_settings = args.Settings;
+
+ if (m_autoFillValues)
+ m_valuesAutoLoaded = LoadDialogSettings();
+
+ if (PageEnter != null)
+ PageEnter(owner, args);
}
- void IWizardControl.Leave(IWizardForm owner, ref bool cancel)
+ void IWizardControl.Leave(IWizardForm owner, PageChangedArgs args)
{
+ if (PageLeave != null)
+ PageLeave(owner, args);
+
+ if (m_autoFillValues)
+ SaveDialogSettings();
}
#endregion
+
+ protected Control[] FindAllControls()
+ {
+ Dictionary visited = new Dictionary();
+ List items = new List();
+ List result = new List();
+
+ foreach (Control c in this.Controls)
+ items.Add(c);
+
+ while (items.Count > 0)
+ {
+ Control c = items[0];
+ items.RemoveAt(0);
+
+ if (visited.ContainsKey(c))
+ continue;
+ else
+ visited.Add(c, null);
+
+ //Filter out display items
+ if (!(c is Label || c is Button || c is GroupBox || c is Panel))
+ result.Add(c);
+
+ foreach (Control cx in c.Controls)
+ items.Add(cx);
+ }
+
+ return result.ToArray();
+ }
+
+ ///
+ /// Loads previously saved settings
+ ///
+ /// True if there were settings loaded, false otherwise. Use this flag to detect if the control should get default values.
+ protected virtual bool LoadDialogSettings()
+ {
+ string prefix = this.GetType().FullName + ".";
+ bool anyloaded = false;
+
+ foreach(Control c in FindAllControls())
+ {
+ if (m_settings.ContainsKey(prefix + c.Name))
+ {
+ anyloaded = true;
+
+ if (c is CheckBox)
+ ((CheckBox)c).Checked = (bool)m_settings[prefix + c.Name];
+ else if (c is TextBox)
+ c.Text = (string)m_settings[prefix + c.Name];
+ else if (c is ComboBox)
+ {
+ if (((ComboBox)c).DropDownStyle == ComboBoxStyle.DropDownList)
+ ((ComboBox)c).SelectedIndex = (int)m_settings[prefix + c.Name];
+ else
+ c.Text = (string)m_settings[prefix + c.Name];
+ }
+ else if (c is RadioButton)
+ ((RadioButton)c).Checked = (bool)m_settings[prefix + c.Name];
+ else if (c is NumericUpDown)
+ ((NumericUpDown)c).Value = (decimal)m_settings[prefix + c.Name];
+ else if (c is DateTimePicker)
+ ((DateTimePicker)c).Value = (DateTime)m_settings[prefix + c.Name];
+ else
+ {
+ //Default to "Value" if it exists, otherwise use "Text"
+ System.Reflection.PropertyInfo pi = c.GetType().GetProperty("Value");
+ if (pi == null)
+ c.Text = (string)m_settings[prefix + c.Name];
+ else
+ pi.SetValue(c, m_settings[prefix + c.Name], null);
+ }
+ }
+ }
+
+ return anyloaded;
+ }
+
+ protected virtual void SaveDialogSettings()
+ {
+ string prefix = this.GetType().FullName + ".";
+
+ foreach (Control c in FindAllControls())
+ if (c is CheckBox)
+ m_settings[prefix + c.Name] = ((CheckBox)c).Checked;
+ else if (c is TextBox)
+ m_settings[prefix + c.Name] = c.Text;
+ else if (c is ComboBox)
+ {
+ if (((ComboBox)c).DropDownStyle == ComboBoxStyle.DropDownList)
+ m_settings[prefix + c.Name] = ((ComboBox)c).SelectedIndex;
+ else
+ m_settings[prefix + c.Name] = c.Text;
+ }
+ else if (c is RadioButton)
+ m_settings[prefix + c.Name] = ((RadioButton)c).Checked;
+ else if (c is NumericUpDown)
+ m_settings[prefix + c.Name] = ((NumericUpDown)c).Value;
+ else if (c is DateTimePicker)
+ m_settings[prefix + c.Name] = ((DateTimePicker)c).Value;
+ else
+ {
+ //Default to "Value" if it exists, otherwise use "Text"
+ System.Reflection.PropertyInfo pi = c.GetType().GetProperty("Value");
+ if (pi == null)
+ m_settings[prefix + c.Name] = c.Text;
+ else
+ m_settings[prefix + c.Name] = pi.GetValue(c, null);
+
+ }
+ }
+
+ private void InitializeComponent()
+ {
+ this.SuspendLayout();
+ //
+ // WizardControl
+ //
+ this.Name = "WizardControl";
+ this.Size = new System.Drawing.Size(506, 242);
+ this.ResumeLayout(false);
+
+ }
}
}
diff --git a/WizardForm/WizardControl.resx b/WizardForm/WizardControl.resx
new file mode 100644
index 000000000..ff31a6db5
--- /dev/null
+++ b/WizardForm/WizardControl.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/WizardForm/WizardForm.csproj b/WizardForm/WizardForm.csproj
index 9a8af4a34..414799541 100644
--- a/WizardForm/WizardForm.csproj
+++ b/WizardForm/WizardForm.csproj
@@ -53,7 +53,12 @@
StartPage.cs
-
+
+ UserControl
+
+
+ WizardControl.cs
+
@@ -65,6 +70,10 @@
Designer
StartPage.cs
+
+ Designer
+ WizardControl.cs
+
diff --git a/thirdparty/LightDataModel/LightDatamodel.dll b/thirdparty/LightDataModel/LightDatamodel.dll
index 08fec021d..41807e2e5 100644
Binary files a/thirdparty/LightDataModel/LightDatamodel.dll and b/thirdparty/LightDataModel/LightDatamodel.dll differ