diff --git a/Duplicati/GUI/ApplicationSetup.Designer.cs b/Duplicati/GUI/ApplicationSetup.Designer.cs index a05188474..f99ecbf2c 100644 --- a/Duplicati/GUI/ApplicationSetup.Designer.cs +++ b/Duplicati/GUI/ApplicationSetup.Designer.cs @@ -33,8 +33,12 @@ namespace Duplicati.GUI this.GPGPath = new System.Windows.Forms.TextBox(); this.label2 = new System.Windows.Forms.Label(); this.groupBox1 = new System.Windows.Forms.GroupBox(); - this.RecentDuration = new Duplicati.GUI.HelperControls.DurationEditor(); this.groupBox2 = new System.Windows.Forms.GroupBox(); + this.CacheSizeLabel = new System.Windows.Forms.Label(); + this.ClearCacheButton = new System.Windows.Forms.Button(); + this.SignatureCacheEnabled = new System.Windows.Forms.CheckBox(); + this.SignatureCachePathBrowse = new System.Windows.Forms.Button(); + this.SignatureCachePath = new System.Windows.Forms.TextBox(); this.TempPathBrowse = new System.Windows.Forms.Button(); this.TempPath = new System.Windows.Forms.TextBox(); this.label4 = new System.Windows.Forms.Label(); @@ -57,10 +61,9 @@ namespace Duplicati.GUI this.CommonPasswordUseGPG = new System.Windows.Forms.CheckBox(); this.CommonPassword = new System.Windows.Forms.TextBox(); this.UseCommonPassword = new System.Windows.Forms.CheckBox(); - this.SignatureCachePathBrowse = new System.Windows.Forms.Button(); - this.SignatureCachePath = new System.Windows.Forms.TextBox(); - this.SignatureCacheEnabled = new System.Windows.Forms.CheckBox(); this.BrowseSignatureCachePath = new System.Windows.Forms.FolderBrowserDialog(); + this.CacheSizeCalculator = new System.ComponentModel.BackgroundWorker(); + this.RecentDuration = new Duplicati.GUI.HelperControls.DurationEditor(); this.groupBox1.SuspendLayout(); this.groupBox2.SuspendLayout(); this.groupBox3.SuspendLayout(); @@ -108,19 +111,12 @@ namespace Duplicati.GUI this.groupBox1.TabStop = false; this.groupBox1.Text = "User interface settings"; // - // RecentDuration - // - this.RecentDuration.Location = new System.Drawing.Point(208, 24); - this.RecentDuration.Name = "RecentDuration"; - this.RecentDuration.Size = new System.Drawing.Size(221, 21); - this.RecentDuration.TabIndex = 1; - this.RecentDuration.Value = ""; - this.RecentDuration.ValueChanged += new System.EventHandler(this.RecentDuration_ValueChanged); - // // groupBox2 // this.groupBox2.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); + this.groupBox2.Controls.Add(this.CacheSizeLabel); + this.groupBox2.Controls.Add(this.ClearCacheButton); this.groupBox2.Controls.Add(this.SignatureCacheEnabled); this.groupBox2.Controls.Add(this.SignatureCachePathBrowse); this.groupBox2.Controls.Add(this.SignatureCachePath); @@ -138,11 +134,62 @@ namespace Duplicati.GUI this.groupBox2.Controls.Add(this.label2); this.groupBox2.Location = new System.Drawing.Point(8, 176); this.groupBox2.Name = "groupBox2"; - this.groupBox2.Size = new System.Drawing.Size(437, 152); + this.groupBox2.Size = new System.Drawing.Size(437, 176); this.groupBox2.TabIndex = 5; this.groupBox2.TabStop = false; this.groupBox2.Text = "Path settings (Advanced)"; // + // CacheSizeLabel + // + this.CacheSizeLabel.AutoSize = true; + this.CacheSizeLabel.Location = new System.Drawing.Point(128, 152); + this.CacheSizeLabel.Name = "CacheSizeLabel"; + this.CacheSizeLabel.Size = new System.Drawing.Size(125, 13); + this.CacheSizeLabel.TabIndex = 28; + this.CacheSizeLabel.Text = "Calculating cache size ..."; + // + // ClearCacheButton + // + this.ClearCacheButton.Location = new System.Drawing.Point(336, 144); + this.ClearCacheButton.Name = "ClearCacheButton"; + this.ClearCacheButton.Size = new System.Drawing.Size(88, 23); + this.ClearCacheButton.TabIndex = 27; + this.ClearCacheButton.Text = "Clear cache"; + this.ClearCacheButton.UseVisualStyleBackColor = true; + this.ClearCacheButton.Click += new System.EventHandler(this.ClearCacheButton_Click); + // + // SignatureCacheEnabled + // + this.SignatureCacheEnabled.AutoSize = true; + this.SignatureCacheEnabled.Location = new System.Drawing.Point(8, 120); + this.SignatureCacheEnabled.Name = "SignatureCacheEnabled"; + this.SignatureCacheEnabled.Size = new System.Drawing.Size(104, 17); + this.SignatureCacheEnabled.TabIndex = 26; + this.SignatureCacheEnabled.Text = "Signature cache"; + this.SignatureCacheEnabled.UseVisualStyleBackColor = true; + this.SignatureCacheEnabled.CheckedChanged += new System.EventHandler(this.SignatureCacheEnabled_CheckedChanged); + // + // SignatureCachePathBrowse + // + this.SignatureCachePathBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); + this.SignatureCachePathBrowse.Location = new System.Drawing.Point(400, 120); + this.SignatureCachePathBrowse.Name = "SignatureCachePathBrowse"; + this.SignatureCachePathBrowse.Size = new System.Drawing.Size(24, 20); + this.SignatureCachePathBrowse.TabIndex = 25; + this.SignatureCachePathBrowse.Text = "..."; + this.SignatureCachePathBrowse.UseVisualStyleBackColor = true; + this.SignatureCachePathBrowse.Click += new System.EventHandler(this.SignatureCachePathBrowse_Click); + // + // SignatureCachePath + // + this.SignatureCachePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) + | System.Windows.Forms.AnchorStyles.Right))); + this.SignatureCachePath.Location = new System.Drawing.Point(128, 120); + this.SignatureCachePath.Name = "SignatureCachePath"; + this.SignatureCachePath.Size = new System.Drawing.Size(272, 20); + this.SignatureCachePath.TabIndex = 24; + this.SignatureCachePath.TextChanged += new System.EventHandler(this.SignatureCachePath_TextChanged); + // // TempPathBrowse // this.TempPathBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); @@ -247,7 +294,7 @@ namespace Duplicati.GUI // OKBtn // this.OKBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; - this.OKBtn.Location = new System.Drawing.Point(135, 341); + this.OKBtn.Location = new System.Drawing.Point(135, 361); this.OKBtn.Name = "OKBtn"; this.OKBtn.Size = new System.Drawing.Size(80, 24); this.OKBtn.TabIndex = 6; @@ -259,7 +306,7 @@ namespace Duplicati.GUI // this.CancelBtn.Anchor = System.Windows.Forms.AnchorStyles.Bottom; this.CancelBtn.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.CancelBtn.Location = new System.Drawing.Point(231, 341); + this.CancelBtn.Location = new System.Drawing.Point(231, 361); this.CancelBtn.Name = "CancelBtn"; this.CancelBtn.Size = new System.Drawing.Size(72, 24); this.CancelBtn.TabIndex = 7; @@ -336,6 +383,7 @@ namespace Duplicati.GUI this.CommonPassword.Name = "CommonPassword"; this.CommonPassword.Size = new System.Drawing.Size(296, 20); this.CommonPassword.TabIndex = 1; + this.CommonPassword.UseSystemPasswordChar = true; this.CommonPassword.TextChanged += new System.EventHandler(this.CommonPassword_TextChanged); // // UseCommonPassword @@ -349,44 +397,27 @@ namespace Duplicati.GUI this.UseCommonPassword.UseVisualStyleBackColor = true; this.UseCommonPassword.CheckedChanged += new System.EventHandler(this.UseCommonPassword_CheckedChanged); // - // SignatureCachePathBrowse + // CacheSizeCalculator // - this.SignatureCachePathBrowse.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); - this.SignatureCachePathBrowse.Location = new System.Drawing.Point(400, 120); - this.SignatureCachePathBrowse.Name = "SignatureCachePathBrowse"; - this.SignatureCachePathBrowse.Size = new System.Drawing.Size(24, 20); - this.SignatureCachePathBrowse.TabIndex = 25; - this.SignatureCachePathBrowse.Text = "..."; - this.SignatureCachePathBrowse.UseVisualStyleBackColor = true; - this.SignatureCachePathBrowse.Click += new System.EventHandler(this.SignatureCachePathBrowse_Click); + this.CacheSizeCalculator.WorkerSupportsCancellation = true; + this.CacheSizeCalculator.DoWork += new System.ComponentModel.DoWorkEventHandler(this.CacheSizeCalculator_DoWork); + this.CacheSizeCalculator.RunWorkerCompleted += new System.ComponentModel.RunWorkerCompletedEventHandler(this.CacheSizeCalculator_RunWorkerCompleted); // - // SignatureCachePath + // RecentDuration // - this.SignatureCachePath.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left) - | System.Windows.Forms.AnchorStyles.Right))); - this.SignatureCachePath.Location = new System.Drawing.Point(128, 120); - this.SignatureCachePath.Name = "SignatureCachePath"; - this.SignatureCachePath.Size = new System.Drawing.Size(272, 20); - this.SignatureCachePath.TabIndex = 24; - this.SignatureCachePath.TextChanged += new System.EventHandler(this.SignatureCachePath_TextChanged); - // - // SignatureCacheEnabled - // - this.SignatureCacheEnabled.AutoSize = true; - this.SignatureCacheEnabled.Location = new System.Drawing.Point(8, 120); - this.SignatureCacheEnabled.Name = "SignatureCacheEnabled"; - this.SignatureCacheEnabled.Size = new System.Drawing.Size(104, 17); - this.SignatureCacheEnabled.TabIndex = 26; - this.SignatureCacheEnabled.Text = "Signature cache"; - this.SignatureCacheEnabled.UseVisualStyleBackColor = true; - this.SignatureCacheEnabled.CheckedChanged += new System.EventHandler(this.SignatureCacheEnabled_CheckedChanged); + this.RecentDuration.Location = new System.Drawing.Point(208, 24); + this.RecentDuration.Name = "RecentDuration"; + this.RecentDuration.Size = new System.Drawing.Size(221, 21); + this.RecentDuration.TabIndex = 1; + this.RecentDuration.Value = ""; + this.RecentDuration.ValueChanged += new System.EventHandler(this.RecentDuration_ValueChanged); // // ApplicationSetup // 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(453, 379); + this.ClientSize = new System.Drawing.Size(453, 399); this.Controls.Add(this.groupBox3); this.Controls.Add(this.CancelBtn); this.Controls.Add(this.OKBtn); @@ -400,6 +431,7 @@ namespace Duplicati.GUI this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; this.Text = "Duplicati setup"; this.Load += new System.EventHandler(this.ApplicationSetup_Load); + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ApplicationSetup_FormClosing); this.groupBox1.ResumeLayout(false); this.groupBox1.PerformLayout(); this.groupBox2.ResumeLayout(false); @@ -446,5 +478,8 @@ namespace Duplicati.GUI private System.Windows.Forms.Button SignatureCachePathBrowse; private System.Windows.Forms.TextBox SignatureCachePath; private System.Windows.Forms.FolderBrowserDialog BrowseSignatureCachePath; + private System.Windows.Forms.Label CacheSizeLabel; + private System.Windows.Forms.Button ClearCacheButton; + private System.ComponentModel.BackgroundWorker CacheSizeCalculator; } } \ No newline at end of file diff --git a/Duplicati/GUI/ApplicationSetup.cs b/Duplicati/GUI/ApplicationSetup.cs index c7a24a10d..b748e3c23 100644 --- a/Duplicati/GUI/ApplicationSetup.cs +++ b/Duplicati/GUI/ApplicationSetup.cs @@ -35,6 +35,11 @@ namespace Duplicati.GUI private ApplicationSettings m_settings; private bool m_isUpdating = false; + //These variables handle the worker thread size calculation + private object m_lock = new object(); + private System.Threading.Thread m_thread = null; + private bool m_restartCalculator = false; + public ApplicationSetup() { InitializeComponent(); @@ -65,6 +70,7 @@ namespace Duplicati.GUI SignatureCacheEnabled.Checked = m_settings.SignatureCacheEnabled; SignatureCachePath.Text = m_settings.SignatureCachePath; + CalculateSignatureCacheSize(); } finally { @@ -212,6 +218,7 @@ namespace Duplicati.GUI return; m_settings.SignatureCachePath = SignatureCachePath.Text; + CalculateSignatureCacheSize(); } private void SignatureCacheEnabled_CheckedChanged(object sender, EventArgs e) @@ -222,7 +229,89 @@ namespace Duplicati.GUI return; m_settings.SignatureCacheEnabled = SignatureCacheEnabled.Checked; + CalculateSignatureCacheSize(); + } + private void CacheSizeCalculator_DoWork(object sender, DoWorkEventArgs e) + { + lock (m_lock) + m_thread = System.Threading.Thread.CurrentThread; + + try + { + e.Result = "Cache size: " + Library.Core.Utility.FormatSizeString(Library.Core.Utility.GetDirectorySize(System.Environment.ExpandEnvironmentVariables((string)e.Argument), null)); + } + catch (System.Threading.ThreadAbortException) + { + System.Threading.Thread.ResetAbort(); + e.Cancel = true; + } + finally + { + lock (m_lock) + m_thread = null; + } + + } + + private void CacheSizeCalculator_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) + { + if (e.Cancelled) + CacheSizeLabel.Text = "Cancelled"; + else if (e.Error != null) + CacheSizeLabel.Text = e.Error.Message; + else + CacheSizeLabel.Text = (string)e.Result; + + if (m_restartCalculator) + CalculateSignatureCacheSize(); + } + + private void CalculateSignatureCacheSize() + { + CacheSizeLabel.Text = "Calculating cache size ..."; + + lock (m_lock) + if (CacheSizeCalculator.IsBusy) + { + m_restartCalculator = true; + m_thread.Abort(); + } + else + { + m_restartCalculator = false; + if (SignatureCacheEnabled.Checked) + CacheSizeCalculator.RunWorkerAsync(SignatureCachePath.Text); + else + CacheSizeLabel.Text = ""; + } + } + + private void ClearCacheButton_Click(object sender, EventArgs e) + { + try + { + string path = System.Environment.ExpandEnvironmentVariables(SignatureCachePath.Text); + if (MessageBox.Show(this, "Delete signature files in the folder: \n" + path, Application.ProductName, MessageBoxButtons.YesNoCancel, MessageBoxIcon.Warning) != DialogResult.Yes) + return; + + Library.Main.Interface.RemoveSignatureFiles(path); + CalculateSignatureCacheSize(); + } + catch(Exception ex) + { + MessageBox.Show(this, "An error occured: " + ex.Message, Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Error); + } + } + + private void ApplicationSetup_FormClosing(object sender, FormClosingEventArgs e) + { + lock(m_lock) + if (m_thread != null) + { + m_restartCalculator = false; + m_thread.Abort(); + } } } diff --git a/Duplicati/GUI/ApplicationSetup.resx b/Duplicati/GUI/ApplicationSetup.resx index f9a171871..b5117b9d2 100644 --- a/Duplicati/GUI/ApplicationSetup.resx +++ b/Duplicati/GUI/ApplicationSetup.resx @@ -132,6 +132,9 @@ 553, 17 + + 741, 17 + diff --git a/Duplicati/GUI/Duplicati.csproj b/Duplicati/GUI/Duplicati.csproj index 3ed5261bb..b1842ec18 100644 --- a/Duplicati/GUI/Duplicati.csproj +++ b/Duplicati/GUI/Duplicati.csproj @@ -653,6 +653,9 @@ + + + diff --git a/Duplicati/GUI/ListBackupFiles.Designer.cs b/Duplicati/GUI/ListBackupFiles.Designer.cs index 9f05ebf0e..dba03090e 100644 --- a/Duplicati/GUI/ListBackupFiles.Designer.cs +++ b/Duplicati/GUI/ListBackupFiles.Designer.cs @@ -121,6 +121,7 @@ namespace Duplicati.GUI this.ShowInTaskbar = false; this.StartPosition = System.Windows.Forms.FormStartPosition.CenterParent; this.Text = "Files in selected backup"; + this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.ListBackupFiles_FormClosing); this.groupBox1.ResumeLayout(false); this.ContentPanel.ResumeLayout(false); this.ResumeLayout(false); diff --git a/Duplicati/GUI/ListBackupFiles.cs b/Duplicati/GUI/ListBackupFiles.cs index e9e49a2fc..3e2403bf7 100644 --- a/Duplicati/GUI/ListBackupFiles.cs +++ b/Duplicati/GUI/ListBackupFiles.cs @@ -29,6 +29,10 @@ namespace Duplicati.GUI { public partial class ListBackupFiles : Form { + + private object m_lock = new object(); + private System.Threading.Thread m_thread = null; + public ListBackupFiles() { InitializeComponent(); @@ -49,9 +53,25 @@ namespace Duplicati.GUI private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e) { - object[] args = (object[])e.Argument; - DuplicatiRunner r = new DuplicatiRunner(); - e.Result = r.ListActualFiles((Datamodel.Schedule)args[0], (DateTime)args[1]); + lock (m_lock) + m_thread = System.Threading.Thread.CurrentThread; + + try + { + object[] args = (object[])e.Argument; + DuplicatiRunner r = new DuplicatiRunner(); + e.Result = r.ListActualFiles((Datamodel.Schedule)args[0], (DateTime)args[1]); + } + catch (System.Threading.ThreadAbortException) + { + System.Threading.Thread.ResetAbort(); + e.Cancel = true; + } + finally + { + lock (m_lock) + m_thread = null; + } } private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) @@ -175,5 +195,12 @@ namespace Duplicati.GUI parent = match.Nodes; } } + + private void ListBackupFiles_FormClosing(object sender, FormClosingEventArgs e) + { + lock (m_lock) + if (m_thread != null) + m_thread.Abort(); + } } } \ No newline at end of file diff --git a/Duplicati/GUI/Program.cs b/Duplicati/GUI/Program.cs index ce046f7be..1d2f3fdfc 100644 --- a/Duplicati/GUI/Program.cs +++ b/Duplicati/GUI/Program.cs @@ -123,7 +123,7 @@ namespace Duplicati.GUI TrayIcon.Icon = Properties.Resources.TrayNormal; TrayIcon.ContextMenuStrip.Items.Add("Status", Properties.Resources.StatusMenuIcon, new EventHandler(Status_Clicked)); - TrayIcon.ContextMenuStrip.Items.Add("Setup", Properties.Resources.SetupMenuIcon, new EventHandler(Setup_Clicked)); + TrayIcon.ContextMenuStrip.Items.Add("Wizard ...", Properties.Resources.WizardMenuIcon, new EventHandler(Setup_Clicked)); TrayIcon.ContextMenuStrip.Items.Add(new ToolStripSeparator()); TrayIcon.ContextMenuStrip.Items.Add("Settings", Properties.Resources.SettingsMenuIcon, new EventHandler(Settings_Clicked)); diff --git a/Duplicati/GUI/Properties/Resources.Designer.cs b/Duplicati/GUI/Properties/Resources.Designer.cs index 87b7c58a3..79950c010 100644 --- a/Duplicati/GUI/Properties/Resources.Designer.cs +++ b/Duplicati/GUI/Properties/Resources.Designer.cs @@ -165,13 +165,6 @@ namespace Duplicati.GUI.Properties { } } - internal static System.Drawing.Bitmap SetupMenuIcon { - get { - object obj = ResourceManager.GetObject("SetupMenuIcon", resourceCulture); - return ((System.Drawing.Bitmap)(obj)); - } - } - internal static System.Drawing.Bitmap SmallLogo { get { object obj = ResourceManager.GetObject("SmallLogo", resourceCulture); @@ -220,5 +213,12 @@ namespace Duplicati.GUI.Properties { return ((System.Drawing.Bitmap)(obj)); } } + + internal static System.Drawing.Bitmap WizardMenuIcon { + get { + object obj = ResourceManager.GetObject("WizardMenuIcon", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } } } diff --git a/Duplicati/GUI/Properties/Resources.resx b/Duplicati/GUI/Properties/Resources.resx index 891236776..e322ab1f9 100644 --- a/Duplicati/GUI/Properties/Resources.resx +++ b/Duplicati/GUI/Properties/Resources.resx @@ -163,9 +163,6 @@ ..\Resources\SettingsMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - - ..\Resources\SetupMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a - ..\Resources\SmallLogo.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a @@ -187,4 +184,7 @@ ..\Resources\WarningStatusIcon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + + ..\Resources\WizardMenuIcon.png;System.Drawing.Bitmap, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a + \ No newline at end of file diff --git a/Duplicati/GUI/Resources/WizardMenuIcon.png b/Duplicati/GUI/Resources/WizardMenuIcon.png new file mode 100644 index 000000000..a72337d3d Binary files /dev/null and b/Duplicati/GUI/Resources/WizardMenuIcon.png differ diff --git a/Duplicati/GUI/Scheduler.cs b/Duplicati/GUI/Scheduler.cs index 375782747..e58be648c 100644 --- a/Duplicati/GUI/Scheduler.cs +++ b/Duplicati/GUI/Scheduler.cs @@ -132,7 +132,7 @@ namespace Duplicati.GUI if (m_schedule.Length > 0) { - TimeSpan nextrun = m_schedule[0].When - DateTime.Now; + TimeSpan nextrun = m_schedule[0].NextScheduledTime - DateTime.Now; if (nextrun.TotalMilliseconds < 0) continue; diff --git a/Duplicati/GUI/ServiceStatus.Designer.cs b/Duplicati/GUI/ServiceStatus.Designer.cs index ded6e74e5..226e8cec6 100644 --- a/Duplicati/GUI/ServiceStatus.Designer.cs +++ b/Duplicati/GUI/ServiceStatus.Designer.cs @@ -68,9 +68,12 @@ namespace Duplicati.GUI this.CurrentStatus = new System.Windows.Forms.Label(); this.label1 = new System.Windows.Forms.Label(); this.toolTip1 = new System.Windows.Forms.ToolTip(this.components); + this.contextMenuStrip = new System.Windows.Forms.ContextMenuStrip(this.components); + this.viewFilesToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem(); this.advancedPanel.SuspendLayout(); this.simplePanel.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)(this.statusImage)).BeginInit(); + this.contextMenuStrip.SuspendLayout(); this.SuspendLayout(); // // label3 @@ -169,6 +172,7 @@ namespace Duplicati.GUI this.columnHeader1, this.columnHeader2, this.columnHeader3}); + this.recentBackups.ContextMenuStrip = this.contextMenuStrip; this.recentBackups.FullRowSelect = true; this.recentBackups.Location = new System.Drawing.Point(0, 80); this.recentBackups.MultiSelect = false; @@ -179,6 +183,7 @@ namespace Duplicati.GUI this.recentBackups.TabIndex = 15; this.recentBackups.UseCompatibleStateImageBehavior = false; this.recentBackups.View = System.Windows.Forms.View.Details; + this.recentBackups.SelectedIndexChanged += new System.EventHandler(this.recentBackups_SelectedIndexChanged); this.recentBackups.DoubleClick += new System.EventHandler(this.recentBackups_DoubleClick); // // columnHeader1 @@ -239,6 +244,21 @@ namespace Duplicati.GUI this.label1.TabIndex = 10; this.label1.Text = "Recently completed backups"; // + // contextMenuStrip + // + this.contextMenuStrip.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { + this.viewFilesToolStripMenuItem}); + this.contextMenuStrip.Name = "contextMenuStrip"; + this.contextMenuStrip.Size = new System.Drawing.Size(168, 48); + // + // viewFilesToolStripMenuItem + // + this.viewFilesToolStripMenuItem.Image = global::Duplicati.GUI.Properties.Resources.Examine; + this.viewFilesToolStripMenuItem.Name = "viewFilesToolStripMenuItem"; + this.viewFilesToolStripMenuItem.Size = new System.Drawing.Size(167, 22); + this.viewFilesToolStripMenuItem.Text = "View contents ..."; + this.viewFilesToolStripMenuItem.Click += new System.EventHandler(this.viewFilesToolStripMenuItem_Click); + // // ServiceStatus // this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F); @@ -260,6 +280,7 @@ namespace Duplicati.GUI this.simplePanel.ResumeLayout(false); this.simplePanel.PerformLayout(); ((System.ComponentModel.ISupportInitialize)(this.statusImage)).EndInit(); + this.contextMenuStrip.ResumeLayout(false); this.ResumeLayout(false); } @@ -285,5 +306,7 @@ namespace Duplicati.GUI private System.Windows.Forms.Label ProgressMessage; private System.Windows.Forms.ToolTip toolTip1; private System.Windows.Forms.ProgressBar SubProgressBar; + private System.Windows.Forms.ContextMenuStrip contextMenuStrip; + private System.Windows.Forms.ToolStripMenuItem viewFilesToolStripMenuItem; } } \ No newline at end of file diff --git a/Duplicati/GUI/ServiceStatus.cs b/Duplicati/GUI/ServiceStatus.cs index ff58c1e02..a480ba475 100644 --- a/Duplicati/GUI/ServiceStatus.cs +++ b/Duplicati/GUI/ServiceStatus.cs @@ -259,5 +259,25 @@ namespace Duplicati.GUI SubProgressBar.Left = simplePanel.Width - SubProgressBar.Width; } + private void recentBackups_SelectedIndexChanged(object sender, EventArgs e) + { + viewFilesToolStripMenuItem.Enabled = recentBackups.SelectedItems.Count == 1; + } + + private void viewFilesToolStripMenuItem_Click(object sender, EventArgs e) + { + if (recentBackups.SelectedItems.Count != 1) + return; + + Log l = recentBackups.SelectedItems[0].Tag as Log; + if (l == null) + return; + Schedule s = l.OwnerTask.Schedule; + DateTime time = l.EndTime; //Not the excact time to use, but close enough unless there were multiple backups running at the same time + + ListBackupFiles dlg = new ListBackupFiles(); + dlg.ShowList(this, s, time); + } + } } \ No newline at end of file diff --git a/Duplicati/GUI/ServiceStatus.resx b/Duplicati/GUI/ServiceStatus.resx index 0bab50d8a..554938df0 100644 --- a/Duplicati/GUI/ServiceStatus.resx +++ b/Duplicati/GUI/ServiceStatus.resx @@ -117,6 +117,9 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + 208, 17 + 17, 17 diff --git a/Duplicati/Library/Main/BackendWrapper.cs b/Duplicati/Library/Main/BackendWrapper.cs index bb79428fe..2e2129f99 100644 --- a/Duplicati/Library/Main/BackendWrapper.cs +++ b/Duplicati/Library/Main/BackendWrapper.cs @@ -42,8 +42,15 @@ namespace Duplicati.Library.Main //Temporary variable for progress reporting private string m_statusmessage; + /// + /// The cache filename strategy used + /// + /// A cache filename strategy object + public static FilenameStrategy CreateCacheFilenameStrategy() { return new FilenameStrategy("dpl", "_", true); } + private FilenameStrategy m_filenamestrategy; - private FilenameStrategy m_cachefilenamestrategy = new FilenameStrategy("dpl", "_", true); + private FilenameStrategy m_cachefilenamestrategy = BackendWrapper.CreateCacheFilenameStrategy(); + private List m_orphans; diff --git a/Duplicati/Library/Main/FilenameStrategy.cs b/Duplicati/Library/Main/FilenameStrategy.cs index b5d8b2fc0..009306510 100644 --- a/Duplicati/Library/Main/FilenameStrategy.cs +++ b/Duplicati/Library/Main/FilenameStrategy.cs @@ -145,5 +145,7 @@ namespace Duplicati.Library.Main return new BackupEntry(fe, time, type, isFull, isShortName, volNumber, compression, encryption); } + public bool UseShortNames { get { return m_useShortFilenames; } } + public string Prefix { get { return m_prefix; } } } } diff --git a/Duplicati/Library/Main/Interface.cs b/Duplicati/Library/Main/Interface.cs index b5cc51910..56d2ef255 100644 --- a/Duplicati/Library/Main/Interface.cs +++ b/Duplicati/Library/Main/Interface.cs @@ -776,7 +776,7 @@ namespace Duplicati.Library.Main if (string.IsNullOrEmpty(m_options.SignatureCachePath)) throw new Exception("Signature cache path was not given as an argument"); else - System.IO.Directory.Delete(m_options.SignatureCachePath, true); + RemoveSignatureFiles(m_options.SignatureCachePath); } public List GetBackupSets() @@ -802,6 +802,20 @@ namespace Duplicati.Library.Main } } + + public static void RemoveSignatureFiles(string folder) + { + FilenameStrategy cachenames = BackendWrapper.CreateCacheFilenameStrategy(); + foreach (string s in Core.Utility.EnumerateFiles(folder)) + { + BackupEntry e = cachenames.DecodeFilename(new Duplicati.Library.Backend.FileEntry(System.IO.Path.GetFileName(s))); + if (e.IsShortName == cachenames.UseShortNames && e.Type == BackupEntry.EntryType.Signature) + { + try { System.IO.File.Delete(s); } + catch {} + } + } + } //Static helpers diff --git a/Duplicati/Library/Main/RSyncDir.cs b/Duplicati/Library/Main/RSyncDir.cs index ab3e43cbb..bd729b475 100644 --- a/Duplicati/Library/Main/RSyncDir.cs +++ b/Duplicati/Library/Main/RSyncDir.cs @@ -238,17 +238,20 @@ namespace Duplicati.Library.Main.RSync string dirmarker = System.IO.Path.DirectorySeparatorChar.ToString(); for(int i = 0; i < m_unproccesed.Folders.Count; i++) { - string relpath = m_unproccesed.Files[i].Substring(m_sourcefolder.Length); - if (!m_oldFolders.ContainsKey(relpath)) - m_newfolders.Add(relpath); - else - m_oldFolders.Remove(relpath); + string relpath = m_unproccesed.Folders[i].Substring(m_sourcefolder.Length); + if (relpath.Trim().Length != 0) + { + if (!m_oldFolders.ContainsKey(relpath)) + m_newfolders.Add(relpath); + else + m_oldFolders.Remove(relpath); + } } m_unproccesed.Folders.Clear(); - - m_deletedfolders = new List(); - m_deletedfolders.AddRange(m_oldFolders.Keys); + foreach(string s in m_oldFolders.Keys) + if (!m_unproccesed.IsAffectedByError(s)) + m_deletedfolders.AddRange(m_oldFolders.Keys); } public void FinalizeMultiPass(Core.IFileArchive signaturefile, Core.IFileArchive contentfile) diff --git a/thirdparty/SQLite/Dll for .Net/ManagedOnly/System.Data.SQLite.dll b/thirdparty/SQLite/Dll for .Net/ManagedOnly/System.Data.SQLite.dll new file mode 100644 index 000000000..ebf200483 Binary files /dev/null and b/thirdparty/SQLite/Dll for .Net/ManagedOnly/System.Data.SQLite.dll differ diff --git a/thirdparty/SQLite/Dll for .Net/ManagedOnly/readme.txt b/thirdparty/SQLite/Dll for .Net/ManagedOnly/readme.txt new file mode 100644 index 000000000..45a1acd80 --- /dev/null +++ b/thirdparty/SQLite/Dll for .Net/ManagedOnly/readme.txt @@ -0,0 +1,4 @@ +This managed version of the ADO.NET provider for SQLite requires the native +sqlite3.dll or Linux shared library from http://www.sqlite.org + +Requires version 3.6.3 or higher. diff --git a/thirdparty/SQLite/Dll for .Net/System.Data.SQLite.DLL b/thirdparty/SQLite/Dll for .Net/System.Data.SQLite.DLL index 6e1905726..080c74cd5 100644 Binary files a/thirdparty/SQLite/Dll for .Net/System.Data.SQLite.DLL and b/thirdparty/SQLite/Dll for .Net/System.Data.SQLite.DLL differ