From: Takayoshi Matsuyama Date: Wed, 1 Apr 2015 20:14:50 +0000 (+0900) Subject: Ver.1.0.0.185 Task187 Interface based design X-Git-Url: http://git.osdn.net/view?a=commitdiff_plain;h=bf9605a7c39717f42961d2566428d676c6dc269f;p=simplebackup%2FSBTGitRepository.git Ver.1.0.0.185 Task187 Interface based design --- diff --git a/Main/App.config b/Main/App.config index 4d0f454..89a67b9 100644 --- a/Main/App.config +++ b/Main/App.config @@ -13,25 +13,12 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Foobar. If not, see . +along with Simple Backup. If not, see . --> - -
- - - - - - - - - - - \ No newline at end of file diff --git a/Main/App.xaml b/Main/App.xaml index 89f7c69..55ca79c 100644 --- a/Main/App.xaml +++ b/Main/App.xaml @@ -12,12 +12,9 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with Foobar. If not, see . +along with Simple Backup. If not, see . --> + - - - - + xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"/> diff --git a/Main/App.xaml.cs b/Main/App.xaml.cs index b3a2597..4fac83b 100644 --- a/Main/App.xaml.cs +++ b/Main/App.xaml.cs @@ -17,27 +17,37 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with Foobar. If not, see . - -using System; -using System.Windows; -using SimpleBackup.Services; -using SimpleBackup.ViewModels; -using SimpleBackup.Views; +// along with Simple Backup. If not, see . namespace SimpleBackup { + using System; + using System.Windows; + using SimpleBackup.Core; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.ViewModels; + using SimpleBackup.Core.Views; + /// - /// App.xaml の相互作用ロジック + /// The Code-Behind of App.xaml. /// public partial class App : Application { + /// + /// Raises the event. + /// + /// A that contains the event data. protected override void OnStartup(StartupEventArgs e) { try { - var mainWindow = new MainWindow(); - var mainWindowViewModel = new MainWindowViewModel(); + var bootStrapper = new Bootstrapper(); + bootStrapper.Execute(); + + var viewFactory = ObjectContainer.Resolve(); + var viewModelFactory = ObjectContainer.Resolve(); + IMainWindow mainWindow = viewFactory.CreateMainWindow(); + IMainWindowViewModel mainWindowViewModel = viewModelFactory.CreateMainWindowViewModel(); mainWindow.DataContext = mainWindowViewModel; mainWindow.Show(); } @@ -47,15 +57,20 @@ namespace SimpleBackup } } + /// + /// Raises the event. + /// + /// An that contains the event data. protected override void OnExit(ExitEventArgs e) { base.OnExit(e); - if (BackupSettingService.Instance.CurrentSetting != null) + var backupSettingService = ObjectContainer.Resolve(); + if (backupSettingService.CurrentSetting != null) { - SimpleBackup.Properties.Settings.Default.DefaultSettingFileName = - BackupSettingService.Instance.CurrentSetting.SettingFileName; - SimpleBackup.Properties.Settings.Default.Save(); + var settingsService = ObjectContainer.Resolve(); + settingsService.DefaultSettingFileName = + backupSettingService.CurrentSetting.SettingFileName; } } } diff --git a/Main/Bootstrapper.cs b/Main/Bootstrapper.cs new file mode 100644 index 0000000..5e3b8aa --- /dev/null +++ b/Main/Bootstrapper.cs @@ -0,0 +1,97 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.Linq; + using System.Reflection; + using SimpleBackup.Core.AppInfrastructure; + + /// + /// Executes application starting procedure. + /// + public class Bootstrapper + { + /// + /// Executes application starting procedure. + /// + public void Execute() + { + IAppComponent[] appComponents = SearchApplicationComponents(); + InitializeAppComponents(appComponents); + } + + /// + /// Searches the application components. + /// + /// The collection of application component. + private static IAppComponent[] SearchApplicationComponents() + { + Type appComponenType = typeof(IAppComponent); + var appComponents = new HashSet(); + + Assembly executingAssembly = Assembly.GetExecutingAssembly(); + string executingAssemblyFolder = Path.GetDirectoryName(executingAssembly.Location); + string[] files = Directory.GetFiles(executingAssemblyFolder, "*.dll"); + foreach (string file in files) + { + Assembly assembly = Assembly.LoadFrom(file); + Type[] types = assembly.GetTypes(); + foreach (Type type in types) + { + Type[] interfaceTypes = type.GetInterfaces(); + foreach (Type interfaceType in interfaceTypes) + { + if ((interfaceType.FullName == appComponenType.FullName) && + (interfaceType.Assembly.FullName == appComponenType.Assembly.FullName)) + { + appComponents.Add((IAppComponent)Activator.CreateInstance(type)); + } + } + } + } + + return appComponents.ToArray(); + } + + /// + /// Initializes the application components. + /// + /// The application components. + private static void InitializeAppComponents(IEnumerable appComponents) + { + foreach (IAppComponent appComponent in appComponents) + { + try + { + appComponent.Initialize(); + } + catch (Exception e) + { + Console.WriteLine(e); + } + } + } + } +} diff --git a/Main/Documents/Screenshot.png b/Main/Documents/Screenshot.png new file mode 100644 index 0000000..4528a2a Binary files /dev/null and b/Main/Documents/Screenshot.png differ diff --git a/Main/Properties/AssemblyInfo.cs b/Main/Properties/AssemblyInfo.cs index 4188813..ea5202c 100644 --- a/Main/Properties/AssemblyInfo.cs +++ b/Main/Properties/AssemblyInfo.cs @@ -17,7 +17,7 @@ // GNU General Public License for more details. // // You should have received a copy of the GNU General Public License -// along with Foobar. If not, see . +// along with Simple Backup. If not, see . using System.Reflection; using System.Resources; @@ -34,10 +34,10 @@ using System.Windows; [assembly: AssemblyCulture("")] [assembly: ComVisible(false)] -[assembly: ThemeInfo( - ResourceDictionaryLocation.None, - ResourceDictionaryLocation.SourceAssembly)] +//[assembly: ThemeInfo( +// ResourceDictionaryLocation.None, +// ResourceDictionaryLocation.SourceAssembly)] -[assembly: AssemblyVersion("1.0.0.182")] -[assembly: AssemblyFileVersion("1.0.0.182")] +[assembly: AssemblyVersion("1.0.0.185")] +[assembly: AssemblyFileVersion("1.0.0.185")] [assembly: NeutralResourcesLanguageAttribute("en")] diff --git a/Main/Properties/Settings.Designer.cs b/Main/Properties/Settings.Designer.cs index 1735088..99259b0 100644 --- a/Main/Properties/Settings.Designer.cs +++ b/Main/Properties/Settings.Designer.cs @@ -22,29 +22,5 @@ namespace SimpleBackup.Properties { return defaultInstance; } } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string DefaultSettingFileName { - get { - return ((string)(this["DefaultSettingFileName"])); - } - set { - this["DefaultSettingFileName"] = value; - } - } - - [global::System.Configuration.UserScopedSettingAttribute()] - [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] - [global::System.Configuration.DefaultSettingValueAttribute("")] - public string DefaultZipEncodingKeyText { - get { - return ((string)(this["DefaultZipEncodingKeyText"])); - } - set { - this["DefaultZipEncodingKeyText"] = value; - } - } } } diff --git a/Main/Properties/Settings.settings b/Main/Properties/Settings.settings index cec136e..8e615f2 100644 --- a/Main/Properties/Settings.settings +++ b/Main/Properties/Settings.settings @@ -1,12 +1,5 @@  - + - - - - - - - - + \ No newline at end of file diff --git a/Main/SimpleBackup.Core/AppInfrastructure/IAppComponent.cs b/Main/SimpleBackup.Core/AppInfrastructure/IAppComponent.cs new file mode 100644 index 0000000..9fed912 --- /dev/null +++ b/Main/SimpleBackup.Core/AppInfrastructure/IAppComponent.cs @@ -0,0 +1,34 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.AppInfrastructure +{ + /// + /// Interface of an application component. + /// + public interface IAppComponent + { + /// + /// Initializes this application component. + /// + void Initialize(); + } +} diff --git a/Main/SimpleBackup.Core/Models/BackupSourceType.cs b/Main/SimpleBackup.Core/Models/BackupSourceType.cs new file mode 100644 index 0000000..1befdbf --- /dev/null +++ b/Main/SimpleBackup.Core/Models/BackupSourceType.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + /// + /// Represents backup source type. + /// + public enum BackupSourceType + { + /// + /// The file + /// + File, + + /// + /// The folder + /// + Folder + } +} diff --git a/Main/SimpleBackup.Core/Models/BackupState.cs b/Main/SimpleBackup.Core/Models/BackupState.cs new file mode 100644 index 0000000..57c755c --- /dev/null +++ b/Main/SimpleBackup.Core/Models/BackupState.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + /// + /// Represents backup state. + /// + public enum BackupState + { + /// + /// The to do + /// + Todo, + + /// + /// The in progress + /// + InProgress, + + /// + /// The success + /// + Success, + + /// + /// The failed + /// + Failed, + + /// + /// The cancelled + /// + Cancelled, + + /// + /// The skipped + /// + Skipped, + } +} diff --git a/Main/SimpleBackup.Core/Models/IBackupInfo.cs b/Main/SimpleBackup.Core/Models/IBackupInfo.cs new file mode 100644 index 0000000..c5ac655 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/IBackupInfo.cs @@ -0,0 +1,101 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + using System; + using System.ComponentModel; + using System.Xml.Linq; + + /// + /// A interface of single backup information. + /// + public interface IBackupInfo : INotifyPropertyChanged + { + /// + /// Occurs when a property which has to be saved in setting file is changed. + /// + event EventHandler SettingFilePropertyChanged; + + /// + /// Gets or sets the identifier. + /// + Guid Id { get; set; } + + /// + /// Gets or sets the label. + /// + string Label { get; set; } + + /// + /// Gets or sets the type of the backup source. + /// + BackupSourceType BackupSourceType { get; set; } + + /// + /// Gets or sets a value indicating whether the backup is enabled. + /// + bool IsEnabled { get; set; } + + /// + /// Gets or sets a value indicating whether the backup is zip archive. + /// + bool IsZipArchive { get; set; } + + /// + /// Gets or sets the source path. + /// + string SourcePath { get; set; } + + /// + /// Gets or sets the destination folder path. + /// + string DestinationFolderPath { get; set; } + + /// + /// Gets or sets the state of the backup. + /// + BackupState BackupState { get; set; } + + /// + /// Gets or sets the name of the latest successful backup target. + /// + string LatestSuccessfulBackupTargetName { get; set; } + + /// + /// Saves this instance to a XElement. + /// + /// The generated XElement. + XElement ToXml(); + + /// + /// Gets the binary representation of this instance. + /// + /// The binary representation of this instance. + byte[] ToBinary(); + + /// + /// Gets the formatted text representation of this instance. + /// + /// The text representation of this instance. + string ToFormattedText(); + } +} diff --git a/Main/SimpleBackup.Core/Models/IBackupSetting.cs b/Main/SimpleBackup.Core/Models/IBackupSetting.cs new file mode 100644 index 0000000..ef11a85 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/IBackupSetting.cs @@ -0,0 +1,96 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + + /// + /// Interface of a backup setting. + /// + public interface IBackupSetting + { + /// + /// Occurs when backup setting is modified. + /// + event EventHandler SettingModified; + + /// + /// Gets the name of the setting. + /// + string SettingName { get; } + + /// + /// Gets or sets the name of the setting file. + /// + string SettingFileName { get; set; } + + /// + /// Gets or sets a value indicating whether this is modified. + /// + bool Modified { get; set; } + + /// + /// Gets the backup infos. + /// + IReadOnlyCollection BackupInfos { get; } + + /// + /// Gets the count of backup Information item. + /// + int Count { get; } + + /// + /// Firsts the or default. + /// + /// The identifier. + /// The IBackupInfo which is firstly found or null. + IBackupInfo FirstOrDefault(Guid id); + + /// + /// Inserts the specified index. + /// + /// The index. + /// The backup information. + void Insert(int index, IBackupInfo backupInfo); + + /// + /// Removes the specified removing backup information. + /// + /// The removing backup information. + void Remove(IBackupInfo removingBackupInfo); + + /// + /// Moves the item. + /// + /// The backup information identifier. + /// The moving direction. + void MoveItem(Guid backupInfoId, ItemMovingDirection movingDirection); + + /// + /// To the XML. + /// + /// The xml data. + XElement ToXml(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Models/IDestinationPathInfo.cs b/Main/SimpleBackup.Core/Models/IDestinationPathInfo.cs new file mode 100644 index 0000000..9a72c73 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/IDestinationPathInfo.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + /// + /// Interface of a destination path information. + /// + public interface IDestinationPathInfo + { + /// + /// Gets the type of the backup source. + /// + BackupSourceType BackupSourceType { get; } + + /// + /// Gets the path. + /// + string Path { get; } + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Models/IModelFactory.cs b/Main/SimpleBackup.Core/Models/IModelFactory.cs new file mode 100644 index 0000000..542bea0 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/IModelFactory.cs @@ -0,0 +1,130 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + using System; + using System.Collections.Generic; + using System.Xml.Linq; + + /// + /// Interface of a model factory. + /// + public interface IModelFactory + { + /// + /// Creates the backup setting. + /// + /// The backup setting. + IBackupSetting CreateBackupSetting(); + + /// + /// Creates the backup setting. + /// + /// Name of the setting file. + /// The backup information collection. + /// The backup setting. + IBackupSetting CreateBackupSetting(string settingFileName, IEnumerable backupInfoCollection); + + /// + /// Creates the backup information. + /// + /// The backup inforamtion. + IBackupInfo CreateBackupInfo(); + + /// + /// Creates the backup information. + /// + /// The source backup information. + /// The backup inforamtion. + IBackupInfo CreateBackupInfo(IBackupInfo sourceBackupInfo); + + /// + /// Creates the backup information. + /// + /// The label. + /// Type of the backup source. + /// if set to true [is enabled]. + /// if set to true [is zip archive]. + /// The source path. + /// The destination folder path. + /// The backup inforamtion. + IBackupInfo CreateBackupInfo( + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath); + + /// + /// Creates the backup information. + /// + /// The identifier. + /// The label. + /// Type of the backup source. + /// if set to true [is enabled]. + /// if set to true [is zip archive]. + /// The source path. + /// The destination folder path. + /// The backup inforamtion. + IBackupInfo CreateBackupInfo( + Guid id, + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath); + + /// + /// Creates the backup information from binary. + /// + /// The binary data. + /// if set to true copy suffix is needed. + /// The backup inforamtion. + IBackupInfo CreateBackupInfoFromBinary(byte[] binaryData, bool copySuffixNeeded); + + /// + /// Creates the result information. + /// + /// The category. + /// The description. + /// The result inforamtion. + IResultInfo CreateResultInfo(BackupState category, string description); + + /// + /// Creates the destination path information. + /// + /// Type of the backup source. + /// The path. + /// The destination path information. + IDestinationPathInfo CreateDestinationPathInfo(BackupSourceType backupSourceType, string path); + + /// + /// Restores the backup setting from XML. + /// + /// The XML. + /// Name of the file. + /// The restored backup setting. + IBackupSetting RestoreBackupSettingFromXml(XElement xml, string fileName); + } +} diff --git a/Main/SimpleBackup.Core/Models/IResultInfo.cs b/Main/SimpleBackup.Core/Models/IResultInfo.cs new file mode 100644 index 0000000..5a8f163 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/IResultInfo.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + /// + /// Interface of a result information. + /// + public interface IResultInfo + { + /// + /// Gets the state of the backup. + /// + BackupState BackupState { get; } + + /// + /// Gets the description. + /// + string Description { get; } + } +} diff --git a/Main/SimpleBackup.Core/Models/ItemMovingDirection.cs b/Main/SimpleBackup.Core/Models/ItemMovingDirection.cs new file mode 100644 index 0000000..6d38734 --- /dev/null +++ b/Main/SimpleBackup.Core/Models/ItemMovingDirection.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Models +{ + /// + /// Represents item moving direction. + /// + public enum ItemMovingDirection + { + /// + /// The move up + /// + MoveUp, + + /// + /// The move down + /// + MoveDown + } +} diff --git a/Main/SimpleBackup.Core/ObjectContainer.cs b/Main/SimpleBackup.Core/ObjectContainer.cs new file mode 100644 index 0000000..3b95341 --- /dev/null +++ b/Main/SimpleBackup.Core/ObjectContainer.cs @@ -0,0 +1,92 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core +{ + using System; + using System.Collections.Generic; + using SimpleBackup.Core.Utilities; + + /// + /// The container class which contains objects with corresponding interface type. + /// + public static class ObjectContainer + { + /// + /// The object dictionary. + /// + private static readonly Dictionary ObjectDictionary = new Dictionary(); + + /// + /// The lock object. + /// + private static readonly object LockObj = new object(); + + /// + /// Registers the specified object instance. + /// + /// The type of the interface. + /// The object instance. + /// The provided object instance is null. + /// The specified type is not an interface. + public static void Register(TInterface objectInstance) + { + objectInstance.ThrowsArgumentNullException("objectInstance"); + + Type type = typeof(TInterface); + if (type.IsInterface == false) + { + throw new ArgumentException(string.Format("The specified type {0} is not an interface.", type)); + } + + lock (LockObj) + { + ObjectDictionary.Add(type, objectInstance); + } + } + + /// + /// Resolves this instance. + /// + /// The type of the interface. + /// The object instance or null. + /// The specified type is not an interface. + public static TInterface Resolve() + { + Type type = typeof(TInterface); + if (type.IsInterface == false) + { + throw new ArgumentException(string.Format("The specified type {0} is not an interface.", type)); + } + + lock (LockObj) + { + object instance; + if (ObjectDictionary.TryGetValue(type, out instance)) + { + return (TInterface)instance; + } + + return default(TInterface); + } + } + } +} diff --git a/Main/SimpleBackup.Core/Services/FileBackupProgressEventArgs.cs b/Main/SimpleBackup.Core/Services/FileBackupProgressEventArgs.cs new file mode 100644 index 0000000..92643df --- /dev/null +++ b/Main/SimpleBackup.Core/Services/FileBackupProgressEventArgs.cs @@ -0,0 +1,53 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + using SimpleBackup.Core.Models; + + /// + /// Event argument which represents file backup progress. + /// + public class FileBackupProgressEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The progress value. + /// The latest result information. + public FileBackupProgressEventArgs(double progressValue, IResultInfo latestResultInfo) + { + this.ProgressValue = progressValue; + this.LatestResultInfo = latestResultInfo; + } + + /// + /// Gets the progress value. + /// + public double ProgressValue { get; private set; } + + /// + /// Gets the latest result information. + /// + public IResultInfo LatestResultInfo { get; private set; } + } +} diff --git a/Main/SimpleBackup.Core/Services/IBackupService.cs b/Main/SimpleBackup.Core/Services/IBackupService.cs new file mode 100644 index 0000000..8479e5a --- /dev/null +++ b/Main/SimpleBackup.Core/Services/IBackupService.cs @@ -0,0 +1,62 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + using System.Threading; + using SimpleBackup.Core.Models; + + /// + /// Provides backup function. + /// + public interface IBackupService + { + /// + /// Occurs when file backup progress is updated. + /// + event EventHandler NofityFileBackupProgress; + + /// + /// Gets a value indicating whether this service is ready for backup. + /// + bool IsReadyForBackup { get; } + + /// + /// Gets a value indicating whether this service is executing backup. + /// + bool IsExecutingBackup { get; } + + /// + /// Backups multipul files. + /// + /// The cancellation token. + /// The array of result information. + void BackupMultipulFiles(CancellationToken cancellationToken, out IResultInfo[] resultInfos); + + /// + /// Backups single file. + /// + /// The backup information identifier. + /// The result information. + IResultInfo BackupSingleFile(Guid backupInfoId); + } +} diff --git a/Main/SimpleBackup.Core/Services/IBackupSettingService.cs b/Main/SimpleBackup.Core/Services/IBackupSettingService.cs new file mode 100644 index 0000000..a017bdc --- /dev/null +++ b/Main/SimpleBackup.Core/Services/IBackupSettingService.cs @@ -0,0 +1,134 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + using SimpleBackup.Core.Models; + + /// + /// Provides backup setting management function. + /// + public interface IBackupSettingService + { + /// + /// Occurs when backup setting is created. + /// + event EventHandler BackupSettingCreated; + + /// + /// Occurs when backup setting is opened. + /// + event EventHandler BackupSettingOpened; + + /// + /// Occurs when backup setting is modified. + /// + event EventHandler BackupSettingModified; + + /// + /// Occurs when backup setting is saved. + /// + event EventHandler BackupSettingSaved; + + /// + /// Occurs when backup setting is closed. + /// + event EventHandler BackupSettingClosed; + + /// + /// Gets the current setting. + /// + IBackupSetting CurrentSetting { get; } + + /// + /// Creates the backup setting. + /// + /// true if the new backup setting is created; otherwise, false. + bool CreateBackupSetting(); + + /// + /// Opens the backup setting. + /// + /// The result message. + /// + /// true if backup setting is successfully loaded; otherwise, false. + /// + bool OpenBackupSetting(out string resultMessage); + + /// + /// Opens the default backup setting. + /// + /// The result message. + /// + /// true if succeeded, otherwise; false. + /// + bool OpenDefaultBackupSetting(out string resultMessage); + + /// + /// Closes the backup setting. + /// + void CloseBackupSetting(); + + /// + /// Overwrites the currnt backup setting. + /// + /// true if the backup setting is saved; otherwise, false. + bool OverWriteCurrntBackupSetting(); + + /// + /// Saves the current backup setting as a new file. + /// + /// true if the backup setting is saved; otherwise, false. + bool SaveCurrentBackupSettingAsNewFile(); + + /// + /// Creates the backup information. + /// + /// The index. + /// The created backup information. + /// + IBackupInfo CreateBackupInfo(int index); + + /// + /// Copies the backup information. + /// + /// The source backup information. + /// The copied backup information. + /// + IBackupInfo CopyBackupInfo(IBackupInfo sourceBackupInfo); + + /// + /// Inserts the backup information. + /// + /// The index. + /// The backup information. + /// + /// + void InsertBackupInfo(int index, IBackupInfo backupInfo); + + /// + /// Removes the backup information. + /// + /// The backup information identifier. + void RemoveBackupInfo(Guid backupInfoId); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Services/IClipboardService.cs b/Main/SimpleBackup.Core/Services/IClipboardService.cs new file mode 100644 index 0000000..4a0959d --- /dev/null +++ b/Main/SimpleBackup.Core/Services/IClipboardService.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + using System.Windows; + + /// + /// Provides clip board access. + /// + public interface IClipboardService + { + /// + /// Sets the data object. + /// + /// The data object. + /// The data object is null. + void SetDataObject(IDataObject dataObject); + + /// + /// Gets the data. + /// + /// The type. + /// The format. + /// + /// The data. + /// + /// The format string is null or empty. + T GetData(string format); + + /// + /// Gets a boolean value indicating whether the clipboard data contains data in specified format. + /// + /// The format. + /// The format string is null or empty. + /// True if the specified format is contained in the Clipboard. + bool DoesClipboardDataContain(string format); + + /// + /// Clears the clipbord. + /// + void ClearClipbord(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Services/ISettingsService.cs b/Main/SimpleBackup.Core/Services/ISettingsService.cs new file mode 100644 index 0000000..317eb02 --- /dev/null +++ b/Main/SimpleBackup.Core/Services/ISettingsService.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + /// + /// Interface of a seting service. + /// + public interface ISettingsService + { + /// + /// Gets or sets the default name of the setting file. + /// + string DefaultSettingFileName { get; set; } + + /// + /// Gets or sets the default zip encoding key text. + /// + string DefaultZipEncodingKeyText { get; set; } + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Services/IUndoRedoService.cs b/Main/SimpleBackup.Core/Services/IUndoRedoService.cs new file mode 100644 index 0000000..d8982d0 --- /dev/null +++ b/Main/SimpleBackup.Core/Services/IUndoRedoService.cs @@ -0,0 +1,68 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + + /// + /// Provides undo/redo function. + /// + public interface IUndoRedoService + { + /// + /// Commits the specified redo action with related undo action and the context information. + /// + /// The redo action. + /// The undo action. + /// The context. + /// The redoAction is null. + /// The undoAction is null. + void Commit(Action redoAction, Action undoAction, object context); + + /// + /// Executes undo action. + /// + void Undo(); + + /// + /// Determines whether the undo action is executable. + /// + /// true if the undo action can be executable; otherwise, false. + bool CanExecuteUndo(); + + /// + /// Executes redo action. + /// + void Redo(); + + /// + /// Determines whether the redo action is executable. + /// + /// true if the redo action can be executable; otherwise, false. + bool CanExecuteRedo(); + + /// + /// Clears the undo redo buffer. + /// + void ClearUndoRedoBuffer(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Services/SettingFileEventArgs.cs b/Main/SimpleBackup.Core/Services/SettingFileEventArgs.cs new file mode 100644 index 0000000..5fe6f7d --- /dev/null +++ b/Main/SimpleBackup.Core/Services/SettingFileEventArgs.cs @@ -0,0 +1,49 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Services +{ + using System; + using SimpleBackup.Core.Utilities; + + /// + /// Setting file event argument + /// + public class SettingFileEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the setting. + /// The provided setting name is null. + public SettingFileEventArgs(string settingName) + { + settingName.ThrowsArgumentNullException("settingName"); + + this.SettingName = settingName; + } + + /// + /// Gets the name of the setting. + /// + public string SettingName { get; private set; } + } +} diff --git a/Main/SimpleBackup.Core/SimpleBackup.Core.csproj b/Main/SimpleBackup.Core/SimpleBackup.Core.csproj new file mode 100644 index 0000000..6c0cc5f --- /dev/null +++ b/Main/SimpleBackup.Core/SimpleBackup.Core.csproj @@ -0,0 +1,115 @@ + + + + + Debug + AnyCPU + {33F1D454-9962-4EB6-AAD3-8D11D9A78D1F} + Library + Properties + SimpleBackup.Core + SimpleBackup.Core + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + + + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Core/SimpleBackupKey.snk b/Main/SimpleBackup.Core/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.Core/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.Core/Utilities/Constants.cs b/Main/SimpleBackup.Core/Utilities/Constants.cs new file mode 100644 index 0000000..0010eb8 --- /dev/null +++ b/Main/SimpleBackup.Core/Utilities/Constants.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Utilities +{ + using System.Text.RegularExpressions; + + /// + /// Defines constants + /// + public static class Constants + { + /// + /// The backup information clipboard format: "BackupInfoClipboardFormat" + /// + public const string BackupInfoClipboardFormat = "BackupInfoClipboardFormat"; + + /// + /// The end path segment regex: "[^\\]*$" + /// + public static readonly Regex EndPathSegmentRegex = new Regex(@"[^\\]*$", RegexOptions.Compiled); + + /// + /// The end path separator regex: "\\$" + /// + public static readonly Regex EndPathSeparatorRegex = new Regex(@"\\$", RegexOptions.Compiled); + + /// + /// The file name regex: "^.*(?=\.)" + /// + public static readonly Regex FileNameRegex = new Regex(@"^.*(?=\.)", RegexOptions.Compiled); + + /// + /// The extension regex: "[^\.]*$" + /// + public static readonly Regex ExtensionRegex = new Regex(@"[^\.]*$", RegexOptions.Compiled); + } +} diff --git a/Main/SimpleBackup.Core/Utilities/HelperExtensions.cs b/Main/SimpleBackup.Core/Utilities/HelperExtensions.cs new file mode 100644 index 0000000..52b3f21 --- /dev/null +++ b/Main/SimpleBackup.Core/Utilities/HelperExtensions.cs @@ -0,0 +1,214 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Utilities +{ + using System; + using System.IO; + using System.Windows; + using System.Windows.Media; + using SimpleBackup.Core.Models; + using SimpleBackup.Resources; + + /// + /// Defines helper extension methods. + /// + public static class HelperExtensions + { + /// + /// Throwses the argument null exception. + /// + /// The source. + /// Name of the parameter. + /// The argument is null. + public static void ThrowsArgumentNullException(this object source, string parameterName) + { + if (source == null) + { + throw new ArgumentNullException(parameterName); + } + } + + public static void ThrowsArgumentExceptionIfNullOrEmpty(this string source, string parameterName) + { + if (string.IsNullOrEmpty(source)) + { + throw new ArgumentException("provided text is null or empty.", parameterName); + } + } + + public static T SearchUpParentWithSelf(this DependencyObject source) + where T : DependencyObject + { + if (source == null) + { + return null; + } + + if (source is T) + { + return (T)source; + } + + DependencyObject parent = VisualTreeHelper.GetParent(source); + while (true) + { + parent = VisualTreeHelper.GetParent(parent); + if ((parent == null) || (parent is Window)) + { + return null; + } + + if (parent is T) + { + return (T)parent; + } + } + } + + public static T GetVisualChild(this Visual source) where T : Visual + { + T targetChild = default(T); + int childrenCount = VisualTreeHelper.GetChildrenCount(source); + for (int i = 0; i < childrenCount; i++) + { + var childVisual = (Visual)VisualTreeHelper.GetChild(source, i); + targetChild = childVisual as T ?? GetVisualChild(childVisual); + if (targetChild != null) + { + break; + } + } + + return targetChild; + } + + public static object GetVisualChild(this Visual source, Type targeType) + { + object targetChild = null; + int childrenCount = VisualTreeHelper.GetChildrenCount(source); + for (int i = 0; i < childrenCount; i++) + { + var childVisual = (Visual)VisualTreeHelper.GetChild(source, i); + if (childVisual.GetType() == targeType) + { + targetChild = childVisual; + break; + } + + targetChild = GetVisualChild(childVisual, targeType); + } + + return targetChild; + } + + public static bool IsValidFileOrDirectoryPath(this string pathText) + { + if (string.IsNullOrWhiteSpace(pathText)) + { + return false; + } + + return File.Exists(pathText) || Directory.Exists(pathText); + } + + public static bool IsValidFilePath(this string pathText) + { + if (string.IsNullOrWhiteSpace(pathText)) + { + return false; + } + + return File.Exists(pathText); + } + + public static bool IsValidDirectoryPath(this string pathText) + { + if (string.IsNullOrWhiteSpace(pathText)) + { + return false; + } + + return Directory.Exists(pathText); + } + + public static bool IsExistingFileOrDirectoryPath(this string pathText) + { + if (string.IsNullOrWhiteSpace(pathText)) + { + return false; + } + + if (File.Exists(pathText)) + { + return true; + } + + if (Directory.Exists(pathText)) + { + return true; + } + + return false; + } + + public static string AddTailPathSeparatorIfNotExist(this string text) + { + if (string.IsNullOrWhiteSpace(text)) + { + return text; + } + + if (text.EndsWith("\\") == false) + { + return text + "\\"; + } + + return text; + } + + /// + /// Translates the specified backup state. + /// + /// State of the backup. + /// The translated text. + public static string Translate(this BackupState backupState) + { + switch (backupState) + { + case BackupState.Todo: + return Resources.BackupState_Todo; + case BackupState.InProgress: + return Resources.BackupState_InProgress; + case BackupState.Success: + return Resources.BackupState_Success; + case BackupState.Failed: + return Resources.BackupState_Failed; + case BackupState.Cancelled: + return Resources.BackupState_Cancelled; + case BackupState.Skipped: + return Resources.BackupState_Skipped; + default: + return string.Empty; + } + } + } +} diff --git a/Main/SimpleBackup.Core/Utilities/Helpers.cs b/Main/SimpleBackup.Core/Utilities/Helpers.cs new file mode 100644 index 0000000..6113b0b --- /dev/null +++ b/Main/SimpleBackup.Core/Utilities/Helpers.cs @@ -0,0 +1,167 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Utilities +{ + using System.Diagnostics; + using System.Globalization; + using System.IO; + using System.Windows; + using System.Windows.Threading; + + /// + /// Defines helper methods. + /// + public static class Helpers + { + #region WPF + + public static void UpdateWpfGui() + { + var frame = new DispatcherFrame(); + var callback = new DispatcherOperationCallback(obj => + { + ((DispatcherFrame)obj).Continue = false; + return null; + }); + Application.Current.Dispatcher.BeginInvoke(DispatcherPriority.Background, callback, frame); + Dispatcher.PushFrame(frame); + } + + #endregion + + #region Files and directories + + public static bool TryExtractValidFolderPath(string sourcePath, out string extractedPath) + { + extractedPath = string.Empty; + + if (string.IsNullOrEmpty(sourcePath)) + { + return false; + } + + string testPath = sourcePath; + while (true) + { + if (Directory.Exists(testPath)) + { + extractedPath = testPath; + return true; + } + + testPath = Path.GetDirectoryName(testPath); + if (string.IsNullOrEmpty(testPath)) + { + break; + } + } + + return false; + } + + /// + /// Creates the display path text. + /// + /// The full path. + /// The display path text. + public static string CreateDisplayPathText(string fullPath) + { + if (string.IsNullOrWhiteSpace(fullPath)) + { + return string.Empty; + } + + string fileName = Path.GetFileName(fullPath); + string directoryName = Path.GetDirectoryName(fullPath); + + return string.Format(CultureInfo.CurrentCulture, "{0} ({1})", fileName, directoryName); + } + + public static void OpenFolder(string path) + { + if (string.IsNullOrWhiteSpace(path)) + { + MessageBox.Show( + string.Format(SimpleBackup.Resources.Resources.FileAccess_InvalidPathFormat, path)); + return; + } + + if (Directory.Exists(path)) + { + Process.Start("explorer.exe", string.Format("/n, /e, {0}", path)); + } + else + { + MessageBox.Show( + string.Format(Resources.Resources.FileAccess_FolderPathNotExistFormat, path)); + } + } + + /// + /// Opens the parent folder and select the specified file or folder. + /// + /// The path. + public static void OpenParentFolderAndSelect(string path) + { + if (path.IsExistingFileOrDirectoryPath() == false) + { + MessageBox.Show( + string.Format(Resources.Resources.FileAccess_InvalidPathFormat, path)); + return; + } + + Process.Start("explorer.exe", string.Format("/n, /e, /select,{0}", path)); + } + + /// + /// Opens the file. + /// + /// Name of the file. + public static void OpenFile(string fileName) + { + if (fileName.IsExistingFileOrDirectoryPath() == false) + { + MessageBox.Show( + string.Format(Resources.Resources.FileAccess_InvalidPathFormat, fileName)); + return; + } + + var processStartInfo = new ProcessStartInfo + { + FileName = fileName, + UseShellExecute = true + }; + + try + { + Process.Start(processStartInfo); + } + catch + { + MessageBox.Show( + string.Format(Resources.Resources.FileAccess_FailedToOpenFormat, fileName)); + } + } + + #endregion + } +} diff --git a/Main/SimpleBackup.Core/Utilities/IdIndexPair.cs b/Main/SimpleBackup.Core/Utilities/IdIndexPair.cs new file mode 100644 index 0000000..f8c41d8 --- /dev/null +++ b/Main/SimpleBackup.Core/Utilities/IdIndexPair.cs @@ -0,0 +1,64 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Utilities +{ + using System; + + /// + /// A pair of Guid and index. + /// + public class IdIndexPair + { + /// + /// Initializes a new instance of the class. + /// + /// The identifier. + /// The index. + /// The provided GUID is zero. + /// The provided index is a minus value. + public IdIndexPair(Guid id, int index) + { + if (id == default(Guid)) + { + throw new ArgumentException("The provided GUID is zero.", "id"); + } + + if (index < 0) + { + throw new ArgumentException("The provided index is a minus value.", "index"); + } + + this.Id = id; + this.Index = index; + } + + /// + /// Gets the identifier. + /// + public Guid Id { get; private set; } + + /// + /// Gets the index. + /// + public int Index { get; private set; } + } +} diff --git a/Main/SimpleBackup.Core/Utilities/PropertyChangeNotificationBase.cs b/Main/SimpleBackup.Core/Utilities/PropertyChangeNotificationBase.cs new file mode 100644 index 0000000..e52dba1 --- /dev/null +++ b/Main/SimpleBackup.Core/Utilities/PropertyChangeNotificationBase.cs @@ -0,0 +1,48 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Utilities +{ + using System.ComponentModel; + + /// + /// Base class of classes which implement INotifyPropertyChanged. + /// + public abstract class PropertyChangeNotificationBase : INotifyPropertyChanged + { + /// + /// Occurs when a property value changes. + /// + public event PropertyChangedEventHandler PropertyChanged; + + /// + /// Notifies the property changed. + /// + /// Name of the property. + protected void NotifyPropertyChanged(string propertyName) + { + if (this.PropertyChanged != null) + { + this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); + } + } + } +} diff --git a/Main/SimpleBackup.Core/ViewModels/BackupInfoPathType.cs b/Main/SimpleBackup.Core/ViewModels/BackupInfoPathType.cs new file mode 100644 index 0000000..6a0c229 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/BackupInfoPathType.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Represents backup information path type. + /// + public enum BackupInfoPathType + { + /// + /// The source + /// + Source, + + /// + /// The destination + /// + Destination + } +} diff --git a/Main/SimpleBackup.Core/ViewModels/FocusOnGridRowEventArgs.cs b/Main/SimpleBackup.Core/ViewModels/FocusOnGridRowEventArgs.cs new file mode 100644 index 0000000..da66a8b --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/FocusOnGridRowEventArgs.cs @@ -0,0 +1,51 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + using System; + + /// + /// Event argument of FocusOnGridRow event. + /// + public class FocusOnGridRowEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// The index. + /// The provided index is out of the range. + public FocusOnGridRowEventArgs(int index) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + this.Index = index; + } + + /// + /// Gets the index. + /// + public int Index { get; private set; } + } +} diff --git a/Main/SimpleBackup.Core/ViewModels/IBackupInfoViewModel.cs b/Main/SimpleBackup.Core/ViewModels/IBackupInfoViewModel.cs new file mode 100644 index 0000000..bc72ce8 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/IBackupInfoViewModel.cs @@ -0,0 +1,123 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + using System; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Views; + + /// + /// The interface of backup information view model. + /// + public interface IBackupInfoViewModel + { + /// + /// Gets the open source file relay command. + /// + RelayCommand OpenSourceFileRelayCommand { get; } + + /// + /// Gets the open source folder relay command. + /// + RelayCommand OpenSourceFolderRelayCommand { get; } + + /// + /// Gets the select source relay command. + /// + RelayCommand SelectSourceRelayCommand { get; } + + /// + /// Gets the open destination folder relay command. + /// + RelayCommand OpenDestinationFolderRelayCommand { get; } + + /// + /// Gets the select destination relay command. + /// + RelayCommand SelectDestinationRelayCommand { get; } + + /// + /// Gets the edit source relay command. + /// + RelayCommand EditSourceRelayCommand { get; } + + /// + /// Gets the edit destination relay command. + /// + RelayCommand EditDestinationRelayCommand { get; } + + /// + /// Gets the single backup with context menu relay command. + /// + RelayCommand SingleBackupRelayCommand { get; } + + Guid BackupInfoId { get; } + + BackupSourceType SourceType { get; } + + BackupState BackupState { get; } + + bool IsEnabled { get; set; } + + bool IsZipArchive { get; set; } + + string Label { get; set; } + + string SourcePath { get; set; } + + string DisplaySourcePath { get; } + + string EditingSourcePath { get; set; } + + string SourceToolTipText { get; } + + bool IsSourceEditing { get; set; } + + bool HasSourcePathError { get; } + + string DestinationFolderPath { get; set; } + + string DisplayDestinationFolderPath { get; } + + string EditingDestinationPath { get; set; } + + string DestinationToolTipText { get; } + + bool IsDestinationEditing { get; set; } + + bool HasDestinationFolderPathError { get; } + + bool IsEditing { get; } + + bool IsCutReserved { get; set; } + + IBackupInfo GetBackupInfo(); + + void ExecuteDoubleClickAction(BackupInfoPathType pathType); + + void SingleBackup(); + + void CommitEditingContents(); + + void ResetBackupState(); + } +} diff --git a/Main/SimpleBackup.Core/ViewModels/IDestinationColumnHeaderViewModel.cs b/Main/SimpleBackup.Core/ViewModels/IDestinationColumnHeaderViewModel.cs new file mode 100644 index 0000000..20b4562 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/IDestinationColumnHeaderViewModel.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Interface of a destination column header view model. + /// + public interface IDestinationColumnHeaderViewModel + { + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/ViewModels/ILabelColumnHeaderViewModel.cs b/Main/SimpleBackup.Core/ViewModels/ILabelColumnHeaderViewModel.cs new file mode 100644 index 0000000..bba6949 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/ILabelColumnHeaderViewModel.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Interface of a label column header view model. + /// + public interface ILabelColumnHeaderViewModel + { + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/ViewModels/IMainWindowViewModel.cs b/Main/SimpleBackup.Core/ViewModels/IMainWindowViewModel.cs new file mode 100644 index 0000000..2582e60 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/IMainWindowViewModel.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + using System; + using SimpleBackup.Core.Views; + + /// + /// Interface of a main window view model. + /// + public interface IMainWindowViewModel : IDisposable + { + /// + /// Occurs when the focus is set on the Grid. + /// + event EventHandler FocusOnGrid; + + /// + /// Occurs when the focus is set on a Grid row. + /// + event EventHandler FocusOnGridRow; + + /// + /// Gets the save backup setting relay command. + /// + RelayCommand SaveBackupSettingRelayCommand { get; } + + /// + /// Called when Escape key is pressed. + /// + void OnEscKeyPressed(); + } +} diff --git a/Main/SimpleBackup.Core/ViewModels/ISourceColumnHeaderViewModel.cs b/Main/SimpleBackup.Core/ViewModels/ISourceColumnHeaderViewModel.cs new file mode 100644 index 0000000..c1315ce --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/ISourceColumnHeaderViewModel.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Interface of a source column header view model. + /// + public interface ISourceColumnHeaderViewModel + { + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/ViewModels/IViewModelFactory.cs b/Main/SimpleBackup.Core/ViewModels/IViewModelFactory.cs new file mode 100644 index 0000000..0b2d8dd --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/IViewModelFactory.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Interface of a view model factory. + /// + public interface IViewModelFactory + { + /// + /// Creates the main window view model. + /// + /// The main window view model. + IMainWindowViewModel CreateMainWindowViewModel(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/ViewModels/PasteType.cs b/Main/SimpleBackup.Core/ViewModels/PasteType.cs new file mode 100644 index 0000000..c3c8ec3 --- /dev/null +++ b/Main/SimpleBackup.Core/ViewModels/PasteType.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.ViewModels +{ + /// + /// Paste operation type. + /// + public enum PasteType + { + /// + /// The copy + /// + Copy, + + /// + /// The cut + /// + Cut + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Views/ExDataGridSelectedFirstCellItemChangedEventArgs.cs b/Main/SimpleBackup.Core/Views/ExDataGridSelectedFirstCellItemChangedEventArgs.cs new file mode 100644 index 0000000..3dc8ad6 --- /dev/null +++ b/Main/SimpleBackup.Core/Views/ExDataGridSelectedFirstCellItemChangedEventArgs.cs @@ -0,0 +1,54 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + using System; + + /// + /// Event argument of ExDataGrid's SelectedFirstCellItemChangedEvent event. + /// + public class ExDataGridSelectedFirstCellItemChangedEventArgs : EventArgs + { + /// + /// Initializes a new instance of the class. + /// + /// Index of the selected first cell item. + /// The selected first cell item. + public ExDataGridSelectedFirstCellItemChangedEventArgs( + int selectedFirstCellItemIndex, + object selectedFirstCellItem) + { + this.SelectedFirstCellItemIndex = selectedFirstCellItemIndex; + this.SelectedFirstCellItem = selectedFirstCellItem; + } + + /// + /// Gets the index of the selected first cell item. + /// + public int SelectedFirstCellItemIndex { get; private set; } + + /// + /// Gets the selected first cell item. + /// + public object SelectedFirstCellItem { get; private set; } + } +} diff --git a/Main/SimpleBackup.Core/Views/IFileFolderDialog.cs b/Main/SimpleBackup.Core/Views/IFileFolderDialog.cs new file mode 100644 index 0000000..3709604 --- /dev/null +++ b/Main/SimpleBackup.Core/Views/IFileFolderDialog.cs @@ -0,0 +1,42 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + using System.Windows.Forms; + + /// + /// Interface of a file folder dialog. + /// + public interface IFileFolderDialog + { + /// + /// Gets or sets the selected path. + /// + string SelectedPath { get; set; } + + /// + /// Shows the dialog. + /// + /// The dialog result. + DialogResult ShowDialog(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Views/IMainWindow.cs b/Main/SimpleBackup.Core/Views/IMainWindow.cs new file mode 100644 index 0000000..70568e1 --- /dev/null +++ b/Main/SimpleBackup.Core/Views/IMainWindow.cs @@ -0,0 +1,39 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + /// + /// Interface of a main window. + /// + public interface IMainWindow + { + /// + /// Gets or sets the data context. + /// + object DataContext { get; set; } + + /// + /// Shows the window. + /// + void Show(); + } +} diff --git a/Main/SimpleBackup.Core/Views/IVersionInformationWindow.cs b/Main/SimpleBackup.Core/Views/IVersionInformationWindow.cs new file mode 100644 index 0000000..ffc9bc1 --- /dev/null +++ b/Main/SimpleBackup.Core/Views/IVersionInformationWindow.cs @@ -0,0 +1,35 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + /// + /// Interface of a version information window. + /// + public interface IVersionInformationWindow + { + /// + /// Shows the dialog window. + /// + /// The result. + bool? ShowDialogWindow(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Views/IViewFactory.cs b/Main/SimpleBackup.Core/Views/IViewFactory.cs new file mode 100644 index 0000000..d050f1d --- /dev/null +++ b/Main/SimpleBackup.Core/Views/IViewFactory.cs @@ -0,0 +1,47 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + /// + /// Interface of a view factory. + /// + public interface IViewFactory + { + /// + /// Creates the main window. + /// + /// The main window. + IMainWindow CreateMainWindow(); + + /// + /// Creates the version information window. + /// + /// The version information window. + IVersionInformationWindow CreateVersionInformationWindow(); + + /// + /// Creates the file folder dialog. + /// + /// The file folder dialog. + IFileFolderDialog CreateFileFolderDialog(); + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Core/Views/RelayCommand.cs b/Main/SimpleBackup.Core/Views/RelayCommand.cs new file mode 100644 index 0000000..ad29dc2 --- /dev/null +++ b/Main/SimpleBackup.Core/Views/RelayCommand.cs @@ -0,0 +1,105 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Core.Views +{ + using System; + using System.Diagnostics; + using System.Windows.Input; + using SimpleBackup.Core.Utilities; + + /// + /// A relay command for WPF MVVM pattern. + /// See WPF Apps With The Model-View-ViewModel Design Pattern http://msdn.microsoft.com/en-us/magazine/dd419663.aspx#id0090030 + /// in MSDN Magazine > Issues and Downloads > 2009 > February. + /// + public class RelayCommand : ICommand + { + /// + /// The execute action + /// + private readonly Action executeAction; + + /// + /// The can execute predicate + /// + private readonly Predicate canExecutePredicate; + + /// + /// Initializes a new instance of the class. + /// + /// The execute action. + public RelayCommand(Action executeAction) + : this(executeAction, null) + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The execute action. + /// The can execute predicate. + /// executeAction is null. + public RelayCommand(Action executeAction, Predicate canExecutePredicate) + { + executeAction.ThrowsArgumentNullException("executeAction"); + + this.executeAction = executeAction; + this.canExecutePredicate = canExecutePredicate; + } + + /// + /// Occurs when changes occur that affect whether or not the command should execute. + /// + public event EventHandler CanExecuteChanged + { + add + { + CommandManager.RequerySuggested += value; + } + + remove + { + CommandManager.RequerySuggested -= value; + } + } + + /// + /// Defines the method to be called when the command is invoked. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + public void Execute(object parameter) + { + this.executeAction(parameter); + } + + /// + /// Defines the method that determines whether the command can execute in its current state. + /// + /// Data used by the command. If the command does not require data to be passed, this object can be set to null. + /// true if this command can be executed; otherwise, false. + [DebuggerStepThrough] + public bool CanExecute(object parameter) + { + return this.canExecutePredicate == null || this.canExecutePredicate(parameter); + } + } +} \ No newline at end of file diff --git a/Main/SimpleBackup.Models/BackupInfo.cs b/Main/SimpleBackup.Models/BackupInfo.cs new file mode 100644 index 0000000..6b85734 --- /dev/null +++ b/Main/SimpleBackup.Models/BackupInfo.cs @@ -0,0 +1,464 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using System; + using System.IO; + using System.Xml.Linq; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Utilities; + using Resources = SimpleBackup.Resources.Resources; + + /// + /// A model of single backup information. + /// + internal class BackupInfo : PropertyChangeNotificationBase, IBackupInfo + { + private Guid innerId = Guid.NewGuid(); + private string innerLabel = string.Empty; + private BackupSourceType innerBackupSourceType = BackupSourceType.File; + private bool innerIsEnabled = true; + private bool innerIsZipArchive; + private string innerSourcePath = string.Empty; + private string innerDestinationFolderPath = string.Empty; + private BackupState innerBackupState = BackupState.Todo; + + /// + /// Initializes a new instance of the class. + /// + internal BackupInfo() + { + } + + /// + /// Initializes a new instance of the class. + /// + /// The source backup information. + /// The index is out of range. + internal BackupInfo(IBackupInfo sourceBackupInfo) + { + sourceBackupInfo.ThrowsArgumentNullException("sourceBackupInfo"); + + this.Id = Guid.NewGuid(); + this.BackupState = BackupState.Todo; + + this.Label = sourceBackupInfo.Label; + this.BackupSourceType = sourceBackupInfo.BackupSourceType; + this.IsEnabled = sourceBackupInfo.IsEnabled; + this.IsZipArchive = sourceBackupInfo.IsZipArchive; + this.SourcePath = sourceBackupInfo.SourcePath; + this.DestinationFolderPath = sourceBackupInfo.DestinationFolderPath; + } + + /// + /// Initializes a new instance of the class. + /// + /// The label. + /// Type of the backup source. + /// if set to true the backup is enabled. + /// if set to true zip archive switch is on. + /// The source path. + /// The destination folder path. + /// The label is null. + /// The source path is null. + /// The destination folder path is null. + internal BackupInfo( + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath) + { + label.ThrowsArgumentNullException("label"); + sourcePath.ThrowsArgumentNullException("sourcePath"); + destinationFolderPath.ThrowsArgumentNullException("destinationFolderPath"); + + this.Id = Guid.NewGuid(); + this.BackupState = BackupState.Todo; + + this.Label = label; + this.BackupSourceType = backupSourceType; + this.IsEnabled = isEnabled; + this.IsZipArchive = isZipArchive; + this.SourcePath = sourcePath; + this.DestinationFolderPath = destinationFolderPath; + } + + /// + /// Initializes a new instance of the class. + /// + /// The identifier. + /// The label. + /// Type of the backup source. + /// if set to true the backup is enabled. + /// if set to true zip archive switch is on. + /// The source path. + /// The destination folder path. + /// The label is null. + /// The label is null. + /// The label is null. + internal BackupInfo( + Guid id, + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath) + { + label.ThrowsArgumentNullException("label"); + sourcePath.ThrowsArgumentNullException("sourcePath"); + destinationFolderPath.ThrowsArgumentNullException("destinationFolderPath"); + + this.Id = id; + this.BackupState = BackupState.Todo; + + this.Label = label; + this.BackupSourceType = backupSourceType; + this.IsEnabled = isEnabled; + this.IsZipArchive = isZipArchive; + this.SourcePath = sourcePath; + this.DestinationFolderPath = destinationFolderPath; + } + + /// + /// Occurs when a property which has to be saved in setting file is changed. + /// + public event EventHandler SettingFilePropertyChanged; + + /// + /// Gets or sets the identifier. + /// + public Guid Id + { + get + { + return this.innerId; + } + + set + { + if (this.innerId != value) + { + this.innerId = value; + this.NotifyPropertyChanged("Id"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets the label. + /// + public string Label + { + get + { + return this.innerLabel; + } + + set + { + if (this.innerLabel != value) + { + this.innerLabel = value; + this.NotifyPropertyChanged("Label"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets the type of the backup source. + /// + public BackupSourceType BackupSourceType + { + get + { + return this.innerBackupSourceType; + } + + set + { + if (this.innerBackupSourceType != value) + { + this.innerBackupSourceType = value; + this.NotifyPropertyChanged("BackupSourceType"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets a value indicating whether the backup is enabled. + /// + public bool IsEnabled + { + get + { + return this.innerIsEnabled; + } + + set + { + if (this.innerIsEnabled != value) + { + this.innerIsEnabled = value; + this.NotifyPropertyChanged("IsEnabled"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets a value indicating whether the backup is zip archive. + /// + public bool IsZipArchive + { + get + { + return this.innerIsZipArchive; + } + + set + { + if (this.innerIsZipArchive != value) + { + this.innerIsZipArchive = value; + this.NotifyPropertyChanged("IsZipArchive"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets the source path. + /// + public string SourcePath + { + get + { + return this.innerSourcePath; + } + + set + { + if (this.innerSourcePath != value) + { + this.innerSourcePath = value; + this.NotifyPropertyChanged("SourcePath"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets the destination folder path. + /// + public string DestinationFolderPath + { + get + { + return this.innerDestinationFolderPath; + } + + set + { + if (this.innerDestinationFolderPath != value) + { + this.innerDestinationFolderPath = value; + this.NotifyPropertyChanged("DestinationFolderPath"); + this.NotifySettingFilePropertyChanged(); + } + } + } + + /// + /// Gets or sets the state of the backup. + /// + public BackupState BackupState + { + get + { + return this.innerBackupState; + } + + set + { + if (this.innerBackupState != value) + { + this.innerBackupState = value; + this.NotifyPropertyChanged("BackupState"); + } + } + } + + /// + /// Gets or sets the name of the latest successful backup target. + /// + public string LatestSuccessfulBackupTargetName { get; set; } + + /// + /// Creates the backup information. + /// + /// The backup information. + public static IBackupInfo CreateBackupInfo() + { + return new BackupInfo(); + } + + /// + /// Creates the backup information. + /// + /// The source backup information. + /// The backup information. + public static IBackupInfo CreateBackupInfo(IBackupInfo sourceBackupInfo) + { + return new BackupInfo(sourceBackupInfo); + } + + /// + /// Creates the backup information. + /// + /// The identifier. + /// The label. + /// Type of the backup source. + /// if set to true [is enabled]. + /// if set to true [is zip archive]. + /// The source path. + /// The destination folder path. + /// The backup information. + public static IBackupInfo CreateBackupInfo( + Guid id, + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath) + { + return new BackupInfo( + id, + label, + backupSourceType, + isEnabled, + isZipArchive, + sourcePath, + destinationFolderPath); + } + + /// + /// Restores from binary. + /// + /// The binary data. + /// if set to true [copy suffix needed]. + /// The restored backup information. + public static IBackupInfo FromBinary(byte[] binaryData, bool copySuffixNeeded) + { + var memoryStream = new MemoryStream(binaryData); + using (var binaryReader = new BinaryReader(memoryStream)) + { + string label = binaryReader.ReadString(); + var backupSourceType = (BackupSourceType)Enum.ToObject(typeof(BackupSourceType), binaryReader.ReadInt32()); + bool isEnabled = binaryReader.ReadBoolean(); + bool isZipArchive = binaryReader.ReadBoolean(); + string sourcePath = binaryReader.ReadString(); + string destinationFolderPath = binaryReader.ReadString(); + + return new BackupInfo( + copySuffixNeeded ? string.Format("{0} - {1}", label, Resources.Edit_CopySuffix) : label, + backupSourceType, + isEnabled, + isZipArchive, + sourcePath, + destinationFolderPath); + } + } + + /// + /// Saves this instance to a XElement. + /// + /// The generated XElement. + public XElement ToXml() + { + var element = new XElement("BackupInfo"); + element.Add(new XElement("Id", this.Id)); + element.Add(new XElement("Label", this.Label)); + element.Add(new XElement("BackupSourceType", this.BackupSourceType)); + element.Add(new XElement("IsEnabled", this.IsEnabled)); + element.Add(new XElement("IsZipArchive", this.IsZipArchive)); + element.Add(new XElement("SourcePath", this.SourcePath)); + element.Add(new XElement("DestinationFolderPath", this.DestinationFolderPath)); + + return element; + } + + /// + /// Gets the binary representation of this instance. + /// + /// The binary representation of this instance. + public byte[] ToBinary() + { + var memoryStream = new MemoryStream(); + using (var binaryWriter = new BinaryWriter(memoryStream)) + { + binaryWriter.Write(this.Label); + binaryWriter.Write((int)this.BackupSourceType); + binaryWriter.Write(this.IsEnabled); + binaryWriter.Write(this.IsZipArchive); + binaryWriter.Write(this.SourcePath); + binaryWriter.Write(this.DestinationFolderPath); + + memoryStream.Flush(); + return memoryStream.GetBuffer(); + } + } + + /// + /// Gets the text representation of this instance. + /// + /// The text representation of this instance. + public string ToFormattedText() + { + return string.Format( + "{0}\t{1}\t{2}\t{3}\t{4}\t{5}", + this.Label, + this.BackupSourceType, + this.IsEnabled, + this.IsZipArchive, + this.SourcePath, + this.DestinationFolderPath); + } + + /// + /// Notifies the setting file property is changed. + /// + private void NotifySettingFilePropertyChanged() + { + if (this.SettingFilePropertyChanged != null) + { + this.SettingFilePropertyChanged(this, new EventArgs()); + } + } + } +} diff --git a/Main/SimpleBackup.Models/BackupSetting.cs b/Main/SimpleBackup.Models/BackupSetting.cs new file mode 100644 index 0000000..93c7fa8 --- /dev/null +++ b/Main/SimpleBackup.Models/BackupSetting.cs @@ -0,0 +1,246 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Xml.Linq; + using SimpleBackup.Core.Models; + + /// + /// Represents a backup setting. + /// + internal class BackupSetting : IBackupSetting + { + private readonly List backupInfoList = new List(); + + /// + /// Initializes a new instance of the class. + /// + internal BackupSetting() + { + this.SettingFileName = string.Empty; + this.Modified = true; + } + + /// + /// Initializes a new instance of the class. + /// + /// Name of the setting file. + /// The backup information collection. + internal BackupSetting( + string settingFileName, + IEnumerable backupInfoCollection) + { + this.SettingFileName = settingFileName; + this.backupInfoList.AddRange(backupInfoCollection); + foreach (IBackupInfo backupInfo in this.backupInfoList) + { + backupInfo.SettingFilePropertyChanged += this.OnBackupInfoSettingFilePropertyChanged; + } + } + + /// + /// Occurs when backup setting is modified. + /// + public event EventHandler SettingModified; + + /// + /// Gets the name of the setting. + /// + public string SettingName + { + get + { + if (string.IsNullOrEmpty(this.SettingFileName)) + { + return Resources.Resources.Views_NewBackupSettingName; + } + + return this.SettingFileName; + } + } + + /// + /// Gets or sets the name of the setting file. + /// + public string SettingFileName { get; set; } + + /// + /// Gets or sets a value indicating whether this is modified. + /// + public bool Modified { get; set; } + + /// + /// Gets the backup infos. + /// + public IReadOnlyCollection BackupInfos + { + get + { + return this.backupInfoList.AsReadOnly(); + } + } + + /// + /// Gets the count. + /// + public int Count + { + get + { + return this.backupInfoList.Count; + } + } + + /// + /// Creates the backup setting. + /// + /// The backup setting. + public static IBackupSetting CreateBackupSetting() + { + return new BackupSetting(); + } + + /// + /// Creates the backup setting. + /// + /// Name of the setting file. + /// The backup information collection. + /// The backup setting. +// public static IBackupSetting CreateBackupSetting( +// string settingFileName, +// IEnumerable backupInfoCollection) +// { +// return new BackupSetting(settingFileName, backupInfoCollection); +// } + + /// + /// Inserts the specified index. + /// + /// The index. + /// The backup information. + public void Insert(int index, IBackupInfo backupInfo) + { + backupInfo.SettingFilePropertyChanged += this.OnBackupInfoSettingFilePropertyChanged; + this.backupInfoList.Insert(index, backupInfo); + + this.MarkAsModifiedAndPublishNotification(); + } + + /// + /// Removes the specified removing backup information. + /// + /// The removing backup information. + public void Remove(IBackupInfo removingBackupInfo) + { + removingBackupInfo.SettingFilePropertyChanged -= this.OnBackupInfoSettingFilePropertyChanged; + this.backupInfoList.Remove(removingBackupInfo); + + this.MarkAsModifiedAndPublishNotification(); + } + + public IBackupInfo FirstOrDefault(Guid id) + { + return this.backupInfoList.FirstOrDefault(p => p.Id == id); + } + + public void MoveItem(Guid backupInfoId, ItemMovingDirection movingDirection) + { + IBackupInfo movingBackupInfo = null; + int currentIndex = 0; + for (int i = 0; i < this.backupInfoList.Count; i++) + { + if (this.backupInfoList[i].Id == backupInfoId) + { + currentIndex = i; + movingBackupInfo = this.backupInfoList[i]; + break; + } + } + + if (movingBackupInfo != null) + { + int newIndex = -1; + switch (movingDirection) + { + case ItemMovingDirection.MoveUp: + if (currentIndex > 0) + { + newIndex = currentIndex - 1; + } + + break; + case ItemMovingDirection.MoveDown: + if (currentIndex < this.backupInfoList.Count - 1) + { + newIndex = currentIndex + 1; + } + + break; + default: + throw new InvalidOperationException("Not supported direction."); + } + + if (newIndex != -1) + { + IBackupInfo temp = this.backupInfoList[newIndex]; + this.backupInfoList[newIndex] = this.backupInfoList[currentIndex]; + this.backupInfoList[currentIndex] = temp; + } + + this.MarkAsModifiedAndPublishNotification(); + } + } + + public XElement ToXml() + { + var backupSettingElement = new XElement("BackupSetting"); + backupSettingElement.SetAttributeValue("Version", "1.0"); + backupSettingElement.SetAttributeValue("RequiredToolVersion", "1.0.0.181"); + + var items = new XElement("Items"); + foreach (IBackupInfo backupInfo in this.BackupInfos) + { + items.Add(backupInfo.ToXml()); + } + + backupSettingElement.Add(items); + return backupSettingElement; + } + + private void OnBackupInfoSettingFilePropertyChanged(object sender, EventArgs e) + { + this.MarkAsModifiedAndPublishNotification(); + } + + private void MarkAsModifiedAndPublishNotification() + { + this.Modified = true; + if (this.SettingModified != null) + { + this.SettingModified(this, new EventArgs()); + } + } + } +} diff --git a/Main/SimpleBackup.Models/DestinationPathInfo.cs b/Main/SimpleBackup.Models/DestinationPathInfo.cs new file mode 100644 index 0000000..d54f65a --- /dev/null +++ b/Main/SimpleBackup.Models/DestinationPathInfo.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using SimpleBackup.Core.Models; + + /// + /// The destination path information. + /// + internal class DestinationPathInfo : IDestinationPathInfo + { + /// + /// Initializes a new instance of the class. + /// + /// Type of the backup source. + /// The path. + public DestinationPathInfo(BackupSourceType backupSourceType, string path) + { + this.BackupSourceType = backupSourceType; + this.Path = path; + } + + /// + /// Gets the type of the backup source. + /// + public BackupSourceType BackupSourceType { get; private set; } + + /// + /// Gets the path. + /// + public string Path { get; private set; } + } +} diff --git a/Main/SimpleBackup.Models/ModelComponent.cs b/Main/SimpleBackup.Models/ModelComponent.cs new file mode 100644 index 0000000..df9d461 --- /dev/null +++ b/Main/SimpleBackup.Models/ModelComponent.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using SimpleBackup.Core; + using SimpleBackup.Core.AppInfrastructure; + using SimpleBackup.Core.Models; + + /// + /// The model component. + /// + internal class ModelComponent : IAppComponent + { + /// + /// Initializes this application component. + /// + public void Initialize() + { + ObjectContainer.Register(new ModelFactory()); + } + } +} diff --git a/Main/SimpleBackup.Models/ModelFactory.cs b/Main/SimpleBackup.Models/ModelFactory.cs new file mode 100644 index 0000000..0a9e1e6 --- /dev/null +++ b/Main/SimpleBackup.Models/ModelFactory.cs @@ -0,0 +1,278 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using System; + using System.Collections.Generic; + using System.Linq; + using System.Xml.Linq; + using SimpleBackup.Core.Models; + + /// + /// Creates model objectrs. + /// + internal class ModelFactory : IModelFactory + { + /// + /// Creates the backup setting. + /// + /// + /// The backup setting. + /// + public IBackupSetting CreateBackupSetting() + { + return new BackupSetting(); + } + + /// + /// Creates the backup setting. + /// + /// Name of the setting file. + /// The backup information collection. + /// + /// The backup setting. + /// + public IBackupSetting CreateBackupSetting( + string settingFileName, + IEnumerable backupInfoCollection) + { + return new BackupSetting(settingFileName, backupInfoCollection); + } + + /// + /// Creates the backup information. + /// + /// + /// The backup inforamtion. + /// + public IBackupInfo CreateBackupInfo() + { + return new BackupInfo(); + } + + /// + /// Creates the backup information. + /// + /// The source backup information. + /// + /// The backup inforamtion. + /// + public IBackupInfo CreateBackupInfo(IBackupInfo sourceBackupInfo) + { + return new BackupInfo(sourceBackupInfo); + } + + /// + /// Creates the backup information. + /// + /// The label. + /// Type of the backup source. + /// if set to true [is enabled]. + /// if set to true [is zip archive]. + /// The source path. + /// The destination folder path. + /// + /// The backup inforamtion. + /// + public IBackupInfo CreateBackupInfo( + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath) + { + return new BackupInfo( + label, + backupSourceType, + isEnabled, + isZipArchive, + sourcePath, + destinationFolderPath); + } + + /// + /// Creates the backup information. + /// + /// The identifier. + /// The label. + /// Type of the backup source. + /// if set to true [is enabled]. + /// if set to true [is zip archive]. + /// The source path. + /// The destination folder path. + /// + /// The backup inforamtion. + /// + public IBackupInfo CreateBackupInfo( + Guid id, + string label, + BackupSourceType backupSourceType, + bool isEnabled, + bool isZipArchive, + string sourcePath, + string destinationFolderPath) + { + return new BackupInfo( + id, + label, + backupSourceType, + isEnabled, + isZipArchive, + sourcePath, + destinationFolderPath); + } + + /// + /// Creates the backup information from binary. + /// + /// The binary data. + /// if set to true copy suffix is needed. + /// + /// The backup inforamtion. + /// + public IBackupInfo CreateBackupInfoFromBinary(byte[] binaryData, bool copySuffixNeeded) + { + return BackupInfo.FromBinary(binaryData, copySuffixNeeded); + } + + /// + /// Creates the result information. + /// + /// The category. + /// The description. + /// + /// The result inforamtion. + /// + public IResultInfo CreateResultInfo(BackupState category, string description) + { + return new ResultInfo(category, description); + } + + /// + /// Creates the destination path information. + /// + /// Type of the backup source. + /// The path. + /// + /// The destination path information. + /// + public IDestinationPathInfo CreateDestinationPathInfo(BackupSourceType backupSourceType, string path) + { + return new DestinationPathInfo(backupSourceType, path); + } + + /// + /// Restores the backup setting from XML. + /// + /// The XML. + /// Name of the file. + /// The restored backup setting. + public IBackupSetting RestoreBackupSettingFromXml(XElement xml, string fileName) + { + if (xml.Name != "BackupSetting") + { + return null; + } + + XElement itemsElement = xml.Elements("Items").FirstOrDefault(); + if (itemsElement == null) + { + return null; + } + + var backupInfoList = new List(); + foreach (XElement element in itemsElement.Elements()) + { + IBackupInfo backupInfo = RestoreBackupInfoFromXml(element); + backupInfoList.Add(backupInfo); + } + + return new BackupSetting(fileName, backupInfoList); + } + + /// + /// Restores the backup information from XML. + /// + /// The XML. + /// The restored backup information. + private static IBackupInfo RestoreBackupInfoFromXml(XElement xml) + { + if (xml.Name != "BackupInfo") + { + return null; + } + + XElement idElement = xml.Elements("Id").FirstOrDefault(); + XElement labelElement = xml.Elements("Label").FirstOrDefault(); + XElement backupSourceTypeElement = xml.Elements("BackupSourceType").FirstOrDefault(); + XElement enabledElement = xml.Elements("IsEnabled").FirstOrDefault(); + XElement zipArchiveElement = xml.Elements("IsZipArchive").FirstOrDefault(); + XElement sourcePathElement = xml.Elements("SourcePath").FirstOrDefault(); + XElement destinationFolderPathElement = xml.Elements("DestinationFolderPath").FirstOrDefault(); + + if ((idElement == null) || + (labelElement == null) || + (backupSourceTypeElement == null) || + (enabledElement == null) || + (zipArchiveElement == null) || + (sourcePathElement == null) || + (destinationFolderPathElement == null)) + { + return null; + } + + Guid id; + if (Guid.TryParse(idElement.Value, out id) == false) + { + return null; + } + + BackupSourceType backupSourceType; + if (Enum.TryParse(backupSourceTypeElement.Value, out backupSourceType) == false) + { + return null; + } + + bool isEnabled; + if (bool.TryParse(enabledElement.Value, out isEnabled) == false) + { + return null; + } + + bool isZipArchive; + if (bool.TryParse(zipArchiveElement.Value, out isZipArchive) == false) + { + return null; + } + + return BackupInfo.CreateBackupInfo( + id, + labelElement.Value, + backupSourceType, + isEnabled, + isZipArchive, + sourcePathElement.Value, + destinationFolderPathElement.Value); + } + } +} diff --git a/Main/SimpleBackup.Models/ResultInfo.cs b/Main/SimpleBackup.Models/ResultInfo.cs new file mode 100644 index 0000000..49642b9 --- /dev/null +++ b/Main/SimpleBackup.Models/ResultInfo.cs @@ -0,0 +1,52 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Models +{ + using SimpleBackup.Core.Models; + + /// + /// Represents a backup result. + /// + internal class ResultInfo : IResultInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The category. + /// The description. + public ResultInfo(BackupState category, string description) + { + this.BackupState = category; + this.Description = description ?? string.Empty; + } + + /// + /// Gets the state of the backup. + /// + public BackupState BackupState { get; private set; } + + /// + /// Gets the description. + /// + public string Description { get; private set; } + } +} diff --git a/Main/SimpleBackup.Models/SimpleBackup.Models.csproj b/Main/SimpleBackup.Models/SimpleBackup.Models.csproj new file mode 100644 index 0000000..1c59dad --- /dev/null +++ b/Main/SimpleBackup.Models/SimpleBackup.Models.csproj @@ -0,0 +1,90 @@ + + + + + Debug + AnyCPU + {7B8C68F1-8A5C-470F-9356-F0EC1268617F} + Library + Properties + SimpleBackup.Models + SimpleBackup.Models + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + + + + + + + + + + + + {33f1d454-9962-4eb6-aad3-8d11d9a78d1f} + SimpleBackup.Core + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + + + + + set EXE_BIN_DIR=$(ProjectDir)..\bin\$(ConfigurationName)\ +xcopy "$(TargetDir)$(TargetName).dll" "%25EXE_BIN_DIR%25" /Y +if exist "$(TargetDir)$(TargetName).pdb" xcopy "$(TargetDir)$(TargetName).pdb" "%25EXE_BIN_DIR%25" /Y + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Models/SimpleBackupKey.snk b/Main/SimpleBackup.Models/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.Models/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.Resources/Images/Activity_16xLG.png b/Main/SimpleBackup.Resources/Images/Activity_16xLG.png new file mode 100644 index 0000000..9fe818e Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Activity_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/AddVariable_5541.png b/Main/SimpleBackup.Resources/Images/AddVariable_5541.png new file mode 100644 index 0000000..7888863 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/AddVariable_5541.png differ diff --git a/Main/SimpleBackup.Resources/Images/ApplicationIcon.ico b/Main/SimpleBackup.Resources/Images/ApplicationIcon.ico new file mode 100644 index 0000000..393d054 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/ApplicationIcon.ico differ diff --git a/Main/SimpleBackup.Resources/Images/Arrow_RedoRetry_16xLG.png b/Main/SimpleBackup.Resources/Images/Arrow_RedoRetry_16xLG.png new file mode 100644 index 0000000..75b508d Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Arrow_RedoRetry_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/Arrow_UndoRevertRestore_16xLG.png b/Main/SimpleBackup.Resources/Images/Arrow_UndoRevertRestore_16xLG.png new file mode 100644 index 0000000..d759568 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Arrow_UndoRevertRestore_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/Copy_6524.png b/Main/SimpleBackup.Resources/Images/Copy_6524.png new file mode 100644 index 0000000..5e506e8 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Copy_6524.png differ diff --git a/Main/SimpleBackup.Resources/Images/Cut_6523.png b/Main/SimpleBackup.Resources/Images/Cut_6523.png new file mode 100644 index 0000000..6683ee7 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Cut_6523.png differ diff --git a/Main/SimpleBackup.Resources/Images/Delete_black_32x32.png b/Main/SimpleBackup.Resources/Images/Delete_black_32x32.png new file mode 100644 index 0000000..906d053 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Delete_black_32x32.png differ diff --git a/Main/SimpleBackup.Resources/Images/FileGroup_10135_32x.png b/Main/SimpleBackup.Resources/Images/FileGroup_10135_32x.png new file mode 100644 index 0000000..166c1ae Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/FileGroup_10135_32x.png differ diff --git a/Main/SimpleBackup.Resources/Images/NewFile_6276.png b/Main/SimpleBackup.Resources/Images/NewFile_6276.png new file mode 100644 index 0000000..12354ce Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/NewFile_6276.png differ diff --git a/Main/SimpleBackup.Resources/Images/Open_6529.png b/Main/SimpleBackup.Resources/Images/Open_6529.png new file mode 100644 index 0000000..7482286 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Open_6529.png differ diff --git a/Main/SimpleBackup.Resources/Images/Paste_6520.png b/Main/SimpleBackup.Resources/Images/Paste_6520.png new file mode 100644 index 0000000..656678c Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Paste_6520.png differ diff --git a/Main/SimpleBackup.Resources/Images/Print_11009.png b/Main/SimpleBackup.Resources/Images/Print_11009.png new file mode 100644 index 0000000..fd56bdf Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Print_11009.png differ diff --git a/Main/SimpleBackup.Resources/Images/StatusAnnotations_Complete_and_ok_32xLG_color.png b/Main/SimpleBackup.Resources/Images/StatusAnnotations_Complete_and_ok_32xLG_color.png new file mode 100644 index 0000000..31d44e1 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/StatusAnnotations_Complete_and_ok_32xLG_color.png differ diff --git a/Main/SimpleBackup.Resources/Images/StatusAnnotations_Critical_32xLG_color.png b/Main/SimpleBackup.Resources/Images/StatusAnnotations_Critical_32xLG_color.png new file mode 100644 index 0000000..7d96891 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/StatusAnnotations_Critical_32xLG_color.png differ diff --git a/Main/SimpleBackup.Resources/Images/Symbols_Complete_and_ok_32xLG.png b/Main/SimpleBackup.Resources/Images/Symbols_Complete_and_ok_32xLG.png new file mode 100644 index 0000000..9817b25 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Symbols_Complete_and_ok_32xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/Synchronize_16xLG.png b/Main/SimpleBackup.Resources/Images/Synchronize_16xLG.png new file mode 100644 index 0000000..5829529 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Synchronize_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/Warning.png b/Main/SimpleBackup.Resources/Images/Warning.png new file mode 100644 index 0000000..2167241 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/Warning.png differ diff --git a/Main/SimpleBackup.Resources/Images/action_Cancel_16xLG.png b/Main/SimpleBackup.Resources/Images/action_Cancel_16xLG.png new file mode 100644 index 0000000..ac08d59 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/action_Cancel_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/arrow_Down_16xLG.png b/Main/SimpleBackup.Resources/Images/arrow_Down_16xLG.png new file mode 100644 index 0000000..efdaccd Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/arrow_Down_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/arrow_Up_16xLG.png b/Main/SimpleBackup.Resources/Images/arrow_Up_16xLG.png new file mode 100644 index 0000000..09b45f7 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/arrow_Up_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/arrow_all_run_16xLG.png b/Main/SimpleBackup.Resources/Images/arrow_all_run_16xLG.png new file mode 100644 index 0000000..c2cf001 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/arrow_all_run_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/arrow_run_16xLG.png b/Main/SimpleBackup.Resources/Images/arrow_run_16xLG.png new file mode 100644 index 0000000..b88c293 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/arrow_run_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/document_32xLG.png b/Main/SimpleBackup.Resources/Images/document_32xLG.png new file mode 100644 index 0000000..66c486d Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/document_32xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/flag_16xLG.png b/Main/SimpleBackup.Resources/Images/flag_16xLG.png new file mode 100644 index 0000000..25c3b86 Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/flag_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/refresh_16xLG.png b/Main/SimpleBackup.Resources/Images/refresh_16xLG.png new file mode 100644 index 0000000..129f36e Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/refresh_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/Images/save_16xLG.png b/Main/SimpleBackup.Resources/Images/save_16xLG.png new file mode 100644 index 0000000..199d45b Binary files /dev/null and b/Main/SimpleBackup.Resources/Images/save_16xLG.png differ diff --git a/Main/SimpleBackup.Resources/ResourceHelper.cs b/Main/SimpleBackup.Resources/ResourceHelper.cs new file mode 100644 index 0000000..d4362b6 --- /dev/null +++ b/Main/SimpleBackup.Resources/ResourceHelper.cs @@ -0,0 +1,156 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Resources +{ + using System; + using System.Resources; + using System.Windows; + + /// + /// Provides localized resources. + /// + public class ResourceHelper + { + /// + /// The resource identifier property + /// + public static readonly DependencyProperty ResourceIdProperty = DependencyProperty.RegisterAttached( + "ResourceId", + typeof(string), + typeof(ResourceHelper), + new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None, OnResourceIdChanged)); + + /// + /// The resource text property + /// + public static readonly DependencyProperty ResourceTextProperty = DependencyProperty.RegisterAttached( + "ResourceText", + typeof(string), + typeof(ResourceHelper), + new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.None)); + + /// + /// The inner resource manager + /// + private static readonly ResourceManager InnerResourceManager = + new ResourceManager("SimpleBackup.Resources.Resources", typeof(ResourceHelper).Assembly); + + /// + /// The synchronize root + /// + private static readonly object SyncRoot = new object(); + + /// + /// The instance of ResourceService. + /// + private static volatile ResourceHelper instance; + + /// + /// Prevents a default instance of the class from being created. + /// + private ResourceHelper() + { + } + + /// + /// Sets the resource identifier. + /// + /// The dependency object. + /// The value. + public static void SetResourceId(DependencyObject obj, string value) + { + obj.SetValue(ResourceIdProperty, value); + } + + /// + /// Gets the resource identifier. + /// + /// The dependency object. + /// The resource ID. + public static string GetResourceId(DependencyObject obj) + { + return (string)obj.GetValue(ResourceIdProperty); + } + + /// + /// Gets the resource text. + /// + /// The object. + /// The resource text. + public static string GetResourceText(DependencyObject obj) + { + return (string)obj.GetValue(ResourceTextProperty); + } + + /// + /// Called when [resource identifier changed]. + /// + /// The dependency object. + /// The instance containing the event data. + private static void OnResourceIdChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + var newResourceId = (string)e.NewValue; + string resourceText; + if (TryGetResourceText(newResourceId, out resourceText)) + { + d.SetValue(ResourceTextProperty, resourceText); + } + } + + /// + /// Tries the get resource text. + /// + /// The resource identifier. + /// The resource text. + /// True if succeeded to get resource text. + private static bool TryGetResourceText(string resourceId, out string resourceText) + { + resourceText = string.Empty; + + try + { + resourceText = InnerResourceManager.GetString(resourceId); + } + catch (ArgumentNullException) + { + //// Ignore exception. + } + catch (InvalidOperationException) + { + //// Ignore exception. + } + catch (MissingManifestResourceException) + { + //// Ignore exception. + } + catch (MissingSatelliteAssemblyException) + { + //// Ignore exception. + } + + var succeeded = resourceText != null; + resourceText = resourceText ?? string.Empty; + + return succeeded; + } + } +} diff --git a/Main/SimpleBackup.Resources/Resources.Designer.cs b/Main/SimpleBackup.Resources/Resources.Designer.cs new file mode 100644 index 0000000..09d4ef4 --- /dev/null +++ b/Main/SimpleBackup.Resources/Resources.Designer.cs @@ -0,0 +1,778 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:4.0.30319.34014 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace SimpleBackup.Resources { + using System; + + + /// + /// ローカライズされた文字列などを検索するための、厳密に型指定されたリソース クラスです。 + /// + // このクラスは StronglyTypedResourceBuilder クラスが ResGen + // または Visual Studio のようなツールを使用して自動生成されました。 + // メンバーを追加または削除するには、.ResX ファイルを編集して、/str オプションと共に + // ResGen を実行し直すか、または VS プロジェクトをビルドし直します。 + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + public class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// このクラスで使用されているキャッシュされた ResourceManager インスタンスを返します。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("SimpleBackup.Resources.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// 厳密に型指定されたこのリソース クラスを使用して、すべての検索リソースに対し、 + /// 現在のスレッドの CurrentUICulture プロパティをオーバーライドします。 + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + public static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Backup... に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_ExecutingBackup { + get { + return ResourceManager.GetString("Backup_ExecutingBackup", resourceCulture); + } + } + + /// + /// The backup information has not been prepared. に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Failed_BackupInfomationNotPrepared { + get { + return ResourceManager.GetString("Backup_Failed_BackupInfomationNotPrepared", resourceCulture); + } + } + + /// + /// The destination Folder does not exist. に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Failed_DestinationNotExist { + get { + return ResourceManager.GetString("Backup_Failed_DestinationNotExist", resourceCulture); + } + } + + /// + /// Failed to copy the file. に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Failed_FailedToCopy { + get { + return ResourceManager.GetString("Backup_Failed_FailedToCopy", resourceCulture); + } + } + + /// + /// The source does not exist. に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Failed_SourceNotExist { + get { + return ResourceManager.GetString("Backup_Failed_SourceNotExist", resourceCulture); + } + } + + /// + /// From に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_From { + get { + return ResourceManager.GetString("Backup_From", resourceCulture); + } + } + + /// + /// The backup has been skipped. に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Skipped { + get { + return ResourceManager.GetString("Backup_Skipped", resourceCulture); + } + } + + /// + /// Done! に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_Succeeded { + get { + return ResourceManager.GetString("Backup_Succeeded", resourceCulture); + } + } + + /// + /// To に類似しているローカライズされた文字列を検索します。 + /// + public static string Backup_To { + get { + return ResourceManager.GetString("Backup_To", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. The file name is empty: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_EmptyFileNameFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_EmptyFileNameFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. Invalid major version value: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_InvalidMajorVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_InvalidMajorVersionFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. Invalid minor version value: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_InvalidMinorVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_InvalidMinorVersionFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. Invalid "RequiredToolVersion" value: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_InvalidRequiredToolVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_InvalidRequiredToolVersionFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. Invalid "Version" value: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_InvalidVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_InvalidVersionFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. There is no "BackupSetting" tag: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_NoBackupSettingElementFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_NoBackupSettingElementFormat", resourceCulture); + } + } + + /// + /// Failed to open the backup setting. There is no "Version" tag: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_FailedToOpenSetting_NoVersionElementFormat { + get { + return ResourceManager.GetString("BackupSetting_FailedToOpenSetting_NoVersionElementFormat", resourceCulture); + } + } + + /// + /// Failed to read the backup setting data because it is incomatible. To read the backup setting data, please use Simple Backup Ver.{0} or later. に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_IncompatibleMajorVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_IncompatibleMajorVersionFormat", resourceCulture); + } + } + + /// + /// Failed to read some part of the backup setting data because they are incompatible. To read all the backup setting data, please use Simple Backup Ver.{0} or later. に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_IncompatibleMinorVersionFormat { + get { + return ResourceManager.GetString("BackupSetting_IncompatibleMinorVersionFormat", resourceCulture); + } + } + + /// + /// The backup setting is opened: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupSetting_SettingOpenedFormat { + get { + return ResourceManager.GetString("BackupSetting_SettingOpenedFormat", resourceCulture); + } + } + + /// + /// Cancelled に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_Cancelled { + get { + return ResourceManager.GetString("BackupState_Cancelled", resourceCulture); + } + } + + /// + /// Fail に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_Failed { + get { + return ResourceManager.GetString("BackupState_Failed", resourceCulture); + } + } + + /// + /// In Progress に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_InProgress { + get { + return ResourceManager.GetString("BackupState_InProgress", resourceCulture); + } + } + + /// + /// Skipped に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_Skipped { + get { + return ResourceManager.GetString("BackupState_Skipped", resourceCulture); + } + } + + /// + /// Success に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_Success { + get { + return ResourceManager.GetString("BackupState_Success", resourceCulture); + } + } + + /// + /// TODO に類似しているローカライズされた文字列を検索します。 + /// + public static string BackupState_Todo { + get { + return ResourceManager.GetString("BackupState_Todo", resourceCulture); + } + } + + /// + /// Copy に類似しているローカライズされた文字列を検索します。 + /// + public static string Edit_CopySuffix { + get { + return ResourceManager.GetString("Edit_CopySuffix", resourceCulture); + } + } + + /// + /// Failed to open the file: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string FileAccess_FailedToOpenFormat { + get { + return ResourceManager.GetString("FileAccess_FailedToOpenFormat", resourceCulture); + } + } + + /// + /// The folder path does not exist: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string FileAccess_FolderPathNotExistFormat { + get { + return ResourceManager.GetString("FileAccess_FolderPathNotExistFormat", resourceCulture); + } + } + + /// + /// The path is not valid: {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string FileAccess_InvalidPathFormat { + get { + return ResourceManager.GetString("FileAccess_InvalidPathFormat", resourceCulture); + } + } + + /// + /// Copyright© 2015 Takayoshi Matsuyama に類似しているローカライズされた文字列を検索します。 + /// + public static string Version_Copyright { + get { + return ResourceManager.GetString("Version_Copyright", resourceCulture); + } + } + + /// + /// This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + /// + ///This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + /// + ///You should have received a copy [残りの文字列は切り詰められました]"; に類似しているローカライズされた文字列を検索します。 + /// + public static string Version_CopyrightDescription { + get { + return ResourceManager.GetString("Version_CopyrightDescription", resourceCulture); + } + } + + /// + /// Add に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_AddButtonToolTipText { + get { + return ResourceManager.GetString("Views_AddButtonToolTipText", resourceCulture); + } + } + + /// + /// Destination に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_BackupDestinationColumnHeaderText { + get { + return ResourceManager.GetString("Views_BackupDestinationColumnHeaderText", resourceCulture); + } + } + + /// + /// Source に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_BackupSourceColumnHeaderText { + get { + return ResourceManager.GetString("Views_BackupSourceColumnHeaderText", resourceCulture); + } + } + + /// + /// Cancel Multi Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_CancelMultiBackupButtonToolTipText { + get { + return ResourceManager.GetString("Views_CancelMultiBackupButtonToolTipText", resourceCulture); + } + } + + /// + /// Confirmation に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ConfirmationDialogTitle { + get { + return ResourceManager.GetString("Views_ConfirmationDialogTitle", resourceCulture); + } + } + + /// + /// Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_Backup { + get { + return ResourceManager.GetString("Views_ContextMenu_Backup", resourceCulture); + } + } + + /// + /// Edit に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_Edit { + get { + return ResourceManager.GetString("Views_ContextMenu_Edit", resourceCulture); + } + } + + /// + /// Open Destination に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_OpenDestination { + get { + return ResourceManager.GetString("Views_ContextMenu_OpenDestination", resourceCulture); + } + } + + /// + /// Open File に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_OpenFile { + get { + return ResourceManager.GetString("Views_ContextMenu_OpenFile", resourceCulture); + } + } + + /// + /// Open Source Folder に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_OpenSourceFolder { + get { + return ResourceManager.GetString("Views_ContextMenu_OpenSourceFolder", resourceCulture); + } + } + + /// + /// Select Destination に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_SelectDestination { + get { + return ResourceManager.GetString("Views_ContextMenu_SelectDestination", resourceCulture); + } + } + + /// + /// Select Source に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ContextMenu_SelectSource { + get { + return ResourceManager.GetString("Views_ContextMenu_SelectSource", resourceCulture); + } + } + + /// + /// Copy に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_CopyButtonToolTipText { + get { + return ResourceManager.GetString("Views_CopyButtonToolTipText", resourceCulture); + } + } + + /// + /// Simple Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_CopyrightApplicationName { + get { + return ResourceManager.GetString("Views_CopyrightApplicationName", resourceCulture); + } + } + + /// + /// Cut に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_CutButtonToolTipText { + get { + return ResourceManager.GetString("Views_CutButtonToolTipText", resourceCulture); + } + } + + /// + /// Simple Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_DefaultWindowTitle { + get { + return ResourceManager.GetString("Views_DefaultWindowTitle", resourceCulture); + } + } + + /// + /// Label に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_LabelColumnHeaderText { + get { + return ResourceManager.GetString("Views_LabelColumnHeaderText", resourceCulture); + } + } + + /// + /// _Close に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_Close { + get { + return ResourceManager.GetString("Views_MainMenu_Close", resourceCulture); + } + } + + /// + /// E_xit に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_Exit { + get { + return ResourceManager.GetString("Views_MainMenu_Exit", resourceCulture); + } + } + + /// + /// _File に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_File { + get { + return ResourceManager.GetString("Views_MainMenu_File", resourceCulture); + } + } + + /// + /// _Help に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_Help { + get { + return ResourceManager.GetString("Views_MainMenu_Help", resourceCulture); + } + } + + /// + /// _New に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_New { + get { + return ResourceManager.GetString("Views_MainMenu_New", resourceCulture); + } + } + + /// + /// _Open に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_Open { + get { + return ResourceManager.GetString("Views_MainMenu_Open", resourceCulture); + } + } + + /// + /// Open Current Setting File Location に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_OpenCurrentSettingFileLocation { + get { + return ResourceManager.GetString("Views_MainMenu_OpenCurrentSettingFileLocation", resourceCulture); + } + } + + /// + /// _Save に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_Save { + get { + return ResourceManager.GetString("Views_MainMenu_Save", resourceCulture); + } + } + + /// + /// Save _As に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_SaveAs { + get { + return ResourceManager.GetString("Views_MainMenu_SaveAs", resourceCulture); + } + } + + /// + /// Show Help (_V) に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_ShowHelp { + get { + return ResourceManager.GetString("Views_MainMenu_ShowHelp", resourceCulture); + } + } + + /// + /// Show Version Information (_A) に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MainMenu_ShowVersionInformation { + get { + return ResourceManager.GetString("Views_MainMenu_ShowVersionInformation", resourceCulture); + } + } + + /// + /// Move down に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MoveDownButtonToolTipText { + get { + return ResourceManager.GetString("Views_MoveDownButtonToolTipText", resourceCulture); + } + } + + /// + /// Move up に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MoveUpButtonToolTipText { + get { + return ResourceManager.GetString("Views_MoveUpButtonToolTipText", resourceCulture); + } + } + + /// + /// Multiple Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_MultipleBackupButtonToolTipText { + get { + return ResourceManager.GetString("Views_MultipleBackupButtonToolTipText", resourceCulture); + } + } + + /// + /// New Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_NewBackupSettingName { + get { + return ResourceManager.GetString("Views_NewBackupSettingName", resourceCulture); + } + } + + /// + /// New に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_NewFileButtonToolTipText { + get { + return ResourceManager.GetString("Views_NewFileButtonToolTipText", resourceCulture); + } + } + + /// + /// Open Backup Setting に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_OpenBackupSettingButtonToolTipText { + get { + return ResourceManager.GetString("Views_OpenBackupSettingButtonToolTipText", resourceCulture); + } + } + + /// + /// Open Backup Setting に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_OpenFileDialogTitle { + get { + return ResourceManager.GetString("Views_OpenFileDialogTitle", resourceCulture); + } + } + + /// + /// Clear に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_OutputWindowContextMenu_Clear { + get { + return ResourceManager.GetString("Views_OutputWindowContextMenu_Clear", resourceCulture); + } + } + + /// + /// Paste に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_PasteButtonToolTipText { + get { + return ResourceManager.GetString("Views_PasteButtonToolTipText", resourceCulture); + } + } + + /// + /// Redo に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_RedoButtonToolTipText { + get { + return ResourceManager.GetString("Views_RedoButtonToolTipText", resourceCulture); + } + } + + /// + /// Refresh に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_RefreshButtonToolTipText { + get { + return ResourceManager.GetString("Views_RefreshButtonToolTipText", resourceCulture); + } + } + + /// + /// Remove に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_RemoveButtonToolTipText { + get { + return ResourceManager.GetString("Views_RemoveButtonToolTipText", resourceCulture); + } + } + + /// + /// Save Backup Setting に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_SaveBackupSettingButtonToolTipText { + get { + return ResourceManager.GetString("Views_SaveBackupSettingButtonToolTipText", resourceCulture); + } + } + + /// + /// Save the changes? に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_SaveConfirmationMessage { + get { + return ResourceManager.GetString("Views_SaveConfirmationMessage", resourceCulture); + } + } + + /// + /// Save Backup Setting に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_SaveFileDialogTitle { + get { + return ResourceManager.GetString("Views_SaveFileDialogTitle", resourceCulture); + } + } + + /// + /// Single Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_SingleBackupButtonToolTipText { + get { + return ResourceManager.GetString("Views_SingleBackupButtonToolTipText", resourceCulture); + } + } + + /// + /// Undo に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_UndoButtonToolTipText { + get { + return ResourceManager.GetString("Views_UndoButtonToolTipText", resourceCulture); + } + } + + /// + /// Version Information of Simple Backup に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_VersionWindowTitle { + get { + return ResourceManager.GetString("Views_VersionWindowTitle", resourceCulture); + } + } + + /// + /// Simple Backup - {0} に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_WindowTitleFormat { + get { + return ResourceManager.GetString("Views_WindowTitleFormat", resourceCulture); + } + } + + /// + /// Zip Encoding に類似しているローカライズされた文字列を検索します。 + /// + public static string Views_ZipEncodingTitleText { + get { + return ResourceManager.GetString("Views_ZipEncodingTitleText", resourceCulture); + } + } + } +} diff --git a/Main/SimpleBackup.Resources/Resources.ja.resx b/Main/SimpleBackup.Resources/Resources.ja.resx new file mode 100644 index 0000000..b16a2a4 --- /dev/null +++ b/Main/SimpleBackup.Resources/Resources.ja.resx @@ -0,0 +1,348 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + キャンセル + + + 失敗 + + + 進行中 + + + スキップ + + + 成功 + + + 実行待ち + + + バックアップ実行中... + + + バックアップ対象がありません。 + + + バックアップ情報が準備できていません。 + + + バックアップはスキップされました。 + + + バックアップ対象 + + + バックアップ先 + + + コピー + + + 追加 + + + バックアップ先 + + + バックアップ対象 + + + マルチバックアップをキャンセル + + + バックアップ + + + 編集 + + + バックアップ先の場所を開く + + + ファイルを開く + + + バックアップ対象の場所を開く + + + バックアップ先を選ぶ + + + バックアップ対象を選ぶ + + + コピー + + + 切り取り + + + バックアップツール + + + ラベル + + + 閉じる(_C) + + + 終了(_X) + + + ファイル(_F) + + + ヘルプ(_H) + + + 新規作成(_N) + + + 開く(_O) + + + 現在の設定ファイルの場所を開く + + + ヘルプの表示(_V) + + + バージョン情報(_A) + + + 下へ移動 + + + 上へ移動 + + + マルチバックアップ + + + 新しいバックアップ + + + 新規作成 + + + バックアップ設定を開く + + + クリア + + + 貼り付け + + + やり直し + + + リフレッシュ + + + 削除 + + + バックアップ設定を保存する + + + シングルバックアップ + + + 元に戻す + + + バックアップツールのバージョン情報 + + + バックアップツール - {0} + + + バックアップ先のフォルダががありません。 + + + ファイルのコピーに失敗しました。 + + + バックアップを完了しました。 + + + 保存(_S) + + + 名前を付けて保存(_A) + + + Zipエンコード + + + バックアップ設定を開く + + + バックアップ設定の保存 + + + 互換性がないため、バックアップ設定データの読み込みに失敗しました。このバックアップ設定データを読み込むには、Ver.{0}以降のバックアップツールを入手してください。 + + + 互換性がないため、一部のバックアップ設定データの読み込みに失敗しました。全てのバックアップ設定データを読み込むには、Ver.{0}以降のバックアップツールを入手してください。 + + + バックアップ設定を開きました。{0} + + + バックアップ設定の読み込みに失敗しました。ファイル名が空です。{0} + + + バックアップ設定の読み込みに失敗しました。メジャーバージョン値が不正です。{0} + + + バックアップ設定の読み込みに失敗しました。マイナーバージョン値が不正です。{0} + + + バックアップ設定の読み込みに失敗しました。"RequiredToolVersion"値が不正です。{0} + + + バックアップ設定の読み込みに失敗しました。"Version"値が不正です。{0} + + + バックアップ設定の読み込みに失敗しました。"BackupSetting"タグが見つかりません。{0} + + + バックアップ設定の読み込みに失敗しました。"Version"タグが見つかりません。{0} + + + ファイルオープンに失敗しました。 {0} + + + 存在しないフォルダです。 {0} + + + 不正なパスです。 {0} + + + 確認 + + + 変更を保存しますか? + + \ No newline at end of file diff --git a/Main/SimpleBackup.Resources/Resources.resx b/Main/SimpleBackup.Resources/Resources.resx new file mode 100644 index 0000000..a8eb5b9 --- /dev/null +++ b/Main/SimpleBackup.Resources/Resources.resx @@ -0,0 +1,361 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Cancelled + + + Fail + + + In Progress + + + Skipped + + + Success + + + TODO + + + Backup... + + + The source does not exist. + + + The backup information has not been prepared. + + + The backup has been skipped. + + + From + + + To + + + Copy + + + Copyright© 2015 Takayoshi Matsuyama + + + This program is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. + +You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. + + + Add + + + Destination + + + Source + + + Cancel Multi Backup + + + Backup + + + Edit + + + Open Destination + + + Open File + + + Open Source Folder + + + Select Destination + + + Select Source + + + Copy + + + Simple Backup + + + Cut + + + Simple Backup + + + Label + + + _Close + + + E_xit + + + _File + + + _Help + + + _New + + + _Open + + + Open Current Setting File Location + + + Show Help (_V) + + + Show Version Information (_A) + + + Move down + + + Move up + + + Multiple Backup + + + New Backup + + + New + + + Open Backup Setting + + + Clear + + + Paste + + + Redo + + + Refresh + + + Remove + + + Save Backup Setting + + + Single Backup + + + Undo + + + Version Information of Simple Backup + + + Simple Backup - {0} + + + The destination Folder does not exist. + + + Failed to copy the file. + + + Done! + + + _Save + + + Save _As + + + Zip Encoding + + + Open Backup Setting + + + Save Backup Setting + + + Failed to read the backup setting data because it is incomatible. To read the backup setting data, please use Simple Backup Ver.{0} or later. + + + Failed to read some part of the backup setting data because they are incompatible. To read all the backup setting data, please use Simple Backup Ver.{0} or later. + + + The backup setting is opened: {0} + + + Failed to open the backup setting. The file name is empty: {0} + + + Failed to open the backup setting. Invalid major version value: {0} + + + Failed to open the backup setting. Invalid minor version value: {0} + + + Failed to open the backup setting. Invalid "RequiredToolVersion" value: {0} + + + Failed to open the backup setting. Invalid "Version" value: {0} + + + Failed to open the backup setting. There is no "BackupSetting" tag: {0} + + + Failed to open the backup setting. There is no "Version" tag: {0} + + + Failed to open the file: {0} + + + The folder path does not exist: {0} + + + The path is not valid: {0} + + + Confirmation + + + Save the changes? + + \ No newline at end of file diff --git a/Main/SimpleBackup.Resources/SimpleBackup.Resources.csproj b/Main/SimpleBackup.Resources/SimpleBackup.Resources.csproj new file mode 100644 index 0000000..5bdec14 --- /dev/null +++ b/Main/SimpleBackup.Resources/SimpleBackup.Resources.csproj @@ -0,0 +1,165 @@ + + + + + Debug + AnyCPU + {A655131E-D439-4DE1-BC39-5C955306183F} + Library + Properties + SimpleBackup.Resources + SimpleBackup.Resources + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + Resources.resx + True + True + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PublicResXFileCodeGenerator + Resources.Designer.cs + + + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Resources/SimpleBackupKey.snk b/Main/SimpleBackup.Resources/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.Resources/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.Services/BackupService.cs b/Main/SimpleBackup.Services/BackupService.cs new file mode 100644 index 0000000..a77dc58 --- /dev/null +++ b/Main/SimpleBackup.Services/BackupService.cs @@ -0,0 +1,643 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using System; + using System.Collections.Generic; + using System.IO; + using System.IO.Compression; + using System.Linq; + using System.Text; + using System.Text.RegularExpressions; + using System.Threading; + using SimpleBackup.Core; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Resources; + + /// + /// Backup service. + /// + internal class BackupService : IBackupService + { + /// + /// The synchronize root + /// + private static readonly object SyncRoot = new object(); + + /// + /// The instance of BackupService. + /// + private static volatile BackupService instance; + + /// + /// Prevents a default instance of the class from being created. + /// + private BackupService() + { + BackupSettingService.Instance.BackupSettingCreated += this.OnBackupSettingCreated; + BackupSettingService.Instance.BackupSettingOpened += this.OnBackupSettingOpened; + BackupSettingService.Instance.BackupSettingClosed += this.OnBackupSettingClosed; + } + + /// + /// Occurs when file backup progress is updated. + /// + public event EventHandler NofityFileBackupProgress; + + /// + /// Gets the instance. + /// + public static IBackupService Instance + { + get + { + if (instance == null) + { + lock (SyncRoot) + { + if (instance == null) + { + instance = new BackupService(); + } + } + } + + return instance; + } + } + + /// + /// Gets a value indicating whether this service is ready for backup. + /// + public bool IsReadyForBackup { get; private set; } + + /// + /// Gets a value indicating whether this service is executing backup. + /// + public bool IsExecutingBackup { get; private set; } + + /// + /// Backups multipul files. + /// + /// The cancellation token. + /// The array of result information. + public void BackupMultipulFiles(CancellationToken cancellationToken, out IResultInfo[] resultInfos) + { + var modelFactory = ObjectContainer.Resolve(); + + this.IsExecutingBackup = true; + var resultList = new List(); + if (this.IsReadyForBackup == false) + { + resultList.Add(modelFactory.CreateResultInfo(BackupState.Failed, Resources.Backup_Failed_BackupInfomationNotPrepared)); + resultInfos = resultList.ToArray(); + return; + } + + try + { + this.NotifyBackupProgress(0, null); + + int processedCount = 0; + + foreach (IBackupInfo backupInfo in BackupSettingService.Instance.CurrentSetting.BackupInfos) + { + cancellationToken.ThrowIfCancellationRequested(); + backupInfo.BackupState = BackupState.InProgress; + + Thread.Sleep(100); + + IResultInfo resultInfo = null; + double progressValue = 0; + + if (backupInfo.IsEnabled == false) + { + string description = string.Format( + "{0}\r\n\t{1}: {2}", + Resources.Backup_Skipped, + Resources.Backup_From, + backupInfo.SourcePath); + resultInfo = modelFactory.CreateResultInfo(BackupState.Skipped, description); + processedCount++; + progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count; + this.NotifyBackupProgress(progressValue, resultInfo); + backupInfo.BackupState = BackupState.Skipped; + continue; + } + + // Check the source. + if (((backupInfo.BackupSourceType == BackupSourceType.File) && (File.Exists(backupInfo.SourcePath) == false)) || + ((backupInfo.BackupSourceType == BackupSourceType.Folder) && (Directory.Exists(backupInfo.SourcePath) == false))) + { + string description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Failed_SourceNotExist, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + backupInfo.DestinationFolderPath); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + resultList.Add(resultInfo); + processedCount++; + progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count; + this.NotifyBackupProgress(progressValue, resultInfo); + backupInfo.BackupState = BackupState.Failed; + continue; + } + + // Check the destination. + if ((backupInfo.DestinationFolderPath == "\\") || + (Directory.Exists(backupInfo.DestinationFolderPath) == false)) + { + string description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Failed_DestinationNotExist, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + backupInfo.DestinationFolderPath); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + resultList.Add(resultInfo); + processedCount++; + progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count; + this.NotifyBackupProgress(progressValue, resultInfo); + backupInfo.BackupState = BackupState.Failed; + continue; + } + + var destinationFileNames = new IDestinationPathInfo[0]; + try + { + if (backupInfo.IsZipArchive) + { + if (backupInfo.BackupSourceType == BackupSourceType.File) + { + BackupFileToZip(backupInfo, out destinationFileNames); + } + else if (backupInfo.BackupSourceType == BackupSourceType.Folder) + { + BackupFolerToZip(backupInfo, out destinationFileNames); + } + } + else + { + if (backupInfo.BackupSourceType == BackupSourceType.File) + { + BackupFile(backupInfo, out destinationFileNames); + } + else if (backupInfo.BackupSourceType == BackupSourceType.Folder) + { + BackupFolder(backupInfo, out destinationFileNames); + } + } + } + catch (Exception e) + { + string description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}\r\n{5}", + Resources.Backup_Failed_FailedToCopy, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + destinationFileNames.FirstOrDefault(), + e.Message); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + resultList.Add(resultInfo); + processedCount++; + progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count; + this.NotifyBackupProgress(progressValue, resultInfo); + backupInfo.BackupState = BackupState.Failed; + continue; + } + + if (CheckExistence(destinationFileNames)) + { + string description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Succeeded, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + destinationFileNames.First().Path); + resultInfo = modelFactory.CreateResultInfo(BackupState.Success, description); + resultList.Add(resultInfo); + backupInfo.BackupState = BackupState.Success; + backupInfo.LatestSuccessfulBackupTargetName = destinationFileNames.First().Path; + } + + processedCount++; + progressValue = processedCount * 100.0 / BackupSettingService.Instance.CurrentSetting.Count; + this.NotifyBackupProgress(progressValue, resultInfo); + } + + this.NotifyBackupProgress(100.0, null); + } + catch (OperationCanceledException) + { + var resultInfo = modelFactory.CreateResultInfo(BackupState.Cancelled, Resources.BackupState_Cancelled); + resultList.Add(resultInfo); + this.NotifyBackupProgress(100.0, resultInfo); + } + finally + { + resultInfos = resultList.ToArray(); + this.IsExecutingBackup = false; + } + } + + /// + /// Backups single file. + /// + /// The backup information identifier. + /// The result information. + public IResultInfo BackupSingleFile(Guid backupInfoId) + { + var modelFactory = ObjectContainer.Resolve(); + + IBackupInfo backupInfo = BackupSettingService.Instance.CurrentSetting.FirstOrDefault(backupInfoId); + if (backupInfo == null) + { + return modelFactory.CreateResultInfo( + BackupState.Failed, + Resources.Backup_Failed_BackupInfomationNotPrepared); + } + + backupInfo.BackupState = BackupState.InProgress; + Helpers.UpdateWpfGui(); + + IResultInfo resultInfo = null; + string description = string.Empty; + + // Check the source. + if (((backupInfo.BackupSourceType == BackupSourceType.File) && (File.Exists(backupInfo.SourcePath) == false)) || + ((backupInfo.BackupSourceType == BackupSourceType.Folder) && (Directory.Exists(backupInfo.SourcePath) == false))) + { + description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Failed_SourceNotExist, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + backupInfo.DestinationFolderPath); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + backupInfo.BackupState = BackupState.Failed; + return resultInfo; + } + + // Check the destination. + if (Directory.Exists(backupInfo.DestinationFolderPath) == false) + { + description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Failed_DestinationNotExist, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + backupInfo.DestinationFolderPath); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + backupInfo.BackupState = BackupState.Failed; + return resultInfo; + } + + var destinationFileNames = new IDestinationPathInfo[0]; + try + { + if (backupInfo.IsZipArchive) + { + if (backupInfo.BackupSourceType == BackupSourceType.File) + { + BackupFileToZip(backupInfo, out destinationFileNames); + } + else if (backupInfo.BackupSourceType == BackupSourceType.Folder) + { + BackupFolerToZip(backupInfo, out destinationFileNames); + } + } + else + { + if (backupInfo.BackupSourceType == BackupSourceType.File) + { + BackupFile(backupInfo, out destinationFileNames); + } + else if (backupInfo.BackupSourceType == BackupSourceType.Folder) + { + BackupFolder(backupInfo, out destinationFileNames); + } + } + } + catch (Exception e) + { + description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}\r\n{5}", + Resources.Backup_Failed_FailedToCopy, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + destinationFileNames.FirstOrDefault(), + e.Message); + resultInfo = modelFactory.CreateResultInfo(BackupState.Failed, description); + backupInfo.BackupState = BackupState.Failed; + return resultInfo; + } + + if (CheckExistence(destinationFileNames)) + { + description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Succeeded, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + destinationFileNames.First().Path); + resultInfo = modelFactory.CreateResultInfo(BackupState.Success, description); + backupInfo.BackupState = BackupState.Success; + backupInfo.LatestSuccessfulBackupTargetName = destinationFileNames.First().Path; + return resultInfo; + } + + description = string.Format( + "{0}\r\n\t{1}: {2}\r\n\t{3}: {4}", + Resources.Backup_Failed_FailedToCopy, + Resources.Backup_From, + backupInfo.SourcePath, + Resources.Backup_To, + destinationFileNames.FirstOrDefault()); + return modelFactory.CreateResultInfo(BackupState.Failed, description); + } + + private static void BackupFileToZip(IBackupInfo backupInfo, out IDestinationPathInfo[] destinationPathInfoArray) + { + var innerDestinationPathInfoList = new List(); + + var modelFactory = ObjectContainer.Resolve(); + + Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath); + Match fileNameMatch = Constants.FileNameRegex.Match(lastPathSegmentMatch.Value); + Match extensionMatch = Constants.ExtensionRegex.Match(lastPathSegmentMatch.Value); + + string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist(); + string destinationTempFolderPath = destinationFolderPath + fileNameMatch.Value + + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "-tmp"; + string destinationTempFileName = destinationTempFolderPath + "\\" + fileNameMatch.Value + + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "." + extensionMatch.Value; + try + { + try + { + Directory.CreateDirectory(destinationTempFolderPath); + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + "Failed to create the folder: {0}\r\n{1}", + destinationTempFolderPath, + e.Message), + e); + } + + try + { + File.Copy(backupInfo.SourcePath, destinationTempFileName); + } + catch (Exception e) + { + throw new InvalidOperationException( + string.Format( + "Failed to copy the file.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}", + backupInfo.SourcePath, + destinationTempFolderPath, + e.Message), + e); + } + + var destinationFileName = destinationFolderPath + fileNameMatch.Value + + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + ".zip"; + innerDestinationPathInfoList.Add(modelFactory.CreateDestinationPathInfo(BackupSourceType.File, destinationFileName)); + + try + { + ZipFile.CreateFromDirectory( + destinationTempFolderPath, + destinationFileName, + CompressionLevel.Optimal, + false, + Encoding.GetEncoding(Properties.Settings.Default.DefaultZipEncodingKeyText)); + } + catch (Exception e) + { + backupInfo.BackupState = BackupState.Failed; + throw new InvalidOperationException( + string.Format( + "Failed to create the zip archive.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}", + destinationTempFolderPath, + destinationFileName, + e.Message), + e); + } + } + finally + { + destinationPathInfoArray = innerDestinationPathInfoList.ToArray(); + + if (File.Exists(destinationTempFileName)) + { + File.Delete(destinationTempFileName); + } + + if (Directory.Exists(destinationTempFolderPath)) + { + Directory.Delete(destinationTempFolderPath); + } + } + } + + private static void BackupFolerToZip(IBackupInfo backupInfo, out IDestinationPathInfo[] destinationPathInfoArray) + { + var innerDestinationPathInfoList = new List(); + + var modelFactory = ObjectContainer.Resolve(); + + Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath); + + string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist(); + var destinationFileName = destinationFolderPath + + lastPathSegmentMatch.Value + " - " + + DateTime.Now.ToString("yyyyMMdd-HHmmss") + + ".zip"; + innerDestinationPathInfoList.Add(modelFactory.CreateDestinationPathInfo(BackupSourceType.File, destinationFileName)); + + try + { + ZipFile.CreateFromDirectory( + backupInfo.SourcePath, + destinationFileName, + CompressionLevel.Optimal, + false, + Encoding.GetEncoding(Properties.Settings.Default.DefaultZipEncodingKeyText)); + } + catch (Exception e) + { + backupInfo.BackupState = BackupState.Failed; + throw new InvalidOperationException( + string.Format( + "Failed to create the zip archive.\r\n\tFrom: {0}\r\n\tTo: {1}\r\n{2}", + backupInfo.SourcePath, + destinationFileName, + e.Message), + e); + } + finally + { + destinationPathInfoArray = innerDestinationPathInfoList.ToArray(); + } + } + + private static void BackupFile(IBackupInfo backupInfo, out IDestinationPathInfo[] destinationPathInfoArray) + { + var innerDestinationPathInfoList = new List(); + + var modelFactory = ObjectContainer.Resolve(); + + Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath); + Match fileNameMatch = Constants.FileNameRegex.Match(lastPathSegmentMatch.Value); + Match extensionMatch = Constants.ExtensionRegex.Match(lastPathSegmentMatch.Value); + + string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist(); + var destinationFileName = destinationFolderPath + fileNameMatch.Value + + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss") + "." + extensionMatch.Value; + innerDestinationPathInfoList.Add(modelFactory.CreateDestinationPathInfo(BackupSourceType.File, destinationFileName)); + + try + { + File.Copy(backupInfo.SourcePath, destinationFileName); + } + finally + { + destinationPathInfoArray = innerDestinationPathInfoList.ToArray(); + } + } + + private static void BackupFolder(IBackupInfo backupInfo, out IDestinationPathInfo[] destinationPathInfoArray) + { + var innerDestinationPathInfoList = new List(); + + var modelFactory = ObjectContainer.Resolve(); + + Match lastPathSegmentMatch = Constants.EndPathSegmentRegex.Match(backupInfo.SourcePath); + + //// 方法 : ディレクトリをコピーする + //// http://msdn.microsoft.com/ja-jp/library/bb762914(v=vs.110).aspx + string destinationFolderPath = backupInfo.DestinationFolderPath.AddTailPathSeparatorIfNotExist(); + var destinationFolderName = destinationFolderPath + + lastPathSegmentMatch.Value + " - " + DateTime.Now.ToString("yyyyMMdd-HHmmss"); + innerDestinationPathInfoList.Add(modelFactory.CreateDestinationPathInfo(BackupSourceType.Folder, destinationFolderName)); + + try + { + FolderCopy(backupInfo.SourcePath, destinationFolderName, true); + } + finally + { + destinationPathInfoArray = innerDestinationPathInfoList.ToArray(); + } + } + + private static void FolderCopy(string sourceFolderPath, string destinationFolderPath, bool copySubFolders) + { + var sourceDirectoryInfo = new DirectoryInfo(sourceFolderPath); + DirectoryInfo[] subDirectoryInfos = sourceDirectoryInfo.GetDirectories(); + + if (sourceDirectoryInfo.Exists == false) + { + throw new DirectoryNotFoundException( + "Source directory does not exist or could not be found: " + + sourceFolderPath); + } + + // If the destination directory doesn't exist, create it. + if (Directory.Exists(destinationFolderPath) == false) + { + Directory.CreateDirectory(destinationFolderPath); + } + + // Get the files in the directory and copy them to the new location. + FileInfo[] files = sourceDirectoryInfo.GetFiles(); + foreach (FileInfo file in files) + { + string temppath = Path.Combine(destinationFolderPath, file.Name); + file.CopyTo(temppath, false); + } + + // If copying subdirectories, copy them and their contents to new location. + if (copySubFolders) + { + foreach (DirectoryInfo subDirectoryInfo in subDirectoryInfos) + { + string temppath = Path.Combine(destinationFolderPath, subDirectoryInfo.Name); + FolderCopy(subDirectoryInfo.FullName, temppath, copySubFolders); + } + } + } + + private static bool CheckExistence(IDestinationPathInfo[] destinationPathInfoArray) + { + return (destinationPathInfoArray != null) && + (destinationPathInfoArray.Length != 0) && + destinationPathInfoArray.All( + destinationPathInfo => + { + if (destinationPathInfo.BackupSourceType == BackupSourceType.File) + { + return File.Exists(destinationPathInfo.Path); + } + + return Directory.Exists(destinationPathInfo.Path); + }); + } + + private void OnBackupSettingCreated(object sender, SettingFileEventArgs settingFileEventArgs) + { + this.IsReadyForBackup = true; + } + + private void OnBackupSettingOpened(object sender, SettingFileEventArgs settingFileEventArgs) + { + this.IsReadyForBackup = true; + } + + private void OnBackupSettingClosed(object sender, SettingFileEventArgs settingFileEventArgs) + { + this.IsReadyForBackup = false; + } + + private void NotifyBackupProgress(double progressValue, IResultInfo latestResultInfo) + { + if (this.NofityFileBackupProgress != null) + { + this.NofityFileBackupProgress(this, new FileBackupProgressEventArgs(progressValue, latestResultInfo)); + } + } + } +} diff --git a/Main/SimpleBackup.Services/BackupSettingService.cs b/Main/SimpleBackup.Services/BackupSettingService.cs new file mode 100644 index 0000000..2827371 --- /dev/null +++ b/Main/SimpleBackup.Services/BackupSettingService.cs @@ -0,0 +1,591 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using System; + using System.IO; + using System.Linq; + using System.Windows; + using System.Windows.Input; + using System.Xml.Linq; + using SimpleBackup.Core; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Resources; + using Application = System.Windows.Application; + using Cursors = System.Windows.Input.Cursors; + using MessageBox = System.Windows.MessageBox; + using OpenFileDialog = Microsoft.Win32.OpenFileDialog; + using SaveFileDialog = Microsoft.Win32.SaveFileDialog; + + /// + /// Backup Setting service. + /// + internal class BackupSettingService : IBackupSettingService + { + /// + /// The supported major version + /// + private const int SupportedMajorVersion = 1; + + /// + /// The supported minor version + /// + private const int SupportedMinorVersion = 0; + + /// + /// The synchronize root + /// + private static readonly object SyncRoot = new object(); + + /// + /// The instance of SettingFileService. + /// + private static volatile BackupSettingService instance; + + /// + /// Prevents a default instance of the class from being created. + /// + private BackupSettingService() + { + } + + /// + /// Occurs when backup setting is created. + /// + public event EventHandler BackupSettingCreated; + + /// + /// Occurs when backup setting is opened. + /// + public event EventHandler BackupSettingOpened; + + /// + /// Occurs when backup setting is modified. + /// + public event EventHandler BackupSettingModified; + + /// + /// Occurs when backup setting is saved. + /// + public event EventHandler BackupSettingSaved; + + /// + /// Occurs when backup setting is closed. + /// + public event EventHandler BackupSettingClosed; + + /// + /// Gets the instance. + /// + public static IBackupSettingService Instance + { + get + { + if (instance == null) + { + lock (SyncRoot) + { + if (instance == null) + { + instance = new BackupSettingService(); + } + } + } + + return instance; + } + } + + /// + /// Gets the current setting. + /// + public IBackupSetting CurrentSetting { get; private set; } + + /// + /// Creates the backup setting. + /// + /// true if the new backup setting is created; otherwise, false. + public bool CreateBackupSetting() + { + if ((this.CurrentSetting != null) && this.CurrentSetting.Modified) + { + MessageBoxResult confirmationResult = MessageBox.Show( + Application.Current.MainWindow, + Resources.Views_SaveConfirmationMessage, + Resources.Views_ConfirmationDialogTitle, + MessageBoxButton.YesNoCancel); + if (confirmationResult == MessageBoxResult.Yes) + { + this.SaveCurrentBackupSetting(); + } + else if (confirmationResult == MessageBoxResult.Cancel) + { + return false; + } + } + + if (this.CurrentSetting != null) + { + this.CloseCurrentBackupSetting(); + } + + var modelFactory = ObjectContainer.Resolve(); + + IBackupSetting backupSetting = modelFactory.CreateBackupSetting(); + this.CurrentSetting = backupSetting; + this.CurrentSetting.SettingModified += this.OnCurrentSettingModified; + + if (this.BackupSettingCreated != null) + { + this.BackupSettingCreated(this, new SettingFileEventArgs(this.CurrentSetting.SettingName)); + } + + return true; + } + + /// + /// Opens the backup setting. + /// + /// The result message. + /// + /// true if backup setting is successfully loaded; otherwise, false. + /// + public bool OpenBackupSetting(out string resultMessage) + { + if ((this.CurrentSetting != null) && this.CurrentSetting.Modified) + { + MessageBoxResult confirmationResult = MessageBox.Show( + Application.Current.MainWindow, + Resources.Views_SaveConfirmationMessage, + Resources.Views_ConfirmationDialogTitle, + MessageBoxButton.YesNoCancel); + if (confirmationResult == MessageBoxResult.Yes) + { + this.SaveCurrentBackupSetting(); + } + else if (confirmationResult == MessageBoxResult.Cancel) + { + resultMessage = string.Empty; + return false; + } + } + + string initialDirectory = AppDomain.CurrentDomain.BaseDirectory; + if ((this.CurrentSetting != null) && + this.CurrentSetting.SettingFileName.IsValidFilePath()) + { + initialDirectory = Path.GetDirectoryName(this.CurrentSetting.SettingFileName); + this.CloseBackupSetting(); + } + + var openFileDialog = new OpenFileDialog + { + Title = Resources.Views_OpenFileDialogTitle, + DefaultExt = ".xml", + Filter = "Backup Setting File|*.xml", + InitialDirectory = initialDirectory, + Multiselect = false + }; + + if (openFileDialog.ShowDialog(Application.Current.MainWindow) != true) + { + resultMessage = string.Empty; + return false; + } + + var fileName = openFileDialog.FileName; + try + { + Mouse.OverrideCursor = Cursors.Wait; + return this.OpenBackupSetting(fileName, out resultMessage); + } + finally + { + Mouse.OverrideCursor = null; + } + } + + /// + /// Closes the backup setting. + /// + public void CloseBackupSetting() + { + if (this.CurrentSetting == null) + { + return; + } + + if (this.CurrentSetting.Modified) + { + MessageBoxResult confirmationResult = MessageBox.Show( + Application.Current.MainWindow, + Resources.Views_SaveConfirmationMessage, + Resources.Views_ConfirmationDialogTitle, + MessageBoxButton.YesNoCancel); + if (confirmationResult == MessageBoxResult.Yes) + { + this.SaveCurrentBackupSetting(); + } + else if (confirmationResult == MessageBoxResult.Cancel) + { + return; + } + } + + this.CloseCurrentBackupSetting(); + } + + /// + /// Overwrites the currnt backup setting. + /// + /// true if the backup setting is saved; otherwise, false. + public bool OverWriteCurrntBackupSetting() + { + if (this.CurrentSetting == null) + { + return false; + } + + if (string.IsNullOrEmpty(this.CurrentSetting.SettingFileName) || + (File.Exists(this.CurrentSetting.SettingFileName) == false)) + { + var saveFileDialog = new SaveFileDialog + { + Title = Resources.Views_SaveFileDialogTitle, + DefaultExt = ".xml", + Filter = "Backup Setting File|*.xml" + }; + + if (saveFileDialog.ShowDialog(Application.Current.MainWindow) != true) + { + return false; + } + + this.CurrentSetting.SettingFileName = saveFileDialog.FileName; + } + + this.SaveCurrentBackupSetting(); + return true; + } + + /// + /// Saves the current backup setting as a new file. + /// + /// true if the backup setting is saved; otherwise, false. + public bool SaveCurrentBackupSettingAsNewFile() + { + if (this.CurrentSetting == null) + { + return false; + } + + var saveFileDialog = new SaveFileDialog + { + Title = Resources.Views_SaveFileDialogTitle, + DefaultExt = ".xml", + Filter = "Backup Setting File|*.xml" + }; + + if (saveFileDialog.ShowDialog(Application.Current.MainWindow) != true) + { + return false; + } + + this.CurrentSetting.SettingFileName = saveFileDialog.FileName; + + this.SaveCurrentBackupSetting(); + return true; + } + + /// + /// Opens the default backup setting. + /// + /// The result message. + /// + /// true if succeeded, otherwise; false. + /// + public bool OpenDefaultBackupSetting(out string resultMessage) + { + return this.OpenBackupSetting( + Properties.Settings.Default.DefaultSettingFileName, + out resultMessage); + } + + /// + /// Creates the backup information. + /// + /// The index. + /// The created backup information. + /// + public IBackupInfo CreateBackupInfo(int index) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + var modelFactory = ObjectContainer.Resolve(); + + IBackupInfo backupInfo = modelFactory.CreateBackupInfo(); + this.CurrentSetting.Insert(index, backupInfo); + return backupInfo; + } + + /// + /// Copies the backup information. + /// + /// The source backup information. + /// A copied BackupInfo. + /// + public IBackupInfo CopyBackupInfo(IBackupInfo sourceBackupInfo) + { + sourceBackupInfo.ThrowsArgumentNullException("sourceBackupInfo"); + + var modelFactory = ObjectContainer.Resolve(); + return modelFactory.CreateBackupInfo(sourceBackupInfo); + } + + /// + /// Inserts the backup information. + /// + /// The index. + /// The backup information. + /// + /// + public void InsertBackupInfo(int index, IBackupInfo backupInfo) + { + if (index > this.CurrentSetting.Count) + { + throw new ArgumentOutOfRangeException("index"); + } + + backupInfo.ThrowsArgumentNullException("backupInfo"); + + this.CurrentSetting.Insert(index, backupInfo); + } + + /// + /// Removes the backup information. + /// + /// The backup information identifier. + public void RemoveBackupInfo(Guid backupInfoId) + { + IBackupInfo removingBackupInfo = + this.CurrentSetting.FirstOrDefault(backupInfoId); + if (removingBackupInfo == null) + { + return; + } + + this.CurrentSetting.Remove(removingBackupInfo); + } + + /// + /// Saves the backup setting. + /// + /// The backup setting. + private static void SaveBackupSetting(IBackupSetting backupSetting) + { + var xdoc = new XDocument { Declaration = new XDeclaration("1.0", "utf-8", "yes") }; + xdoc.Add(backupSetting.ToXml()); + + xdoc.Save(backupSetting.SettingFileName, SaveOptions.None); + } + + /// + /// Opens the backup setting. + /// + /// Name of the file. + /// The result message. + /// + /// true if succeeded; otherwise, false. + /// + private bool OpenBackupSetting(string fileName, out string resultMessage) + { + resultMessage = string.Empty; + + if (string.IsNullOrEmpty(fileName)) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_EmptyFileNameFormat, + fileName); + return false; + } + + XDocument xml = XDocument.Load(fileName, LoadOptions.None); + XElement backupSettingElement = xml.Elements("BackupSetting").FirstOrDefault(); + if (backupSettingElement == null) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_NoBackupSettingElementFormat, + fileName); + return false; + } + + XAttribute versionAttribute = backupSettingElement.Attributes().FirstOrDefault(p => p.Name == "Version"); + if (versionAttribute == null) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_NoVersionElementFormat, + fileName); + return false; + } + + string[] versionTextFlagments = versionAttribute.Value.Split('.'); + if (versionTextFlagments.Length != 2) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_InvalidVersionFormat, + fileName); + return false; + } + + int majorVersion; + if (int.TryParse(versionTextFlagments[0], out majorVersion) == false) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_InvalidMajorVersionFormat, + fileName); + return false; + } + + int minorVersion; + if (int.TryParse(versionTextFlagments[1], out minorVersion) == false) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_InvalidMinorVersionFormat, + fileName); + return false; + } + + XAttribute requiredToolVersionAttribute = backupSettingElement.Attributes().FirstOrDefault(p => p.Name == "RequiredToolVersion"); + if (requiredToolVersionAttribute == null) + { + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_InvalidRequiredToolVersionFormat, + fileName); + return false; + } + + if (majorVersion > SupportedMajorVersion) + { + string message = string.Format( + Resources.BackupSetting_IncompatibleMajorVersionFormat, + requiredToolVersionAttribute.Value); + MessageBox.Show( + Application.Current.MainWindow, + message, + Resources.Views_DefaultWindowTitle, + MessageBoxButton.OK, + MessageBoxImage.Error); + resultMessage = message; + return false; + } + + if (minorVersion > SupportedMinorVersion) + { + string message = string.Format( + Resources.BackupSetting_IncompatibleMinorVersionFormat, + requiredToolVersionAttribute.Value); + MessageBox.Show( + Application.Current.MainWindow, + message, + Resources.Views_DefaultWindowTitle, + MessageBoxButton.OK, + MessageBoxImage.Warning); + resultMessage = message + "\r\n"; + } + + var modelFactory = ObjectContainer.Resolve(); + if (modelFactory != null) + { + IBackupSetting backupSetting = modelFactory.RestoreBackupSettingFromXml(backupSettingElement, fileName); + this.CurrentSetting = backupSetting; + this.CurrentSetting.SettingModified += this.OnCurrentSettingModified; + if (this.BackupSettingOpened != null) + { + this.BackupSettingOpened(this, new SettingFileEventArgs(backupSetting.SettingFileName)); + } + + resultMessage += string.Format(Resources.BackupSetting_SettingOpenedFormat, fileName); + return true; + } + + resultMessage = string.Format( + Resources.BackupSetting_FailedToOpenSetting_EmptyFileNameFormat, + fileName); + return false; + } + + /// + /// Saves the current backup setting. + /// + private void SaveCurrentBackupSetting() + { + try + { + Mouse.OverrideCursor = Cursors.Wait; + + SaveBackupSetting(this.CurrentSetting); + + this.CurrentSetting.Modified = false; + } + finally + { + Mouse.OverrideCursor = null; + } + + if (this.BackupSettingSaved != null) + { + this.BackupSettingSaved(this, new SettingFileEventArgs(this.CurrentSetting.SettingFileName)); + } + } + + private void CloseCurrentBackupSetting() + { + UndoRedoService.Instance.ClearUndoRedoBuffer(); + string settingName = this.CurrentSetting.SettingFileName; + this.CurrentSetting.SettingModified -= this.OnCurrentSettingModified; + this.CurrentSetting = null; + + if (this.BackupSettingClosed != null) + { + this.BackupSettingClosed(this, new SettingFileEventArgs(settingName)); + } + } + + /// + /// Called when current setting is modified. + /// + /// The sender. + /// The instance containing the event data. + private void OnCurrentSettingModified(object sender, EventArgs eventArgs) + { + if (this.BackupSettingModified != null) + { + this.BackupSettingModified(this, new SettingFileEventArgs(this.CurrentSetting.SettingName)); + } + } + } +} diff --git a/Main/SimpleBackup.Services/ClipboardService.cs b/Main/SimpleBackup.Services/ClipboardService.cs new file mode 100644 index 0000000..2efd783 --- /dev/null +++ b/Main/SimpleBackup.Services/ClipboardService.cs @@ -0,0 +1,139 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using System; + using System.Linq; + using System.Windows; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + + /// + /// Provides clip board access. + /// + internal class ClipboardService : IClipboardService + { + private static readonly object SyncRoot = new object(); + private static volatile ClipboardService instance; + + /// + /// Prevents a default instance of the class from being created. + /// + private ClipboardService() + { + } + + /// + /// Gets the instance. + /// + public static IClipboardService Instance + { + get + { + if (instance == null) + { + lock (SyncRoot) + { + if (instance == null) + { + instance = new ClipboardService(); + } + } + } + + return instance; + } + } + + /// + /// Sets the data object. + /// + /// The data object. + /// The data object is null. + public void SetDataObject(IDataObject dataObject) + { + dataObject.ThrowsArgumentNullException("dataObject"); + + Clipboard.SetDataObject(dataObject); + } + + /// + /// Gets the data. + /// + /// The type. + /// The format. + /// + /// The data. + /// + /// The format string is null or empty. + public T GetData(string format) + { + format.ThrowsArgumentExceptionIfNullOrEmpty("format"); + + IDataObject dataObject = Clipboard.GetDataObject(); + if (dataObject != null) + { + if (dataObject.GetDataPresent(format)) + { + try + { + return (T)dataObject.GetData(format); + } + catch + { + return default(T); + } + } + } + + return default(T); + } + + /// + /// Gets a boolean value indicating whether the clipboard data contains data in specified format. + /// + /// The format. + /// The format string is null or empty. + /// True if the specified format is contained in the Clipboard. + public bool DoesClipboardDataContain(string format) + { + format.ThrowsArgumentExceptionIfNullOrEmpty("format"); + + IDataObject dataObject = Clipboard.GetDataObject(); + if (dataObject != null) + { + string[] formats = dataObject.GetFormats(); + return formats.Contains(format); + } + + return false; + } + + /// + /// Clears the clipbord. + /// + public void ClearClipbord() + { + Clipboard.Clear(); + } + } +} diff --git a/Main/SimpleBackup.Services/Properties/Settings.Designer.cs b/Main/SimpleBackup.Services/Properties/Settings.Designer.cs new file mode 100644 index 0000000..fdf4566 --- /dev/null +++ b/Main/SimpleBackup.Services/Properties/Settings.Designer.cs @@ -0,0 +1,50 @@ +//------------------------------------------------------------------------------ +// +// このコードはツールによって生成されました。 +// ランタイム バージョン:4.0.30319.34014 +// +// このファイルへの変更は、以下の状況下で不正な動作の原因になったり、 +// コードが再生成されるときに損失したりします。 +// +//------------------------------------------------------------------------------ + +namespace SimpleBackup.Services.Properties { + + + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")] + internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase { + + private static Settings defaultInstance = ((Settings)(global::System.Configuration.ApplicationSettingsBase.Synchronized(new Settings()))); + + public static Settings Default { + get { + return defaultInstance; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DefaultSettingFileName { + get { + return ((string)(this["DefaultSettingFileName"])); + } + set { + this["DefaultSettingFileName"] = value; + } + } + + [global::System.Configuration.UserScopedSettingAttribute()] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Configuration.DefaultSettingValueAttribute("")] + public string DefaultZipEncodingKeyText { + get { + return ((string)(this["DefaultZipEncodingKeyText"])); + } + set { + this["DefaultZipEncodingKeyText"] = value; + } + } + } +} diff --git a/Main/SimpleBackup.Services/Properties/Settings.settings b/Main/SimpleBackup.Services/Properties/Settings.settings new file mode 100644 index 0000000..4973a97 --- /dev/null +++ b/Main/SimpleBackup.Services/Properties/Settings.settings @@ -0,0 +1,12 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Services/ServiceComponent.cs b/Main/SimpleBackup.Services/ServiceComponent.cs new file mode 100644 index 0000000..46a15e4 --- /dev/null +++ b/Main/SimpleBackup.Services/ServiceComponent.cs @@ -0,0 +1,45 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using SimpleBackup.Core; + using SimpleBackup.Core.AppInfrastructure; + using SimpleBackup.Core.Services; + + /// + /// The service component. + /// + internal class ServiceComponent : IAppComponent + { + /// + /// Initializes this application component. + /// + public void Initialize() + { + ObjectContainer.Register(BackupService.Instance); + ObjectContainer.Register(BackupSettingService.Instance); + ObjectContainer.Register(ClipboardService.Instance); + ObjectContainer.Register(SettingsService.Instance); + ObjectContainer.Register(UndoRedoService.Instance); + } + } +} diff --git a/Main/SimpleBackup.Services/SettingsService.cs b/Main/SimpleBackup.Services/SettingsService.cs new file mode 100644 index 0000000..98aa9b0 --- /dev/null +++ b/Main/SimpleBackup.Services/SettingsService.cs @@ -0,0 +1,110 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using SimpleBackup.Core.Services; + + /// + /// Provides application setting. + /// + internal class SettingsService : ISettingsService + { + /// + /// The synchronize root. + /// + private static readonly object SyncRoot = new object(); + + /// + /// The instance of SettingsService. + /// + private static volatile SettingsService instance; + + /// + /// Prevents a default instance of the class from being created. + /// + private SettingsService() + { + } + + /// + /// Gets the instance. + /// + public static ISettingsService Instance + { + get + { + if (instance == null) + { + lock (SyncRoot) + { + if (instance == null) + { + instance = new SettingsService(); + } + } + } + + return instance; + } + } + + /// + /// Gets or sets the default name of the setting file. + /// + public string DefaultSettingFileName + { + get + { + return Properties.Settings.Default.DefaultSettingFileName; + } + + set + { + if (Properties.Settings.Default.DefaultSettingFileName != value) + { + Properties.Settings.Default.DefaultSettingFileName = value; + Properties.Settings.Default.Save(); + } + } + } + + /// + /// Gets or sets the default zip encoding key text. + /// + public string DefaultZipEncodingKeyText + { + get + { + return Properties.Settings.Default.DefaultZipEncodingKeyText; + } + + set + { + if (Properties.Settings.Default.DefaultZipEncodingKeyText != value) + { + Properties.Settings.Default.DefaultZipEncodingKeyText = value; + Properties.Settings.Default.Save(); + } + } + } + } +} diff --git a/Main/SimpleBackup.Services/SimpleBackup.Services.csproj b/Main/SimpleBackup.Services/SimpleBackup.Services.csproj new file mode 100644 index 0000000..c36f0ae --- /dev/null +++ b/Main/SimpleBackup.Services/SimpleBackup.Services.csproj @@ -0,0 +1,108 @@ + + + + + Debug + AnyCPU + {950EE3DF-1731-49B7-94C2-F33154855782} + Library + Properties + SimpleBackup.Services + SimpleBackup.Services + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + False + ..\Lib\Expression\Blend\.NETFramework\v4.5\Libraries\System.Windows.Interactivity.dll + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + + + + True + True + Settings.settings + + + + + + + + + + SettingsSingleFileGenerator + Settings.Designer.cs + + + + + + {33f1d454-9962-4eb6-aad3-8d11d9a78d1f} + SimpleBackup.Core + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + + + + + set EXE_BIN_DIR=$(ProjectDir)..\bin\$(ConfigurationName)\ +xcopy "$(TargetDir)$(TargetName).dll" "%25EXE_BIN_DIR%25" /Y +if exist "$(TargetDir)$(TargetName).pdb" xcopy "$(TargetDir)$(TargetName).pdb" "%25EXE_BIN_DIR%25" /Y + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Services/SimpleBackupKey.snk b/Main/SimpleBackup.Services/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.Services/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.Services/UndoRedoActionSet.cs b/Main/SimpleBackup.Services/UndoRedoActionSet.cs new file mode 100644 index 0000000..db4bb14 --- /dev/null +++ b/Main/SimpleBackup.Services/UndoRedoActionSet.cs @@ -0,0 +1,71 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using System; + using SimpleBackup.Core.Utilities; + + /// + /// Provides undo/redo function. + /// + internal partial class UndoRedoService + { + /// + /// Represents a pair of undo/redo actions and its context information. + /// + private class UndoRedoActionSet + { + /// + /// Initializes a new instance of the class. + /// + /// The redo action. + /// The undo action. + /// The context. + /// The redoAction is null. + /// The undoAction is null. + public UndoRedoActionSet(Action redoAction, Action undoAction, object context) + { + redoAction.ThrowsArgumentNullException("redoAction"); + undoAction.ThrowsArgumentNullException("undoAction"); + + this.RedoAction = redoAction; + this.UndoAction = undoAction; + this.Context = context; + } + + /// + /// Gets the redo action. + /// + public Action RedoAction { get; private set; } + + /// + /// Gets the undo action. + /// + public Action UndoAction { get; private set; } + + /// + /// Gets the context. + /// + public object Context { get; private set; } + } + } +} diff --git a/Main/SimpleBackup.Services/UndoRedoService.cs b/Main/SimpleBackup.Services/UndoRedoService.cs new file mode 100644 index 0000000..5e221b3 --- /dev/null +++ b/Main/SimpleBackup.Services/UndoRedoService.cs @@ -0,0 +1,144 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Services +{ + using System; + using System.Collections.Generic; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + + /// + /// Provides undo/redo function. + /// + internal partial class UndoRedoService : IUndoRedoService + { + private static readonly object SyncRoot = new object(); + private static volatile UndoRedoService instance; + + private readonly Stack actionSetsForUndo = new Stack(); + private readonly Stack actionSetsForRedo = new Stack(); + + /// + /// Prevents a default instance of the class from being created. + /// + private UndoRedoService() + { + } + + /// + /// Gets the instance. + /// + public static IUndoRedoService Instance + { + get + { + if (instance == null) + { + lock (SyncRoot) + { + if (instance == null) + { + instance = new UndoRedoService(); + } + } + } + + return instance; + } + } + + /// + /// Commits the specified redo action with related undo action and the context information. + /// + /// The redo action. + /// The undo action. + /// The context. + /// The redoAction is null. + /// The undoAction is null. + public void Commit(Action redoAction, Action undoAction, object context) + { + redoAction.ThrowsArgumentNullException("redoAction"); + undoAction.ThrowsArgumentNullException("undoAction"); + + var undoRedoActionSet = new UndoRedoActionSet(redoAction, undoAction, context); + this.actionSetsForUndo.Push(undoRedoActionSet); + redoAction.Invoke(undoRedoActionSet.Context); + } + + /// + /// Executes undo action. + /// + public void Undo() + { + if (this.CanExecuteUndo() == false) + { + return; + } + + UndoRedoActionSet undoRedoActionSet = this.actionSetsForUndo.Pop(); + undoRedoActionSet.UndoAction.Invoke(undoRedoActionSet.Context); + this.actionSetsForRedo.Push(undoRedoActionSet); + } + + /// + /// Determines whether the undo action is executable. + /// + /// true if the undo action can be executable; otherwise, false. + public bool CanExecuteUndo() + { + return this.actionSetsForUndo.Count != 0; + } + + /// + /// Executes redo action. + /// + public void Redo() + { + if (this.CanExecuteRedo() == false) + { + return; + } + + UndoRedoActionSet undoRedoActionSet = this.actionSetsForRedo.Pop(); + undoRedoActionSet.RedoAction.Invoke(undoRedoActionSet.Context); + this.actionSetsForUndo.Push(undoRedoActionSet); + } + + /// + /// Determines whether the redo action is executable. + /// + /// true if the redo action can be executable; otherwise, false. + public bool CanExecuteRedo() + { + return this.actionSetsForRedo.Count != 0; + } + + /// + /// Clears the undo redo buffer. + /// + public void ClearUndoRedoBuffer() + { + this.actionSetsForUndo.Clear(); + this.actionSetsForRedo.Clear(); + } + } +} diff --git a/Main/SimpleBackup.Services/app.config b/Main/SimpleBackup.Services/app.config new file mode 100644 index 0000000..632bc35 --- /dev/null +++ b/Main/SimpleBackup.Services/app.config @@ -0,0 +1,18 @@ + + + + +
+ + + + + + + + + + + + + \ No newline at end of file diff --git a/Main/SimpleBackup.ViewModels/BackupInfoPasteInfo.cs b/Main/SimpleBackup.ViewModels/BackupInfoPasteInfo.cs new file mode 100644 index 0000000..d169528 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/BackupInfoPasteInfo.cs @@ -0,0 +1,67 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using System; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Core.ViewModels; + + /// + /// Paste information of BackupInfo. + /// + [Serializable] + internal class BackupInfoPasteInfo + { + /// + /// Initializes a new instance of the class. + /// + /// The backup information bytes. + /// Type of the paste. + /// Index of the source backup information view model. + public BackupInfoPasteInfo( + byte[] backupInfoBytes, + PasteType pasteType, + int sourceIndex) + { + backupInfoBytes.ThrowsArgumentNullException("backupInfoBytes"); + + this.BackupInfoBytes = backupInfoBytes; + this.PasteType = pasteType; + this.SourceIndex = sourceIndex; + } + + /// + /// Gets the backup information bytes. + /// + public byte[] BackupInfoBytes { get; private set; } + + /// + /// Gets the type of the paste. + /// + public PasteType PasteType { get; private set; } + + /// + /// Gets the index of the source backup information view model. + /// + public int SourceIndex { get; private set; } + } +} diff --git a/Main/SimpleBackup.ViewModels/BackupInfoViewModel.cs b/Main/SimpleBackup.ViewModels/BackupInfoViewModel.cs new file mode 100644 index 0000000..c4ac97f --- /dev/null +++ b/Main/SimpleBackup.ViewModels/BackupInfoViewModel.cs @@ -0,0 +1,794 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using System; + using System.ComponentModel; + using System.IO; + using System.Text.RegularExpressions; + using System.Windows.Forms; + using System.Windows.Input; + using SimpleBackup.Core; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Core.ViewModels; + using SimpleBackup.Core.Views; + using SimpleBackup.Resources; + + /// + /// Backup information view model. + /// + internal class BackupInfoViewModel : PropertyChangeNotificationBase, IBackupInfoViewModel + { + private readonly IBackupService backupService; + private readonly IBackupSettingService backupSettingService; + private readonly IViewFactory viewFactory; + + private readonly IBackupInfo backupInfoModel; + + private readonly Action clearOutputMessageAction; + + private readonly Action addOutputMessageAction; + + private bool innerHasSourcePathError; + + private bool innerHasDestinationFolderPathError; + + private bool innerIsSourceEditing; + + private string innerEditingSourcePath = string.Empty; + + private bool innerIsDestinationEditing; + + private string innerEditingDestinationPath = string.Empty; + + private bool innerIsCutReserved; + + /// + /// Initializes a new instance of the class. + /// + /// The backup information model. + /// The clear output message action. + /// The add output message action. + private BackupInfoViewModel( + IBackupInfo backupInfoModel, + Action clearOutputMessageAction, + Action addOutputMessageAction) + { + backupInfoModel.ThrowsArgumentNullException("backupInfoModel"); + clearOutputMessageAction.ThrowsArgumentNullException("clearOutputMessageAction"); + addOutputMessageAction.ThrowsArgumentNullException("addOutputMessageAction"); + + this.backupInfoModel = backupInfoModel; + this.backupInfoModel.PropertyChanged += this.OnBackupInfoModelPropertyChanged; + this.clearOutputMessageAction = clearOutputMessageAction; + this.addOutputMessageAction = addOutputMessageAction; + + this.backupService = ObjectContainer.Resolve(); + this.backupSettingService = ObjectContainer.Resolve(); + this.viewFactory = ObjectContainer.Resolve(); + + this.OpenSourceFileRelayCommand = new RelayCommand(this.ExecuteOpenSourceFile, this.CanExecuteOpenSourceFile); + this.OpenSourceFolderRelayCommand = new RelayCommand(this.ExecuteOpenSourceFolder, this.CanExecuteOpenSourceFolder); + this.SelectSourceRelayCommand = new RelayCommand(this.ExecuteSelectSource, this.CanExecuteSelectSource); + this.OpenDestinationFolderRelayCommand = new RelayCommand(this.ExecuteOpenDestinationFolder, this.CanExecuteOpenDestinationFolder); + this.SelectDestinationRelayCommand = new RelayCommand(this.ExecuteSelectDestination, this.CanExecuteSelectDestination); + this.EditSourceRelayCommand = new RelayCommand(this.ExecuteEditSource, this.CanExecuteEditSource); + this.EditDestinationRelayCommand = new RelayCommand(this.ExecuteEditDestination, this.CanExecuteEditDestination); + this.SingleBackupRelayCommand = new RelayCommand(this.ExecuteSingleBackup, this.CanExecuteSingleBackup); + + this.UpdateErrorStatus(); + } + + /// + /// Gets the open source file relay command. + /// + public RelayCommand OpenSourceFileRelayCommand { get; private set; } + + /// + /// Gets the open source folder relay command. + /// + public RelayCommand OpenSourceFolderRelayCommand { get; private set; } + + /// + /// Gets the select source relay command. + /// + public RelayCommand SelectSourceRelayCommand { get; private set; } + + /// + /// Gets the open destination folder relay command. + /// + public RelayCommand OpenDestinationFolderRelayCommand { get; private set; } + + /// + /// Gets the select destination relay command. + /// + public RelayCommand SelectDestinationRelayCommand { get; private set; } + + /// + /// Gets the edit source relay command. + /// + public RelayCommand EditSourceRelayCommand { get; private set; } + + /// + /// Gets the edit destination relay command. + /// + public RelayCommand EditDestinationRelayCommand { get; private set; } + + /// + /// Gets the single backup with context menu relay command. + /// + public RelayCommand SingleBackupRelayCommand { get; private set; } + + /// + /// Gets the backup information identifier. + /// + public Guid BackupInfoId + { + get + { + return this.backupInfoModel.Id; + } + } + + /// + /// Gets the type of the source. + /// + public BackupSourceType SourceType + { + get + { + return this.backupInfoModel.BackupSourceType; + } + } + + /// + /// Gets the state of the backup. + /// + public BackupState BackupState + { + get + { + return this.backupInfoModel.BackupState; + } + } + + /// + /// Gets or sets a value indicating whether the backup is enabled. + /// + public bool IsEnabled + { + get + { + return this.backupInfoModel.IsEnabled; + } + + set + { + if (this.backupInfoModel.IsEnabled != value) + { + this.backupInfoModel.IsEnabled = value; + this.NotifyPropertyChanged("IsEnabled"); + } + } + } + + /// + /// Gets or sets a value indicating whether the backup is zip archive. + /// + public bool IsZipArchive + { + get + { + return this.backupInfoModel.IsZipArchive; + } + + set + { + if (this.backupInfoModel.IsZipArchive != value) + { + this.backupInfoModel.IsZipArchive = value; + this.NotifyPropertyChanged("IsZipArchive"); + } + } + } + + /// + /// Gets or sets the label. + /// + public string Label + { + get + { + return this.backupInfoModel.Label; + } + + set + { + if (this.backupInfoModel.Label != value) + { + this.backupInfoModel.Label = value; + this.NotifyPropertyChanged("Label"); + } + } + } + + /// + /// Gets or sets the source path. + /// + public string SourcePath + { + get + { + return this.backupInfoModel.SourcePath; + } + + set + { + if ((this.backupInfoModel.SourcePath != value) && + value.IsValidFileOrDirectoryPath()) + { + this.backupInfoModel.SourcePath = value; + this.UpdateErrorStatus(); + this.NotifyPropertyChanged("SourcePath"); + this.NotifyPropertyChanged("DisplaySourcePath"); + } + } + } + + /// + /// Gets the display source path. + /// + public string DisplaySourcePath + { + get + { + return Helpers.CreateDisplayPathText(this.backupInfoModel.SourcePath); + } + } + + /// + /// Gets or sets the editing source path. + /// + public string EditingSourcePath + { + get + { + return this.innerEditingSourcePath; + } + + set + { + if (this.innerEditingSourcePath != value) + { + this.innerEditingSourcePath = value; + this.NotifyPropertyChanged("EditingSourcePath"); + } + } + } + + /// + /// Gets the source tool tip text. + /// + public string SourceToolTipText + { + get + { + Match match = Constants.EndPathSegmentRegex.Match(this.backupInfoModel.SourcePath); + return match.Success ? match.Value : string.Empty; + } + } + + /// + /// Gets or sets a value indicating whether this instance is source editing. + /// + public bool IsSourceEditing + { + get + { + return this.innerIsSourceEditing; + } + + set + { + if (this.innerIsSourceEditing != value) + { + this.innerIsSourceEditing = value; + this.NotifyPropertyChanged("IsSourceEditing"); + } + } + } + + /// + /// Gets a value indicating whether this instance has source path error. + /// + public bool HasSourcePathError + { + get + { + return this.innerHasSourcePathError; + } + + private set + { + if (this.innerHasSourcePathError != value) + { + this.innerHasSourcePathError = value; + this.NotifyPropertyChanged("HasSourcePathError"); + } + } + } + + /// + /// Gets or sets the destination folder path. + /// + public string DestinationFolderPath + { + get + { + return this.backupInfoModel.DestinationFolderPath; + } + + set + { + if ((this.backupInfoModel.DestinationFolderPath != value) && + value.IsValidFileOrDirectoryPath()) + { + this.backupInfoModel.DestinationFolderPath = value; + this.UpdateErrorStatus(); + this.NotifyPropertyChanged("DestinationFolderPath"); + this.NotifyPropertyChanged("DisplayDestinationFolderPath"); + } + } + } + + /// + /// Gets the display destination folder path. + /// + public string DisplayDestinationFolderPath + { + get + { + return Helpers.CreateDisplayPathText( + Regex.Replace(this.backupInfoModel.DestinationFolderPath, @"\\$", string.Empty)); + } + } + + /// + /// Gets or sets the editing destination path. + /// + public string EditingDestinationPath + { + get + { + return this.innerEditingDestinationPath; + } + + set + { + if (this.innerEditingDestinationPath != value) + { + this.innerEditingDestinationPath = value; + this.NotifyPropertyChanged("EditingDestinationPath"); + } + } + } + + /// + /// Gets the destination tool tip text. + /// + public string DestinationToolTipText + { + get + { + string endSeparatorRemovedPath = Constants.EndPathSeparatorRegex.Replace(this.backupInfoModel.DestinationFolderPath, string.Empty); + Match match = Constants.EndPathSegmentRegex.Match(endSeparatorRemovedPath); + return match.Success ? match.Value : string.Empty; + } + } + + /// + /// Gets or sets a value indicating whether this instance is destination editing. + /// + public bool IsDestinationEditing + { + get + { + return this.innerIsDestinationEditing; + } + + set + { + if (this.innerIsDestinationEditing != value) + { + this.innerIsDestinationEditing = value; + this.NotifyPropertyChanged("IsDestinationEditing"); + } + } + } + + /// + /// Gets a value indicating whether this instance has destination folder path error. + /// + public bool HasDestinationFolderPathError + { + get + { + return this.innerHasDestinationFolderPathError; + } + + private set + { + if (this.innerHasDestinationFolderPathError != value) + { + this.innerHasDestinationFolderPathError = value; + this.NotifyPropertyChanged("HasDestinationFolderPathError"); + } + } + } + + /// + /// Gets a value indicating whether this instance is editing. + /// + public bool IsEditing + { + get + { + return this.IsSourceEditing || this.IsDestinationEditing; + } + } + + /// + /// Gets or sets a value indicating whether this instance is cut reserved. + /// + public bool IsCutReserved + { + get + { + return this.innerIsCutReserved; + } + + set + { + if (this.innerIsCutReserved != value) + { + this.innerIsCutReserved = value; + this.NotifyPropertyChanged("IsCutReserved"); + } + } + } + + /// + /// Creates the backup information view mode. + /// + /// The backup information model. + /// The clear output message action. + /// The add output message action. + /// The backup information view model. + public static IBackupInfoViewModel CreateBackupInfoViewMode( + IBackupInfo backupInfoModel, + Action clearOutputMessageAction, + Action addOutputMessageAction) + { + return new BackupInfoViewModel( + backupInfoModel, + clearOutputMessageAction, + addOutputMessageAction); + } + + /// + /// Gets the backup information. + /// + /// The backup information. + public IBackupInfo GetBackupInfo() + { + return this.backupInfoModel; + } + + /// + /// Executes the double click action. + /// + /// Type of the path. + public void ExecuteDoubleClickAction(BackupInfoPathType pathType) + { + switch (pathType) + { + case BackupInfoPathType.Source: + if (this.SourcePath.IsValidFileOrDirectoryPath()) + { + this.SingleBackup(); + } + else + { + string extractedPath; + this.SelectSource( + Helpers.TryExtractValidFolderPath(this.SourcePath, out extractedPath) + ? extractedPath + : string.Empty); + } + + break; + case BackupInfoPathType.Destination: + if (this.DestinationFolderPath.IsValidFileOrDirectoryPath()) + { + this.ExecuteOpenDestinationFolder(null); + } + else + { + string extractedPath; + this.SelectDestination( + Helpers.TryExtractValidFolderPath(this.DestinationFolderPath, out extractedPath) + ? extractedPath + : string.Empty); + } + + break; + } + } + + /// + /// Executes single backup. + /// + public void SingleBackup() + { + try + { + Mouse.OverrideCursor = System.Windows.Input.Cursors.Wait; + + this.clearOutputMessageAction(); + Helpers.UpdateWpfGui(); + this.addOutputMessageAction(Resources.Backup_ExecutingBackup); + Helpers.UpdateWpfGui(); + + IResultInfo resultInfo = this.backupService.BackupSingleFile(this.BackupInfoId); + this.addOutputMessageAction(string.Format("{0}: {1}", resultInfo.BackupState.Translate(), resultInfo.Description)); + } + finally + { + Mouse.OverrideCursor = null; + } + } + + /// + /// Commits the editing contents. + /// + public void CommitEditingContents() + { + if (this.IsSourceEditing) + { + // Path validation is executed in SourcePath setter. + this.SourcePath = this.EditingSourcePath; + this.EditingSourcePath = string.Empty; + this.IsSourceEditing = false; + } + + if (this.IsDestinationEditing) + { + // Path validation is executed in DestinationFolderPath setter. + this.DestinationFolderPath = this.EditingDestinationPath; + this.EditingDestinationPath = string.Empty; + this.IsDestinationEditing = false; + } + } + + /// + /// Resets the state of the backup. + /// + public void ResetBackupState() + { + this.backupInfoModel.BackupState = BackupState.Todo; + this.UpdateErrorStatus(); + } + + private void OnBackupInfoModelPropertyChanged( + object sender, + PropertyChangedEventArgs propertyChangedEventArgs) + { + if (propertyChangedEventArgs.PropertyName == "BackupState") + { + this.NotifyPropertyChanged("BackupState"); + } + } + + private void ExecuteOpenSourceFile(object obj) + { + if (this.CanExecuteOpenSourceFile(obj) == false) + { + return; + } + + Helpers.OpenFile(this.SourcePath); + } + + private bool CanExecuteOpenSourceFile(object obj) + { + return (this.backupService.IsExecutingBackup == false) && + (this.backupInfoModel.BackupSourceType == BackupSourceType.File); + } + + private void ExecuteOpenSourceFolder(object obj) + { + Helpers.OpenParentFolderAndSelect(this.SourcePath); + } + + private bool CanExecuteOpenSourceFolder(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteSelectSource(object obj) + { + this.SelectSource(string.Empty); + } + + private void SelectSource(string initialDirectoryPath) + { + string newSourcePath = string.Empty; + + IFileFolderDialog fileFolderDialog = this.viewFactory.CreateFileFolderDialog(); + if ((string.IsNullOrEmpty(initialDirectoryPath) == false) && Directory.Exists(initialDirectoryPath)) + { + fileFolderDialog.SelectedPath = initialDirectoryPath; + } + else + { + fileFolderDialog.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + } + + if (fileFolderDialog.ShowDialog() == DialogResult.OK) + { + if (File.Exists(fileFolderDialog.SelectedPath)) + { + this.backupInfoModel.BackupSourceType = BackupSourceType.File; + newSourcePath = fileFolderDialog.SelectedPath; + } + else if (Directory.Exists(fileFolderDialog.SelectedPath)) + { + this.backupInfoModel.BackupSourceType = BackupSourceType.Folder; + newSourcePath = fileFolderDialog.SelectedPath; + } + } + + if (string.IsNullOrEmpty(newSourcePath) == false) + { + this.backupInfoModel.SourcePath = newSourcePath; + this.NotifyPropertyChanged("SourceType"); + this.NotifyPropertyChanged("SourcePath"); + this.NotifyPropertyChanged("DisplaySourcePath"); + } + + this.UpdateErrorStatus(); + } + + private bool CanExecuteSelectSource(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteOpenDestinationFolder(object obj) + { + IBackupInfo backupInfo = this.GetBackupInfo(); + if (((backupInfo.BackupSourceType == BackupSourceType.File) && + File.Exists(backupInfo.LatestSuccessfulBackupTargetName)) || + ((backupInfo.BackupSourceType == BackupSourceType.Folder) && + Directory.Exists(backupInfo.LatestSuccessfulBackupTargetName))) + { + Helpers.OpenParentFolderAndSelect(backupInfo.LatestSuccessfulBackupTargetName); + } + else + { + Helpers.OpenFolder(this.DestinationFolderPath); + } + } + + private bool CanExecuteOpenDestinationFolder(object obj) + { + return this.backupSettingService.CurrentSetting != null; + } + + private void ExecuteSelectDestination(object obj) + { + this.SelectDestination(string.Empty); + } + + private void SelectDestination(string initialDirectoryPath) + { + IFileFolderDialog fileFolderDialog = this.viewFactory.CreateFileFolderDialog(); + if ((string.IsNullOrEmpty(initialDirectoryPath) == false) && Directory.Exists(initialDirectoryPath)) + { + fileFolderDialog.SelectedPath = initialDirectoryPath; + } + else + { + fileFolderDialog.SelectedPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments); + } + + if (fileFolderDialog.ShowDialog() == DialogResult.OK) + { + string destinationPath = + Directory.Exists(fileFolderDialog.SelectedPath) + ? fileFolderDialog.SelectedPath + : Path.GetDirectoryName(fileFolderDialog.SelectedPath); + this.backupInfoModel.DestinationFolderPath = destinationPath; + this.NotifyPropertyChanged("DestinationFolderPath"); + this.NotifyPropertyChanged("DisplayDestinationFolderPath"); + } + + this.UpdateErrorStatus(); + } + + private bool CanExecuteSelectDestination(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteEditSource(object obj) + { + this.EditingSourcePath = this.SourcePath; + this.IsSourceEditing = true; + } + + private bool CanExecuteEditSource(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteEditDestination(object obj) + { + this.EditingDestinationPath = this.DestinationFolderPath; + this.IsDestinationEditing = true; + } + + private bool CanExecuteEditDestination(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteSingleBackup(object obj) + { + this.SingleBackup(); + } + + private bool CanExecuteSingleBackup(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void UpdateErrorStatus() + { + switch (this.backupInfoModel.BackupSourceType) + { + case BackupSourceType.File: + this.HasSourcePathError = File.Exists(this.backupInfoModel.SourcePath) == false; + break; + case BackupSourceType.Folder: + this.HasSourcePathError = Directory.Exists(this.backupInfoModel.SourcePath) == false; + break; + default: + throw new InvalidOperationException("Unexpected backup source type."); + } + + this.HasDestinationFolderPathError = Directory.Exists(this.backupInfoModel.DestinationFolderPath) == false; + } + } +} diff --git a/Main/SimpleBackup.ViewModels/DataGridColumnHeaderBaseViewModel.cs b/Main/SimpleBackup.ViewModels/DataGridColumnHeaderBaseViewModel.cs new file mode 100644 index 0000000..8fd7cee --- /dev/null +++ b/Main/SimpleBackup.ViewModels/DataGridColumnHeaderBaseViewModel.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.Utilities; + + /// + /// A base class of a DataGridColumn view models. + /// + internal abstract class DataGridColumnHeaderBaseViewModel : PropertyChangeNotificationBase + { + /// + /// The inner header + /// + private object innerHeader = new object(); + + /// + /// Gets or sets the header. + /// + public object Header + { + get + { + return this.innerHeader; + } + + set + { + if (this.innerHeader != value) + { + this.innerHeader = value; + this.NotifyPropertyChanged("Header"); + } + } + } + } +} diff --git a/Main/SimpleBackup.ViewModels/DestinationColumnHeaderViewModel.cs b/Main/SimpleBackup.ViewModels/DestinationColumnHeaderViewModel.cs new file mode 100644 index 0000000..7c7df46 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/DestinationColumnHeaderViewModel.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.ViewModels; + + /// + /// The view model of destination column header. + /// + internal class DestinationColumnHeaderViewModel : DataGridColumnHeaderBaseViewModel, IDestinationColumnHeaderViewModel + { + } +} diff --git a/Main/SimpleBackup.ViewModels/EncodingInfoItemViewModel.cs b/Main/SimpleBackup.ViewModels/EncodingInfoItemViewModel.cs new file mode 100644 index 0000000..3fda81d --- /dev/null +++ b/Main/SimpleBackup.ViewModels/EncodingInfoItemViewModel.cs @@ -0,0 +1,55 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.Utilities; + + /// + /// A view model for single encoding information item. + /// + internal class EncodingInfoItemViewModel + { + /// + /// Initializes a new instance of the class. + /// + /// Name of the encoding key. + /// Display name of the encoding. + public EncodingInfoItemViewModel(string encodingKeyName, string encodingDisplayName) + { + encodingKeyName.ThrowsArgumentExceptionIfNullOrEmpty("encodingKeyName"); + encodingDisplayName.ThrowsArgumentExceptionIfNullOrEmpty("encodingDisplayName"); + + this.EncodingKeyName = encodingKeyName; + this.EncodingDisplayName = encodingDisplayName; + } + + /// + /// Gets the name of the encoding key. + /// + public string EncodingKeyName { get; private set; } + + /// + /// Gets the display name of the encoding. + /// + public string EncodingDisplayName { get; private set; } + } +} diff --git a/Main/SimpleBackup.ViewModels/IndexBackupInfoViewModelPair.cs b/Main/SimpleBackup.ViewModels/IndexBackupInfoViewModelPair.cs new file mode 100644 index 0000000..471fc83 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/IndexBackupInfoViewModelPair.cs @@ -0,0 +1,63 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using System; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Core.ViewModels; + + /// + /// A pair of index and backup information view model. + /// + internal class IndexBackupInfoViewModelPair + { + /// + /// Initializes a new instance of the class. + /// + /// The index. + /// The backup information view model. + /// The provided index is out of the range. + /// The provided backupInfoViewModel is null. + public IndexBackupInfoViewModelPair(int index, IBackupInfoViewModel backupInfoViewModel) + { + if (index < 0) + { + throw new ArgumentOutOfRangeException("index"); + } + + backupInfoViewModel.ThrowsArgumentNullException("backupInfoViewModel"); + + this.Index = index; + this.BackupInfoViewModel = backupInfoViewModel; + } + + /// + /// Gets the index. + /// + public int Index { get; private set; } + + /// + /// Gets the backup information view model. + /// + public IBackupInfoViewModel BackupInfoViewModel { get; private set; } + } +} diff --git a/Main/SimpleBackup.ViewModels/IsZipArchiveColumnHeaderViewModel.cs b/Main/SimpleBackup.ViewModels/IsZipArchiveColumnHeaderViewModel.cs new file mode 100644 index 0000000..262f9a4 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/IsZipArchiveColumnHeaderViewModel.cs @@ -0,0 +1,30 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + /// + /// The view model of IsZipArchive column header. + /// + internal class IsZipArchiveColumnHeaderViewModel : DataGridColumnHeaderBaseViewModel + { + } +} diff --git a/Main/SimpleBackup.ViewModels/LabelColumnHeaderViewModel.cs b/Main/SimpleBackup.ViewModels/LabelColumnHeaderViewModel.cs new file mode 100644 index 0000000..cc19cfa --- /dev/null +++ b/Main/SimpleBackup.ViewModels/LabelColumnHeaderViewModel.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.ViewModels; + + /// + /// The view model of label column header. + /// + internal class LabelColumnHeaderViewModel : DataGridColumnHeaderBaseViewModel, ILabelColumnHeaderViewModel + { + } +} diff --git a/Main/SimpleBackup.ViewModels/MainWindowViewModel.cs b/Main/SimpleBackup.ViewModels/MainWindowViewModel.cs new file mode 100644 index 0000000..ad617f5 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/MainWindowViewModel.cs @@ -0,0 +1,1223 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using System; + using System.Collections.Generic; + using System.Collections.ObjectModel; + using System.Globalization; + using System.IO; + using System.Linq; + using System.Reflection; + using System.Threading; + using System.Threading.Tasks; + using System.Windows; + using System.Windows.Input; + using SimpleBackup.Core; + using SimpleBackup.Core.Models; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Core.ViewModels; + using SimpleBackup.Core.Views; + + /// + /// The view model of the main window. + /// + internal class MainWindowViewModel : PropertyChangeNotificationBase, IMainWindowViewModel + { + private readonly string defaultWindowTitleFormat = Resources.Resources.Views_DefaultWindowTitle; + private readonly string windowTitleFormat = Resources.Resources.Views_WindowTitleFormat; + private readonly List innerZipEncodings = new List(); + private readonly IBackupService backupService; + private readonly IBackupSettingService backupSettingService; + private readonly IClipboardService clipboardService; + private readonly IUndoRedoService undoRedoService; + private readonly IModelFactory modelFactory; + private readonly IViewFactory viewFactory; + private string innerWindowTitle; + private string innerOutputMessage; + private EncodingInfoItemViewModel innerSelectedEncodingInfoItem; + private CancellationTokenSource cancellationTokenSource; + private IBackupInfoViewModel innerSelectedBackupInfoViewModel; + private int innerSelectedFirstCellItemIndex; + + /// + /// Prevents a default instance of the class from being created. + /// + private MainWindowViewModel() + { + this.CreateNewBackupSettingRelayCommand = new RelayCommand(this.ExecuteCreateNewBackupSetting, this.CanExecuteCreateNewBackupSetting); + this.OpenBackupSettingRelayCommand = new RelayCommand(this.ExecuteOpenBackupSetting, this.CanExecuteOpenBackupSetting); + this.SaveBackupSettingRelayCommand = new RelayCommand(this.ExecuteSaveBackupSetting, this.CanExecuteSaveBackupSetting); + this.SaveAsBackupSettingRelayCommand = new RelayCommand(this.ExecuteSaveAsBackupSetting, this.CanExecuteSaveAsBackupSetting); + this.CloseBackupSettingRelayCommand = new RelayCommand(this.ExecuteCloseBackupSetting, this.CanExecuteCloseBackupSetting); + this.OpenCurrentSettingFileLocationRelayCommand = new RelayCommand(this.ExecuteOpenCurrentSettingFileLocation, this.CanExecuteOpenCurrentSettingFileLocation); + this.ExitRelayCommand = new RelayCommand(this.ExecuteExit, this.CanExecuteExit); + + this.ShowHelpRelayCommand = new RelayCommand(this.ExecuteShowHelp); + this.ShowVersionInformationRelayCommand = new RelayCommand(this.ExecuteShowVersionInformation); + + this.BackUpRelayCommand = new RelayCommand(this.ExecuteBackup, this.CanExecuteBackup); + this.BackupCancelRelayCommand = new RelayCommand(this.ExecuteBackupCancel, this.CanExecuteBackupCancel); + this.SingleBackupRelayCommand = new RelayCommand(this.ExecuteSingleBackup, this.CanExecuteSingleBackup); + this.AddItemRelayCommand = new RelayCommand(this.ExecuteAddItem, this.CanExecuteAddItem); + this.RemoveItemRelayCommand = new RelayCommand(this.ExecuteRemoveItem, this.CanExecuteRemoveItem); + this.MoveUpItemRelayCommand = new RelayCommand(this.ExecuteMoveUpItem, this.CanExecuteMoveUpItem); + this.MoveDownItemRelayCommand = new RelayCommand(this.ExecuteMoveDownItem, this.CanExecuteMoveDownItem); + this.CopyRelayCommand = new RelayCommand(this.ExecuteCopy, this.CanExecuteCopy); + this.CutRelayCommand = new RelayCommand(this.ExecuteCut, this.CanExecuteCut); + this.PasteRelayCommand = new RelayCommand(this.ExecutePaste, this.CanExecutePaste); + this.UndoRelayCommand = new RelayCommand(this.ExecuteUndo, this.CanExecuteUndo); + this.RedoRelayCommand = new RelayCommand(this.ExecuteRedo, this.CanExecuteRedo); + this.RefreshRelayCommand = new RelayCommand(this.ExecuteRefresh, this.CanExecuteRefresh); + this.ClearOutputWindowRelayCommand = new RelayCommand(this.ExecuteClearOutputWindow, this.CanExecuteClearOutputWindow); + + this.WindowTitle = this.defaultWindowTitleFormat; + this.BackupInfoViewModels = new ObservableCollection(); + + this.IsZipArchiveColumnHeaderViewModel = new IsZipArchiveColumnHeaderViewModel { Header = "Zip" }; + this.LabelColumnHeaderViewModel = new LabelColumnHeaderViewModel { Header = Resources.Resources.Views_LabelColumnHeaderText }; + this.SourceColumnHeaderViewModel = new SourceColumnHeaderViewModel { Header = Resources.Resources.Views_BackupSourceColumnHeaderText }; + this.DestinationColumnHeaderViewModel = new DestinationColumnHeaderViewModel { Header = Resources.Resources.Views_BackupDestinationColumnHeaderText }; + this.ProgressViewModel = new ProgressViewModel(); + + this.innerOutputMessage = string.Empty; + this.SetupZipEncodingItems(); + + this.backupService = ObjectContainer.Resolve(); + this.backupSettingService = ObjectContainer.Resolve(); + this.clipboardService = ObjectContainer.Resolve(); + this.undoRedoService = ObjectContainer.Resolve(); + this.modelFactory = ObjectContainer.Resolve(); + this.viewFactory = ObjectContainer.Resolve(); + + this.backupSettingService.BackupSettingOpened += this.OnBackupSettingOpened; + this.backupSettingService.BackupSettingModified += this.OnBackupSettingModified; + this.backupSettingService.BackupSettingSaved += this.OnBackupSettingSaved; + this.backupSettingService.BackupSettingClosed += this.OnBackupSettingClosed; + this.backupService.NofityFileBackupProgress += this.OnBackupServiceNofityFileBackupProgress; + + string resultMessage; + if (this.backupSettingService.OpenDefaultBackupSetting(out resultMessage)) + { + foreach (IBackupInfo backupInfo in this.backupSettingService.CurrentSetting.BackupInfos) + { + IBackupInfoViewModel backupInfoViewModel = BackupInfoViewModel.CreateBackupInfoViewMode( + backupInfo, + this.ClearOutputMessage, + this.AddOutputMessage); + this.BackupInfoViewModels.Add(backupInfoViewModel); + } + } + + if (string.IsNullOrEmpty(resultMessage) == false) + { + this.OutputMessage = resultMessage; + } + } + + /// + /// Occurs when focusing on grid is required. + /// + public event EventHandler FocusOnGrid; + + /// + /// Occurs when focusing on grid row is required. + /// + public event EventHandler FocusOnGridRow; + + /// + /// Gets the create new backup settings relay command. + /// + public RelayCommand CreateNewBackupSettingRelayCommand { get; private set; } + + /// + /// Gets the open backup settings relay command. + /// + public RelayCommand OpenBackupSettingRelayCommand { get; private set; } + + /// + /// Gets the save backup settings relay command. + /// + public RelayCommand SaveBackupSettingRelayCommand { get; private set; } + + /// + /// Gets the save as backup settings relay command. + /// + public RelayCommand SaveAsBackupSettingRelayCommand { get; private set; } + + /// + /// Gets the close backup settings relay command. + /// + public RelayCommand CloseBackupSettingRelayCommand { get; private set; } + + /// + /// Gets the open current setting file location relay command. + /// + public RelayCommand OpenCurrentSettingFileLocationRelayCommand { get; private set; } + + /// + /// Gets the exit relay command. + /// + public RelayCommand ExitRelayCommand { get; private set; } + + /// + /// Gets the show help relay command. + /// + public RelayCommand ShowHelpRelayCommand { get; private set; } + + /// + /// Gets the show version information relay command. + /// + public RelayCommand ShowVersionInformationRelayCommand { get; private set; } + + /// + /// Gets the back up relay command. + /// + public RelayCommand BackUpRelayCommand { get; private set; } + + /// + /// Gets the backup cancel relay command. + /// + public RelayCommand BackupCancelRelayCommand { get; private set; } + + /// + /// Gets the single backup relay command. + /// + public RelayCommand SingleBackupRelayCommand { get; private set; } + + /// + /// Gets the add item relay command. + /// + public RelayCommand AddItemRelayCommand { get; private set; } + + /// + /// Gets the remove item relay command. + /// + public RelayCommand RemoveItemRelayCommand { get; private set; } + + /// + /// Gets the move up item relay command. + /// + public RelayCommand MoveUpItemRelayCommand { get; private set; } + + /// + /// Gets the move down item relay command. + /// + public RelayCommand MoveDownItemRelayCommand { get; private set; } + + /// + /// Gets the copy relay command. + /// + public RelayCommand CopyRelayCommand { get; private set; } + + /// + /// Gets the cut relay command. + /// + public RelayCommand CutRelayCommand { get; private set; } + + /// + /// Gets the paste relay command. + /// + public RelayCommand PasteRelayCommand { get; private set; } + + /// + /// Gets the undo relay command. + /// + public RelayCommand UndoRelayCommand { get; private set; } + + /// + /// Gets the redo relay command. + /// + public RelayCommand RedoRelayCommand { get; private set; } + + /// + /// Gets the refresh relay command. + /// + public RelayCommand RefreshRelayCommand { get; private set; } + + /// + /// Gets the clear output window relay command. + /// + public RelayCommand ClearOutputWindowRelayCommand { get; private set; } + + /// + /// Gets the backup information view models. + /// + public ObservableCollection BackupInfoViewModels { get; private set; } + + /// + /// Gets the progress view model. + /// + public ProgressViewModel ProgressViewModel { get; private set; } + + /// + /// Gets the is zip archive column header view model. + /// + public IsZipArchiveColumnHeaderViewModel IsZipArchiveColumnHeaderViewModel { get; private set; } + + /// + /// Gets the label column header view model. + /// + public LabelColumnHeaderViewModel LabelColumnHeaderViewModel { get; private set; } + + /// + /// Gets the source column header view model. + /// + public SourceColumnHeaderViewModel SourceColumnHeaderViewModel { get; private set; } + + /// + /// Gets the destination column header view model. + /// + public DestinationColumnHeaderViewModel DestinationColumnHeaderViewModel { get; private set; } + + /// + /// Gets or sets the window title. + /// + public string WindowTitle + { + get + { + return this.innerWindowTitle; + } + + set + { + if (this.innerWindowTitle != value) + { + this.innerWindowTitle = value; + this.NotifyPropertyChanged("WindowTitle"); + } + } + } + + /// + /// Gets the zip encodings. + /// + public IEnumerable ZipEncodings + { + get + { + return this.innerZipEncodings; + } + } + + /// + /// Gets or sets the selected encoding information item. + /// + public EncodingInfoItemViewModel SelectedEncodingInfoItem + { + get + { + return this.innerSelectedEncodingInfoItem; + } + + set + { + if (this.innerSelectedEncodingInfoItem != value) + { + this.innerSelectedEncodingInfoItem = value; + var settingsService = ObjectContainer.Resolve(); + settingsService.DefaultZipEncodingKeyText = value.EncodingKeyName; + } + } + } + + /// + /// Gets or sets the selected backup information view model. + /// + public IBackupInfoViewModel SelectedBackupInfoViewModel + { + get + { + return this.innerSelectedBackupInfoViewModel; + } + + set + { + if (this.innerSelectedBackupInfoViewModel != value) + { + this.innerSelectedBackupInfoViewModel = value; + this.NotifyPropertyChanged("SelectedBackupInfoViewModel"); + } + } + } + + /// + /// Gets or sets the output message. + /// + public string OutputMessage + { + get + { + return this.innerOutputMessage; + } + + set + { + if (this.innerOutputMessage != value) + { + this.innerOutputMessage = value; + this.NotifyPropertyChanged("OutputMessage"); + } + } + } + + /// + /// Gets or sets the index of the selected first cell item. + /// + public int SelectedFirstCellItemIndex + { + get + { + return this.innerSelectedFirstCellItemIndex; + } + + set + { + this.innerSelectedFirstCellItemIndex = value; + this.CommitEditingContents(); + } + } + + /// + /// Gets or sets the selected first cell item. + /// + public BackupInfoViewModel SelectedFirstCellItem { get; set; } + + /// + /// Creates the main window view model. + /// + /// The main window view model. + public static IMainWindowViewModel CreateMainWindowViewModel() + { + return new MainWindowViewModel(); + } + + /// + /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. + /// + public void Dispose() + { + this.Dispose(true); + GC.SuppressFinalize(this); + } + + /// + /// Called when ESC key is pressed. + /// + public void OnEscKeyPressed() + { + this.CancelCutOperation(); + this.CancelCellEditOperation(); + } + + /// + /// Releases unmanaged and - optionally - managed resources. + /// + /// true to release both managed and unmanaged resources; false to release only unmanaged resources. + protected virtual void Dispose(bool disposing) + { + if (disposing) + { + // dispose managed resources + this.cancellationTokenSource.Dispose(); + } + + //// free native resources - Nothing to dispose. + } + + /// + /// Cancels the cut operation. + /// + private void CancelCutOperation() + { + var cutReservedBackupInfoViewModels = this.BackupInfoViewModels.Where(p => p.IsCutReserved).ToArray(); + foreach (IBackupInfoViewModel infoViewModel in cutReservedBackupInfoViewModels) + { + infoViewModel.IsCutReserved = false; + this.clipboardService.ClearClipbord(); + } + } + + /// + /// Cancels the cell edit operation. + /// + private void CancelCellEditOperation() + { + var editingInfoViewModels = this.BackupInfoViewModels.Where(p => p.IsEditing).ToArray(); + foreach (IBackupInfoViewModel infoViewModel in editingInfoViewModels) + { + infoViewModel.IsSourceEditing = false; + infoViewModel.IsDestinationEditing = false; + } + } + + private void OnBackupSettingOpened(object sender, SettingFileEventArgs args) + { + this.WindowTitle = string.Format(CultureInfo.InvariantCulture, this.windowTitleFormat, args.SettingName); + } + + private void OnBackupSettingModified(object sender, SettingFileEventArgs args) + { + this.UpdateWindowTitleAsModified(args.SettingName); + } + + private void OnBackupSettingSaved(object sender, SettingFileEventArgs args) + { + this.WindowTitle = string.Format(CultureInfo.InvariantCulture, this.windowTitleFormat, args.SettingName); + } + + private void OnBackupSettingClosed(object sender, SettingFileEventArgs args) + { + this.WindowTitle = this.defaultWindowTitleFormat; + this.BackupInfoViewModels.Clear(); + } + + private void ExecuteCreateNewBackupSetting(object obj) + { + this.backupSettingService.CreateBackupSetting(); + this.ExecuteAddItem(null); + this.UpdateWindowTitleAsModified(this.backupSettingService.CurrentSetting.SettingName); + } + + private bool CanExecuteCreateNewBackupSetting(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteBackup(object obj) + { + if (this.cancellationTokenSource != null) + { + this.cancellationTokenSource.Dispose(); + } + + this.cancellationTokenSource = new CancellationTokenSource(); + Action backupAction = () => + { + try + { + Application.Current.Dispatcher.Invoke( + () => + { + this.OutputMessage = Resources.Resources.Backup_ExecutingBackup; + Mouse.OverrideCursor = Cursors.Wait; + }); + + IResultInfo[] resultInfos; + this.backupService.BackupMultipulFiles(this.cancellationTokenSource.Token, out resultInfos); + } + finally + { + Application.Current.Dispatcher.Invoke( + () => + { + Mouse.OverrideCursor = null; + }); + } + }; + Action postBackupAction = previousTask => + { + if (previousTask.Exception != null) + { + this.OutputMessage = this.OutputMessage + "\r\n" + previousTask.Exception.ToString(); + } + + if (this.FocusOnGrid != null) + { + Application.Current.Dispatcher.Invoke( + () => this.FocusOnGrid(this, new EventArgs())); + } + }; + + Task.Factory.StartNew(backupAction, this.cancellationTokenSource.Token) + .ContinueWith(postBackupAction); + } + + private bool CanExecuteBackup(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + this.backupService.IsReadyForBackup && (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteBackupCancel(object obj) + { + if (this.cancellationTokenSource != null) + { + this.cancellationTokenSource.Cancel(); + } + } + + private bool CanExecuteBackupCancel(object obj) + { + return this.backupService.IsReadyForBackup && this.backupService.IsExecutingBackup; + } + + private void ExecuteOpenBackupSetting(object obj) + { + if (this.CanExecuteOpenBackupSetting(obj) == false) + { + return; + } + + string resultMessage; + if (this.backupSettingService.OpenBackupSetting(out resultMessage)) + { + foreach (IBackupInfo backupInfo in this.backupSettingService.CurrentSetting.BackupInfos) + { + IBackupInfoViewModel backupInfoViewModel = BackupInfoViewModel.CreateBackupInfoViewMode( + backupInfo, + this.ClearOutputMessage, + this.AddOutputMessage); + this.BackupInfoViewModels.Add(backupInfoViewModel); + } + } + + if (string.IsNullOrEmpty(resultMessage) == false) + { + this.OutputMessage = resultMessage; + } + } + + private bool CanExecuteOpenBackupSetting(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteSaveBackupSetting(object obj) + { + this.backupSettingService.OverWriteCurrntBackupSetting(); + } + + private bool CanExecuteSaveBackupSetting(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteSaveAsBackupSetting(object obj) + { + this.backupSettingService.SaveCurrentBackupSettingAsNewFile(); + } + + private bool CanExecuteSaveAsBackupSetting(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteCloseBackupSetting(object obj) + { + this.backupSettingService.CloseBackupSetting(); + } + + private bool CanExecuteCloseBackupSetting(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteOpenCurrentSettingFileLocation(object obj) + { + Helpers.OpenParentFolderAndSelect(this.backupSettingService.CurrentSetting.SettingFileName); + } + + private bool CanExecuteOpenCurrentSettingFileLocation(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteExit(object obj) + { + Application.Current.Shutdown(0); + } + + private bool CanExecuteExit(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteShowHelp(object obj) + { + string helpFilePath = string.Format( + @"{0}\Documents\HelpDocument.pdf", + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)); + Helpers.OpenFile(helpFilePath); + } + + private void ExecuteShowVersionInformation(object obj) + { + IVersionInformationWindow versionInformationWindow = this.viewFactory.CreateVersionInformationWindow(); + + versionInformationWindow.ShowDialogWindow(); + } + + private void ExecuteSingleBackup(object obj) + { + if (this.SelectedFirstCellItem != null) + { + this.SelectedFirstCellItem.SingleBackup(); + } + } + + private bool CanExecuteSingleBackup(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteAddItem(object obj) + { + if (this.CanExecuteAddItem(obj) == false) + { + return; + } + + int currentIndex = -1; + if (this.SelectedBackupInfoViewModel != null) + { + currentIndex = this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel); + } + + int targetIndex = (currentIndex != -1) ? currentIndex + 1 : this.BackupInfoViewModels.Count; + + var action = new Action( + context => + { + var index = (int)context; + IBackupInfo backupInfo = this.backupSettingService.CreateBackupInfo(index); + IBackupInfoViewModel backupInfoViewModel = BackupInfoViewModel.CreateBackupInfoViewMode( + backupInfo, + this.ClearOutputMessage, + this.AddOutputMessage); + this.BackupInfoViewModels.Insert(index, backupInfoViewModel); + + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(index)); + } + + this.SelectedBackupInfoViewModel = backupInfoViewModel; + }); + + var undoAction = new Action( + context => + { + var index = (int)context; + if (index < this.BackupInfoViewModels.Count) + { + var removingBackupInfoViewModel = this.BackupInfoViewModels[index]; + this.backupSettingService.RemoveBackupInfo(removingBackupInfoViewModel.BackupInfoId); + this.BackupInfoViewModels.Remove(removingBackupInfoViewModel); + + if (index < this.BackupInfoViewModels.Count) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(index)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[index]; + } + else if (this.BackupInfoViewModels.Count != 0) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(index - 1)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[index - 1]; + } + } + }); + + this.undoRedoService.Commit(action, undoAction, targetIndex); + } + + private bool CanExecuteAddItem(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false); + } + + private void ExecuteRemoveItem(object obj) + { + if (this.CanExecuteRemoveItem(obj) == false) + { + return; + } + + var targetIndexViewModelPair = new IndexBackupInfoViewModelPair( + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel), + this.SelectedBackupInfoViewModel); + + this.RemoveItem(targetIndexViewModelPair); + } + + private void RemoveItem(IndexBackupInfoViewModelPair targetIndexViewModelPair) + { + var action = new Action( + context => + { + var indexViewModelPair = (IndexBackupInfoViewModelPair)context; + if (indexViewModelPair.Index < this.BackupInfoViewModels.Count) + { + var removingBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index]; + this.backupSettingService.RemoveBackupInfo(removingBackupInfoViewModel.BackupInfoId); + this.BackupInfoViewModels.Remove(removingBackupInfoViewModel); + + if (indexViewModelPair.Index < this.BackupInfoViewModels.Count) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index]; + } + else if (this.BackupInfoViewModels.Count != 0) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index - 1)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index - 1]; + } + } + }); + + var undoAction = new Action( + context => + { + var indexViewModelPair = (IndexBackupInfoViewModelPair)context; + + this.backupSettingService.InsertBackupInfo( + indexViewModelPair.Index, + indexViewModelPair.BackupInfoViewModel.GetBackupInfo()); + this.BackupInfoViewModels.Insert( + indexViewModelPair.Index, + indexViewModelPair.BackupInfoViewModel); + + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index)); + } + + this.SelectedBackupInfoViewModel = indexViewModelPair.BackupInfoViewModel; + }); + + this.undoRedoService.Commit(action, undoAction, targetIndexViewModelPair); + } + + private bool CanExecuteRemoveItem(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false) && + (this.SelectedBackupInfoViewModel != null); + } + + private void ExecuteMoveUpItem(object obj) + { + if (this.CanExecuteMoveUpItem(obj) == false) + { + return; + } + + var selectedIdIndexPair = new IdIndexPair( + this.SelectedBackupInfoViewModel.BackupInfoId, + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel)); + var action = new Action(context => + { + var idIndexPair = (IdIndexPair)context; + if (idIndexPair.Index > 0) + { + this.backupSettingService.CurrentSetting.MoveItem(idIndexPair.Id, ItemMovingDirection.MoveUp); + this.BackupInfoViewModels.Move(idIndexPair.Index, idIndexPair.Index - 1); + } + }); + + var undoAction = new Action(context => + { + var idIndexPair = (IdIndexPair)context; + var index = idIndexPair.Index - 1; + if (index < this.BackupInfoViewModels.Count - 1) + { + this.backupSettingService.CurrentSetting.MoveItem(idIndexPair.Id, ItemMovingDirection.MoveDown); + this.BackupInfoViewModels.Move(index, index + 1); + } + }); + + this.undoRedoService.Commit(action, undoAction, selectedIdIndexPair); + } + + private bool CanExecuteMoveUpItem(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false) && + (this.SelectedBackupInfoViewModel != null) && + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel) > 0; + } + + private void ExecuteMoveDownItem(object obj) + { + if (this.CanExecuteMoveDownItem(obj) == false) + { + return; + } + + var selectedIdIndexPair = new IdIndexPair( + this.SelectedBackupInfoViewModel.BackupInfoId, + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel)); + var action = new Action(context => + { + var idIndexPair = (IdIndexPair)context; + if (idIndexPair.Index < this.BackupInfoViewModels.Count - 1) + { + this.backupSettingService.CurrentSetting.MoveItem(idIndexPair.Id, ItemMovingDirection.MoveDown); + this.BackupInfoViewModels.Move(idIndexPair.Index, idIndexPair.Index + 1); + } + }); + + var undoAction = new Action(context => + { + var idIndexPair = (IdIndexPair)context; + var index = idIndexPair.Index + 1; + if (index > 0) + { + this.backupSettingService.CurrentSetting.MoveItem(idIndexPair.Id, ItemMovingDirection.MoveUp); + this.BackupInfoViewModels.Move(index, index - 1); + } + }); + + this.undoRedoService.Commit(action, undoAction, selectedIdIndexPair); + } + + private bool CanExecuteMoveDownItem(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + (this.backupService.IsExecutingBackup == false) && + (this.SelectedBackupInfoViewModel != null) && + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel) < this.BackupInfoViewModels.Count - 1; + } + + private void ExecuteCopy(object obj) + { + if (this.CanExecuteCopy(obj)) + { + IBackupInfo copiedBackupInfo = this.backupSettingService.CopyBackupInfo( + this.SelectedBackupInfoViewModel.GetBackupInfo()); + byte[] backupInfoBytes = copiedBackupInfo.ToBinary(); + var info = new BackupInfoPasteInfo( + backupInfoBytes, + PasteType.Copy, + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel)); + IDataObject dataObject = new DataObject(); + dataObject.SetData(Constants.BackupInfoClipboardFormat, info); + dataObject.SetData(DataFormats.Text, copiedBackupInfo.ToFormattedText()); + this.clipboardService.SetDataObject(dataObject); + } + } + + private bool CanExecuteCopy(object obj) + { + return this.SelectedBackupInfoViewModel != null; + } + + private void ExecuteCut(object obj) + { + if (this.CanExecuteCut(obj)) + { + IBackupInfo copiedBackupInfo = this.backupSettingService.CopyBackupInfo( + this.SelectedBackupInfoViewModel.GetBackupInfo()); + byte[] backupInfoBytes = copiedBackupInfo.ToBinary(); + var info = new BackupInfoPasteInfo( + backupInfoBytes, + PasteType.Cut, + this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel)); + IDataObject dataObject = new DataObject(); + dataObject.SetData(Constants.BackupInfoClipboardFormat, info); + this.clipboardService.SetDataObject(dataObject); + dataObject.SetData(DataFormats.Text, copiedBackupInfo.ToFormattedText()); + this.SelectedBackupInfoViewModel.IsCutReserved = true; + } + } + + private bool CanExecuteCut(object obj) + { + return this.SelectedBackupInfoViewModel != null; + } + + private void ExecutePaste(object obj) + { + if (this.CanExecutePaste(obj)) + { + if (this.clipboardService.DoesClipboardDataContain(Constants.BackupInfoClipboardFormat)) + { + var pasteInfo = + this.clipboardService.GetData(Constants.BackupInfoClipboardFormat); + if (pasteInfo != null) + { + IBackupInfo backupInfo = this.modelFactory.CreateBackupInfoFromBinary( + pasteInfo.BackupInfoBytes, + pasteInfo.PasteType == PasteType.Copy); + + if ((pasteInfo.PasteType == PasteType.Cut) && + (pasteInfo.SourceIndex < this.BackupInfoViewModels.Count)) + { + IBackupInfoViewModel source = this.BackupInfoViewModels[pasteInfo.SourceIndex]; + if (source.IsCutReserved) + { + var targetIndexViewModelPair = new IndexBackupInfoViewModelPair( + pasteInfo.SourceIndex, + source); + this.RemoveItem(targetIndexViewModelPair); + } + } + + int targetIndex = this.GetTargetItemIndex(); + this.InsertBackupInfo(backupInfo, targetIndex); + } + } + } + } + + private bool CanExecutePaste(object obj) + { + var supportedClipboardFormats = new string[] { Constants.BackupInfoClipboardFormat }; + + return supportedClipboardFormats.Any(p => this.clipboardService.DoesClipboardDataContain(p)); + } + + private void InsertBackupInfo(IBackupInfo backupInfo, int targetIndex) + { + if ((backupInfo == null) || (targetIndex < 0) || (targetIndex > this.BackupInfoViewModels.Count)) + { + return; + } + + IBackupInfoViewModel backupInfoViewModel = BackupInfoViewModel.CreateBackupInfoViewMode( + backupInfo, + this.ClearOutputMessage, + this.AddOutputMessage); + var targetIndexViewModelPair = new IndexBackupInfoViewModelPair( + targetIndex, + backupInfoViewModel); + + var action = new Action(context => this.InsertBackupInfo(context)); + var undoAction = new Action(context => this.RemoveInsertedBackupInfo(context)); + this.undoRedoService.Commit(action, undoAction, targetIndexViewModelPair); + } + + private void InsertBackupInfo(object context) + { + var indexViewModelPair = (IndexBackupInfoViewModelPair)context; + this.backupSettingService.InsertBackupInfo( + indexViewModelPair.Index, + indexViewModelPair.BackupInfoViewModel.GetBackupInfo()); + this.BackupInfoViewModels.Insert(indexViewModelPair.Index, indexViewModelPair.BackupInfoViewModel); + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index)); + } + + this.SelectedBackupInfoViewModel = indexViewModelPair.BackupInfoViewModel; + } + + private void RemoveInsertedBackupInfo(object context) + { + var indexViewModelPair = (IndexBackupInfoViewModelPair)context; + if (indexViewModelPair.Index < this.BackupInfoViewModels.Count) + { + var removingBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index]; + this.backupSettingService.RemoveBackupInfo(removingBackupInfoViewModel.BackupInfoId); + this.BackupInfoViewModels.Remove(removingBackupInfoViewModel); + + if (indexViewModelPair.Index < this.BackupInfoViewModels.Count) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index]; + } + else if (this.BackupInfoViewModels.Count != 0) + { + if (this.FocusOnGridRow != null) + { + this.FocusOnGridRow(this, new FocusOnGridRowEventArgs(indexViewModelPair.Index - 1)); + } + + this.SelectedBackupInfoViewModel = this.BackupInfoViewModels[indexViewModelPair.Index - 1]; + } + } + } + + private void ExecuteUndo(object obj) + { + if (this.undoRedoService.CanExecuteUndo()) + { + this.undoRedoService.Undo(); + } + } + + private bool CanExecuteUndo(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + this.undoRedoService.CanExecuteUndo(); + } + + private void ExecuteRedo(object obj) + { + if (this.undoRedoService.CanExecuteRedo()) + { + this.undoRedoService.Redo(); + } + } + + private bool CanExecuteRedo(object obj) + { + return (this.backupSettingService.CurrentSetting != null) && + this.undoRedoService.CanExecuteRedo(); + } + + private void ExecuteRefresh(object obj) + { + this.ResetAllBackItemStates(); + this.RestProgressBar(); + } + + private bool CanExecuteRefresh(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void ExecuteClearOutputWindow(object obj) + { + this.OutputMessage = string.Empty; + } + + private bool CanExecuteClearOutputWindow(object obj) + { + return this.backupService.IsExecutingBackup == false; + } + + private void OnBackupServiceNofityFileBackupProgress(object sender, FileBackupProgressEventArgs args) + { + this.ProgressViewModel.ProgressValue = args.ProgressValue; + if (args.LatestResultInfo != null) + { + this.OutputMessage = this.OutputMessage + "\r\n" + + string.Format( + "{0}: {1}", + args.LatestResultInfo.BackupState.Translate(), + args.LatestResultInfo.Description); + } + } + + private void CommitEditingContents() + { + IBackupInfoViewModel[] editingViewModels = + this.BackupInfoViewModels.Where(p => p.IsEditing).ToArray(); + + foreach (IBackupInfoViewModel backupInfoViewModel in editingViewModels) + { + backupInfoViewModel.CommitEditingContents(); + } + } + + private void UpdateWindowTitleAsModified(string backupSettingName) + { + this.WindowTitle = string.Format( + CultureInfo.InvariantCulture, + this.windowTitleFormat, + backupSettingName + "*"); + } + + private void ResetAllBackItemStates() + { + foreach (IBackupInfoViewModel backupInfoViewModel in this.BackupInfoViewModels) + { + backupInfoViewModel.ResetBackupState(); + } + } + + private void RestProgressBar() + { + this.ProgressViewModel.ProgressValue = 0; + } + + private void ClearOutputMessage() + { + this.OutputMessage = string.Empty; + } + + private void AddOutputMessage(string additionalMessage) + { + this.OutputMessage = this.OutputMessage + (additionalMessage ?? string.Empty) + "\r\n"; + } + + private int GetTargetItemIndex() + { + int currentIndex = -1; + if (this.SelectedBackupInfoViewModel != null) + { + currentIndex = this.BackupInfoViewModels.IndexOf(this.SelectedBackupInfoViewModel); + } + else + { + currentIndex = this.SelectedFirstCellItemIndex; + } + + int targetIndex = (currentIndex != -1) ? currentIndex + 1 : this.BackupInfoViewModels.Count; + + return targetIndex; + } + + private void SetupZipEncodingItems() + { + var settingsService = ObjectContainer.Resolve(); + if (string.IsNullOrEmpty(settingsService.DefaultZipEncodingKeyText)) + { + settingsService.DefaultZipEncodingKeyText = "utf-8"; + } + + this.innerZipEncodings.Add(new EncodingInfoItemViewModel("shift_jis", "Japanese (Shift-JIS)")); + this.innerZipEncodings.Add(new EncodingInfoItemViewModel("utf-16", "Unicode")); + this.innerZipEncodings.Add(new EncodingInfoItemViewModel("utf-8", "Unicode (UTF-8)")); + + EncodingInfoItemViewModel defaultEncodingItem = + this.innerZipEncodings.FirstOrDefault( + p => + string.Equals( + p.EncodingKeyName, + settingsService.DefaultZipEncodingKeyText, + StringComparison.OrdinalIgnoreCase)); + if (defaultEncodingItem != null) + { + this.SelectedEncodingInfoItem = defaultEncodingItem; + } + } + } +} diff --git a/Main/SimpleBackup.ViewModels/ProgressViewModel.cs b/Main/SimpleBackup.ViewModels/ProgressViewModel.cs new file mode 100644 index 0000000..8313e26 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/ProgressViewModel.cs @@ -0,0 +1,56 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.Utilities; + + /// + /// The view model for reporting progress. + /// + internal class ProgressViewModel : PropertyChangeNotificationBase + { + /// + /// The progress value + /// + private double progressValue; + + /// + /// Gets or sets the progress value. + /// + public double ProgressValue + { + get + { + return this.progressValue; + } + + set + { + if (this.progressValue.Equals(value) == false) + { + this.progressValue = value; + this.NotifyPropertyChanged("ProgressValue"); + } + } + } + } +} diff --git a/Main/SimpleBackup.ViewModels/SimpleBackup.ViewModels.csproj b/Main/SimpleBackup.ViewModels/SimpleBackup.ViewModels.csproj new file mode 100644 index 0000000..8ffd7ca --- /dev/null +++ b/Main/SimpleBackup.ViewModels/SimpleBackup.ViewModels.csproj @@ -0,0 +1,100 @@ + + + + + Debug + AnyCPU + {70BC6544-A4C9-4325-9CE1-CC3F79787693} + Library + Properties + SimpleBackup.ViewModels + SimpleBackup.ViewModels + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + + + + + + + + + + + + + + + + + + + {33f1d454-9962-4eb6-aad3-8d11d9a78d1f} + SimpleBackup.Core + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + + + + + set EXE_BIN_DIR=$(ProjectDir)..\bin\$(ConfigurationName)\ +xcopy "$(TargetDir)$(TargetName).dll" "%25EXE_BIN_DIR%25" /Y +if exist "$(TargetDir)$(TargetName).pdb" xcopy "$(TargetDir)$(TargetName).pdb" "%25EXE_BIN_DIR%25" /Y + + + \ No newline at end of file diff --git a/Main/SimpleBackup.ViewModels/SimpleBackupKey.snk b/Main/SimpleBackup.ViewModels/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.ViewModels/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.ViewModels/SourceColumnHeaderViewModel.cs b/Main/SimpleBackup.ViewModels/SourceColumnHeaderViewModel.cs new file mode 100644 index 0000000..cca8b35 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/SourceColumnHeaderViewModel.cs @@ -0,0 +1,32 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.ViewModels; + + /// + /// The view model of source column header. + /// + internal class SourceColumnHeaderViewModel : DataGridColumnHeaderBaseViewModel, ISourceColumnHeaderViewModel + { + } +} diff --git a/Main/SimpleBackup.ViewModels/ViewModelComponent.cs b/Main/SimpleBackup.ViewModels/ViewModelComponent.cs new file mode 100644 index 0000000..f2547b1 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/ViewModelComponent.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core; + using SimpleBackup.Core.AppInfrastructure; + using SimpleBackup.Core.ViewModels; + + /// + /// The view model component. + /// + internal class ViewModelComponent : IAppComponent + { + /// + /// Initializes this application component. + /// + public void Initialize() + { + ObjectContainer.Register(new ViewModelFactory()); + } + } +} diff --git a/Main/SimpleBackup.ViewModels/ViewModelFactory.cs b/Main/SimpleBackup.ViewModels/ViewModelFactory.cs new file mode 100644 index 0000000..a54e0b3 --- /dev/null +++ b/Main/SimpleBackup.ViewModels/ViewModelFactory.cs @@ -0,0 +1,40 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.ViewModels +{ + using SimpleBackup.Core.ViewModels; + + /// + /// The view model factory. + /// + internal class ViewModelFactory : IViewModelFactory + { + /// + /// Creates the main window view model. + /// + /// The main window view model. + public IMainWindowViewModel CreateMainWindowViewModel() + { + return MainWindowViewModel.CreateMainWindowViewModel(); + } + } +} diff --git a/Main/SimpleBackup.Views/BackupSourceTypeToImageConverter.cs b/Main/SimpleBackup.Views/BackupSourceTypeToImageConverter.cs new file mode 100644 index 0000000..25bed54 --- /dev/null +++ b/Main/SimpleBackup.Views/BackupSourceTypeToImageConverter.cs @@ -0,0 +1,87 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System; + using System.Diagnostics; + using System.Windows.Controls; + using System.Windows.Data; + using System.Windows.Media.Imaging; + using SimpleBackup.Core.Models; + + /// + /// A converter which converts BackupSourceType to Image. + /// + internal class BackupSourceTypeToImageConverter : IValueConverter + { + /// + /// Converts a value. + /// + /// The value produced by the binding source. + /// The type of the binding target property. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Uri imageSourceUri; + var backupState = (BackupSourceType)value; + switch (backupState) + { + case BackupSourceType.File: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/document_32xLG.png", UriKind.Absolute); + break; + case BackupSourceType.Folder: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/FileGroup_10135_32x.png", UriKind.Absolute); + break; + default: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/document_32xLG.png", UriKind.Absolute); + break; + } + + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.UriSource = imageSourceUri; + bitmapImage.EndInit(); + + return new Image { Source = bitmapImage }; + } + + /// + /// Converts a value. + /// + /// The value that is produced by the binding target. + /// The type to convert to. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Debug.Assert(true, "ConvertBack is called."); + return new object(); + } + } +} diff --git a/Main/SimpleBackup.Views/BackupStateToImageConverter.cs b/Main/SimpleBackup.Views/BackupStateToImageConverter.cs new file mode 100644 index 0000000..63c1f48 --- /dev/null +++ b/Main/SimpleBackup.Views/BackupStateToImageConverter.cs @@ -0,0 +1,99 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System; + using System.Diagnostics; + using System.Windows.Controls; + using System.Windows.Data; + using System.Windows.Media.Imaging; + using SimpleBackup.Core.Models; + + /// + /// A converter which converts BackupState to Image. + /// + internal class BackupStateToImageConverter : IValueConverter + { + /// + /// Converts a value. + /// + /// The value produced by the binding source. + /// The type of the binding target property. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Uri imageSourceUri; + var backupState = (BackupState)value; + switch (backupState) + { + case BackupState.Todo: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/flag_16xLG.png", UriKind.Absolute); + break; + case BackupState.InProgress: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/Activity_16xLG.png", UriKind.Absolute); + break; + case BackupState.Success: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/StatusAnnotations_Complete_and_ok_32xLG_color.png", UriKind.Absolute); + break; + case BackupState.Failed: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/StatusAnnotations_Critical_32xLG_color.png", UriKind.Absolute); + break; + case BackupState.Cancelled: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/Warning.png", UriKind.Absolute); + break; + case BackupState.Skipped: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/Warning.png", UriKind.Absolute); + break; + default: + imageSourceUri = new Uri("pack://application:,,,/SimpleBackup.Resources;component/Images/Remove_16xLG.png", UriKind.Absolute); + break; + } + + var bitmapImage = new BitmapImage(); + bitmapImage.BeginInit(); + bitmapImage.UriSource = imageSourceUri; + bitmapImage.EndInit(); + + return new Image { Source = bitmapImage }; + } + + /// + /// Converts a value. + /// + /// The value that is produced by the binding target. + /// The type to convert to. + /// The converter parameter to use. + /// The culture to use in the converter. + /// + /// A converted value. If the method returns null, the valid null value is used. + /// + public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) + { + Debug.Assert(true, "ConvertBack is called."); + return new object(); + } + } +} diff --git a/Main/SimpleBackup.Views/ExDataGrid.cs b/Main/SimpleBackup.Views/ExDataGrid.cs new file mode 100644 index 0000000..f998a76 --- /dev/null +++ b/Main/SimpleBackup.Views/ExDataGrid.cs @@ -0,0 +1,148 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System; + using System.Linq; + using System.Windows; + using System.Windows.Controls; + using SimpleBackup.Core.Views; + + /// + /// An extended data grid control. + /// + internal class ExDataGrid : DataGrid + { + /// + /// The selected first cell item index property key + /// Read-Only Dependency Properties + /// http://msdn.microsoft.com/en-us/library/ms754044(v=vs.110).aspx + /// + public static readonly DependencyPropertyKey SelectedFirstCellItemIndexPropertyKey = + DependencyProperty.RegisterReadOnly( + "SelectedFirstCellItemIndex", + typeof(int), + typeof(ExDataGrid), + new PropertyMetadata(default(int))); + + /// + /// The selected first cell item index property + /// + public static readonly DependencyProperty SelectedFirstCellItemIndexProperty = + SelectedFirstCellItemIndexPropertyKey.DependencyProperty; + + /// + /// The selected first cell item property key + /// + public static readonly DependencyPropertyKey SelectedFirstCellItemPropertyKey = + DependencyProperty.RegisterReadOnly( + "SelectedFirstCellItem", + typeof(object), + typeof(ExDataGrid), + new PropertyMetadata(default(object))); + + /// + /// The selected first cell item property + /// + public static readonly DependencyProperty SelectedFirstCellItemProperty = + SelectedFirstCellItemPropertyKey.DependencyProperty; + + /// + /// Initializes a new instance of the class. + /// + public ExDataGrid() + { + this.Loaded += (sender, args) => + { + if (this.SelectedFirstCellItemChanged != null) + { + if (this.Items.Count != 0) + { + this.SelectedFirstCellItemChanged( + this, + new ExDataGridSelectedFirstCellItemChangedEventArgs( + 0, + this.Items[0])); + } + } + }; + } + + public event EventHandler SelectedFirstCellItemChanged; + + /// + /// Gets the index of the selected first cell item. + /// + public int SelectedFirstCellItemIndex + { + get + { + return (int)this.GetValue(SelectedFirstCellItemIndexProperty); + } + } + + /// + /// Gets the selected first cell item. + /// + public object SelectedFirstCellItem + { + get + { + return (object)this.GetValue(SelectedFirstCellItemProperty); + } + } + + protected override void OnSelectedCellsChanged(SelectedCellsChangedEventArgs e) + { + base.OnSelectedCellsChanged(e); + + int firstIndex = int.MaxValue; + object firstIndexItem = null; + + DataGridCellInfo[] validCellInfos = this.SelectedCells.Where(p => p.IsValid).ToArray(); + foreach (DataGridCellInfo cellInfo in validCellInfos) + { + int index = this.Items.IndexOf(cellInfo.Item); + if (index < firstIndex) + { + firstIndex = index; + firstIndexItem = cellInfo.Item; + } + } + + if (this.SelectedFirstCellItemIndex != firstIndex) + { + this.SetValue(SelectedFirstCellItemIndexPropertyKey, firstIndex); + this.SetValue(SelectedFirstCellItemPropertyKey, firstIndexItem); + + if (this.SelectedFirstCellItemChanged != null) + { + this.SelectedFirstCellItemChanged( + this, + new ExDataGridSelectedFirstCellItemChangedEventArgs( + firstIndex, + firstIndexItem)); + } + } + } + } +} diff --git a/Main/SimpleBackup.Views/ExDataGridSelectedFirstCellItemBehavior.cs b/Main/SimpleBackup.Views/ExDataGridSelectedFirstCellItemBehavior.cs new file mode 100644 index 0000000..b1a6b79 --- /dev/null +++ b/Main/SimpleBackup.Views/ExDataGridSelectedFirstCellItemBehavior.cs @@ -0,0 +1,102 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System.Windows; + using System.Windows.Interactivity; + using SimpleBackup.Core.Views; + + /// + /// Behavior for ExDataGrid's SelectedFirstCellItemIndex and SelectedFirstCellItem read-only dependency properties. + /// + internal class ExDataGridSelectedFirstCellItemBehavior : Behavior + { + /// + /// The selected first cell item index property. + /// This wraps ExDataGrid's SelectedFirstCellItemIndex read-only dependency property. + /// + public static readonly DependencyProperty SelectedFirstCellItemIndexProperty = + DependencyProperty.Register( + "SelectedFirstCellItemIndex", + typeof(int), + typeof(ExDataGridSelectedFirstCellItemBehavior), + new PropertyMetadata(default(int))); + + /// + /// The selected first cell item property. + /// This wraps ExDataGrid's SelectedFirstCellItem read-only dependency property. + /// + public static readonly DependencyProperty SelectedFirstCellItemProperty = + DependencyProperty.Register( + "SelectedFirstCellItem", + typeof(object), + typeof(ExDataGridSelectedFirstCellItemBehavior), + new PropertyMetadata(default(object))); + + /// + /// Gets or sets the index of the selected first cell item. + /// + public int SelectedFirstCellItemIndex + { + get { return (int)this.GetValue(SelectedFirstCellItemIndexProperty); } + set { this.SetValue(SelectedFirstCellItemIndexProperty, value); } + } + + /// + /// Gets or sets the selected first cell item. + /// + public object SelectedFirstCellItem + { + get { return (object)this.GetValue(SelectedFirstCellItemProperty); } + set { this.SetValue(SelectedFirstCellItemProperty, value); } + } + + /// + /// Called after the behavior is attached to an AssociatedObject. + /// + protected override void OnAttached() + { + base.OnAttached(); + this.AssociatedObject.SelectedFirstCellItemChanged += this.OnExDataGridSelectedFirstCellItemChanged; + } + + /// + /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. + /// + protected override void OnDetaching() + { + base.OnDetaching(); + this.AssociatedObject.SelectedFirstCellItemChanged -= this.OnExDataGridSelectedFirstCellItemChanged; + } + + /// + /// Called when ExDataGrid's SelectedFirstCellItemChanged event is published. + /// + /// The sender. + /// The instance containing the event data. + private void OnExDataGridSelectedFirstCellItemChanged(object sender, ExDataGridSelectedFirstCellItemChangedEventArgs e) + { + this.SelectedFirstCellItemIndex = e.SelectedFirstCellItemIndex; + this.SelectedFirstCellItem = e.SelectedFirstCellItem; + } + } +} diff --git a/Main/SimpleBackup.Views/FileFolderDialog.cs b/Main/SimpleBackup.Views/FileFolderDialog.cs new file mode 100644 index 0000000..c605a9b --- /dev/null +++ b/Main/SimpleBackup.Views/FileFolderDialog.cs @@ -0,0 +1,157 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System; + using System.IO; + using System.Text; + using System.Windows.Forms; + using SimpleBackup.Core.Views; + + /// + /// File folder dialog. + /// + internal class FileFolderDialog : CommonDialog, IFileFolderDialog + { + /// + /// The inner open file dialog + /// + private readonly OpenFileDialog innerOpenFileDialog = new OpenFileDialog(); + + /// + /// Gets or sets the selected path. + /// + public string SelectedPath + { + get + { + if ((string.IsNullOrEmpty(this.innerOpenFileDialog.FileName) == false) && + (this.innerOpenFileDialog.FileName.EndsWith("Folder Selection.") || (File.Exists(this.innerOpenFileDialog.FileName) == false)) && + (Directory.Exists(this.innerOpenFileDialog.FileName) == false)) + { + return Path.GetDirectoryName(this.innerOpenFileDialog.FileName); + } + + return this.innerOpenFileDialog.FileName; + } + + set + { + if (string.IsNullOrEmpty(value) == false) + { + this.innerOpenFileDialog.FileName = value; + } + } + } + + /// + /// Gets the selected paths as semi-colon seprated string. + /// + public string SelectedPaths + { + get + { + if ((this.innerOpenFileDialog.FileNames != null) && (this.innerOpenFileDialog.FileNames.Length > 1)) + { + var sb = new StringBuilder(); + foreach (string fileName in this.innerOpenFileDialog.FileNames) + { + if (File.Exists(fileName)) + { + sb.Append(fileName + ";"); + } + } + + return sb.ToString(); + } + + return null; + } + } + + /// + /// Runs a common dialog box with a default owner. + /// + /// + /// if the user clicks OK in the dialog box; otherwise, . + /// + /// + /// + /// + /// + /// + /// + public new DialogResult ShowDialog() + { + return this.ShowDialog(null); + } + + /// + /// Runs a common dialog box with the specified owner. + /// + /// Any object that implements that represents the top-level window that will own the modal dialog box. + /// + /// if the user clicks OK in the dialog box; otherwise, . + /// + public new DialogResult ShowDialog(IWin32Window owner) + { + this.innerOpenFileDialog.ValidateNames = false; + this.innerOpenFileDialog.CheckFileExists = false; + this.innerOpenFileDialog.CheckPathExists = true; + + // Set initial directory (used when dialog.FileName is set from outside) + if (string.IsNullOrEmpty(this.innerOpenFileDialog.FileName) == false) + { + this.innerOpenFileDialog.InitialDirectory = Directory.Exists(this.innerOpenFileDialog.FileName) + ? this.innerOpenFileDialog.FileName + : Path.GetDirectoryName(this.innerOpenFileDialog.FileName); + } + + // Always default to Folder Selection. + this.innerOpenFileDialog.FileName = "Folder Selection."; + + return (owner == null) + ? this.innerOpenFileDialog.ShowDialog() + : this.innerOpenFileDialog.ShowDialog(owner); + } + + /// + /// When overridden in a derived class, resets the properties of a common dialog box to their default values. + /// + public override void Reset() + { + this.innerOpenFileDialog.Reset(); + } + + /// + /// When overridden in a derived class, specifies a common dialog box. + /// + /// A value that represents the window handle of the owner window for the common dialog box. + /// + /// true if the dialog box was successfully run; otherwise, false. + /// + protected override bool RunDialog(IntPtr hwndOwner) + { + return true; + } + } +} diff --git a/Main/SimpleBackup.Views/MainWindow.xaml b/Main/SimpleBackup.Views/MainWindow.xaml new file mode 100644 index 0000000..2f4922c --- /dev/null +++ b/Main/SimpleBackup.Views/MainWindow.xaml @@ -0,0 +1,553 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Main/SimpleBackup.Views/MainWindow.xaml.cs b/Main/SimpleBackup.Views/MainWindow.xaml.cs new file mode 100644 index 0000000..8519569 --- /dev/null +++ b/Main/SimpleBackup.Views/MainWindow.xaml.cs @@ -0,0 +1,356 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System; + using System.ComponentModel; + using System.Linq; + using System.Windows; + using System.Windows.Controls; + using System.Windows.Controls.Primitives; + using System.Windows.Input; + using SimpleBackup.Core; + using SimpleBackup.Core.Services; + using SimpleBackup.Core.Utilities; + using SimpleBackup.Core.ViewModels; + using SimpleBackup.Core.Views; + using Application = System.Windows.Application; + using DataGrid = System.Windows.Controls.DataGrid; + using DataGridCell = System.Windows.Controls.DataGridCell; + using KeyEventArgs = System.Windows.Input.KeyEventArgs; + using MessageBox = System.Windows.MessageBox; + using TextBox = System.Windows.Controls.TextBox; + + /// + /// The Code-Behind of MainWindow.xaml. + /// + internal partial class MainWindow : Window, IMainWindow + { + private IBackupSettingService backupSettingService; + + /// + /// Prevents a default instance of the class from being created. + /// + private MainWindow() + { + this.InitializeComponent(); + + this.backupSettingService = ObjectContainer.Resolve(); + + this.DataContextChanged += (sender, args) => + { + var viewModel = this.DataContext as IMainWindowViewModel; + if (viewModel != null) + { + viewModel.FocusOnGrid += this.OnFocusOnGridRequired; + viewModel.FocusOnGridRow += this.OnFocusOnGridRowRequired; + } + else + { + throw new InvalidOperationException("The data context is not an IMainWindowViewModel object."); + } + }; + + this.BackupInfoDataGrid.Loaded += (sender, args) => + { + if (this.BackupInfoDataGrid.Items.Count != 0) + { + this.FocusOnGridRow(0); + } + }; + } + + /// + /// Creates the main window. + /// + /// The main window. + public static IMainWindow CreateMainWindow() + { + return new MainWindow(); + } + + /// + /// Raises the Closing event. + /// + /// A that contains the event data. + protected override void OnClosing(CancelEventArgs e) + { + if ((this.backupSettingService.CurrentSetting != null) && + this.backupSettingService.CurrentSetting.Modified) + { + MessageBoxResult confirmationResult = MessageBox.Show( + Application.Current.MainWindow, + SimpleBackup.Resources.Resources.Views_SaveConfirmationMessage, + SimpleBackup.Resources.Resources.Views_ConfirmationDialogTitle, + MessageBoxButton.YesNoCancel); + if (confirmationResult == MessageBoxResult.Yes) + { + if (this.backupSettingService.OverWriteCurrntBackupSetting() == false) + { + e.Cancel = true; + } + } + else if (confirmationResult == MessageBoxResult.Cancel) + { + e.Cancel = true; + } + } + } + + private void OnFocusOnGridRequired(object sender, EventArgs eventArgs) + { + this.BackupInfoDataGrid.Focus(); + } + + private void OnFocusOnGridRowRequired(object sender, FocusOnGridRowEventArgs args) + { + this.FocusOnGridRow(args.Index); + } + + private void FocusOnGridRow(int index) + { + this.BackupInfoDataGrid.Focus(); + var dataGridRow = this.BackupInfoDataGrid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; + if (dataGridRow != null) + { + dataGridRow.Focus(); + this.SelectBackupInfoDataGridItem(index); + + var dataGridCellsPanel = dataGridRow.GetVisualChild(); + if (dataGridCellsPanel != null) + { + if (dataGridCellsPanel.Children.Count != 0) + { + var dataGridCell = dataGridCellsPanel.Children[0] as DataGridCell; + if (dataGridCell != null) + { + dataGridCell.Focus(); + } + } + } + } + } + + private void SelectBackupInfoDataGridItem(int index) + { + this.BackupInfoDataGrid.SelectedIndex = index; + } + + private void OnDataGridMouseDoubleClick(object sender, MouseButtonEventArgs e) + { + var dataGrid = (DataGrid)sender; + var currentItemviewModel = dataGrid.CurrentItem as IBackupInfoViewModel; + if (currentItemviewModel == null) + { + return; + } + + DataGridCellInfo currentCellInfo = dataGrid.CurrentCell; + var currentColumnHeaderContentPresenter = currentCellInfo.Column.Header as ContentPresenter; + if (currentColumnHeaderContentPresenter != null) + { + var sourceColumnHeaderViewModel = + currentColumnHeaderContentPresenter.Content as ISourceColumnHeaderViewModel; + if (sourceColumnHeaderViewModel != null) + { + currentItemviewModel.ExecuteDoubleClickAction(BackupInfoPathType.Source); + } + else + { + var destinationColumnHeaderViewModel = + currentColumnHeaderContentPresenter.Content as IDestinationColumnHeaderViewModel; + if (destinationColumnHeaderViewModel != null) + { + currentItemviewModel.ExecuteDoubleClickAction(BackupInfoPathType.Destination); + } + } + } + } + + private void OnCellContentPreviewKeyDown(object sender, KeyEventArgs e) + { + Type sourceType = sender.GetType(); + + var sourceDataGridCell = ((DependencyObject)sender).SearchUpParentWithSelf(); + if (sourceDataGridCell == null) + { + return; + } + + var sourceDataGridRow = sourceDataGridCell.SearchUpParentWithSelf(); + if (sourceDataGridRow == null) + { + return; + } + + var dataGrid = sourceDataGridRow.SearchUpParentWithSelf(); + if (dataGrid == null) + { + return; + } + + int sourceRowIndex = dataGrid.Items.IndexOf(sourceDataGridRow.Item); + int targetRowIndex = -1; + switch (e.Key) + { + case Key.Up: + if (sourceRowIndex != 0) + { + targetRowIndex = sourceRowIndex - 1; + } + + break; + case Key.Down: + if (sourceRowIndex < dataGrid.Items.Count - 1) + { + targetRowIndex = sourceRowIndex + 1; + } + + break; + case Key.PageUp: + break; + case Key.PageDown: + break; + } + + if (targetRowIndex < 0) + { + return; + } + + var targetDataGridRow = dataGrid.ItemContainerGenerator.ContainerFromIndex(targetRowIndex) as DataGridRow; + if (targetDataGridRow == null) + { + return; + } + + var targetCellsPresenter = targetDataGridRow.GetVisualChild(); + if (targetCellsPresenter == null) + { + return; + } + + var targetDataGridCell = + (DataGridCell)targetCellsPresenter.ItemContainerGenerator.ContainerFromIndex(sourceDataGridCell.Column.DisplayIndex); + if (targetDataGridCell == null) + { + return; + } + + var targetElement = targetDataGridCell.GetVisualChild(sourceType) as UIElement; + if (targetElement == null) + { + return; + } + + sourceDataGridRow.IsSelected = false; + targetDataGridRow.IsSelected = true; + targetElement.Focus(); + + e.Handled = true; + } + + private void OnMainWindowPreviewKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.F2) + { + this.StartEditCurrentCell(); + e.Handled = true; + } + else if (e.Key == Key.Escape) + { + var viewModel = this.DataContext as IMainWindowViewModel; + if (viewModel != null) + { + viewModel.OnEscKeyPressed(); + } + + e.Handled = true; + } + else if ((Keyboard.Modifiers & ModifierKeys.Control) > 0) + { + if (e.Key == Key.S) + { + var viewModel = this.DataContext as IMainWindowViewModel; + if (viewModel != null) + { + if (viewModel.SaveBackupSettingRelayCommand.CanExecute(this)) + { + viewModel.SaveBackupSettingRelayCommand.Execute(this); + e.Handled = true; + } + } + } + } + } + + private void StartEditCurrentCell() + { + var currentItemviewModel = this.BackupInfoDataGrid.CurrentItem as IBackupInfoViewModel; + if (currentItemviewModel == null) + { + return; + } + + DataGridCellInfo currentCellInfo = this.BackupInfoDataGrid.CurrentCell; + var currentColumnHeaderContentPresenter = currentCellInfo.Column.Header as ContentPresenter; + if (currentColumnHeaderContentPresenter != null) + { + if (currentColumnHeaderContentPresenter.Content is ISourceColumnHeaderViewModel) + { + currentItemviewModel.EditSourceRelayCommand.Execute(null); + this.FocusOnTextBoxInSelectedDataGridCell(); + } + else if (currentColumnHeaderContentPresenter.Content is IDestinationColumnHeaderViewModel) + { + currentItemviewModel.EditDestinationRelayCommand.Execute(null); + this.FocusOnTextBoxInSelectedDataGridCell(); + } + else if (currentColumnHeaderContentPresenter.Content is ILabelColumnHeaderViewModel) + { + this.FocusOnTextBoxInSelectedDataGridCell(); + } + } + } + + private void FocusOnTextBoxInSelectedDataGridCell() + { + DataGridCellInfo cellInfo = this.BackupInfoDataGrid.SelectedCells.FirstOrDefault(); + var cellContentPresenter = cellInfo.Column.GetCellContent(cellInfo.Item) as ContentPresenter; + if (cellContentPresenter != null) + { + var textBox = cellContentPresenter.GetVisualChild(); + if (textBox != null) + { + textBox.Focus(); + textBox.Select(textBox.Text.Length, 0); + } + } + } + + private void OnZipEncodingSelectionChanged(object sender, SelectionChangedEventArgs e) + { + // Move focus setting from the ComboBox by setting focus to the main window. + this.Focus(); + } + } +} diff --git a/Main/SimpleBackup.Views/SimpleBackup.Views.csproj b/Main/SimpleBackup.Views/SimpleBackup.Views.csproj new file mode 100644 index 0000000..7fce336 --- /dev/null +++ b/Main/SimpleBackup.Views/SimpleBackup.Views.csproj @@ -0,0 +1,118 @@ + + + + + Debug + AnyCPU + {C42B720C-323E-4E0C-ACBF-7FA9CFE228BE} + Library + Properties + SimpleBackup.Views + SimpleBackup.Views + v4.5 + 512 + SAK + SAK + SAK + SAK + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + + + pdbonly + true + bin\Release\ + TRACE + prompt + 4 + + + true + + + SimpleBackupKey.snk + + + + + + + + + False + ..\Lib\Expression\Blend\.NETFramework\v4.5\Libraries\System.Windows.Interactivity.dll + + + + + + + + + + + + Properties\AssemblyInfo.cs + + + + + + + Component + + + MainWindow.xaml + + + VersionInformationWindow.xaml + + + + + + + + + + {33f1d454-9962-4eb6-aad3-8d11d9a78d1f} + SimpleBackup.Core + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + + + + + MSBuild:Compile + Designer + + + + + MSBuild:Compile + Designer + + + + + set EXE_BIN_DIR=$(ProjectDir)..\bin\$(ConfigurationName)\ +xcopy "$(TargetDir)$(TargetName).dll" "%25EXE_BIN_DIR%25" /Y +if exist "$(TargetDir)$(TargetName).pdb" xcopy "$(TargetDir)$(TargetName).pdb" "%25EXE_BIN_DIR%25" /Y + + + \ No newline at end of file diff --git a/Main/SimpleBackup.Views/SimpleBackupKey.snk b/Main/SimpleBackup.Views/SimpleBackupKey.snk new file mode 100644 index 0000000..def2e6d Binary files /dev/null and b/Main/SimpleBackup.Views/SimpleBackupKey.snk differ diff --git a/Main/SimpleBackup.Views/VersionInformationWindow.xaml b/Main/SimpleBackup.Views/VersionInformationWindow.xaml new file mode 100644 index 0000000..0e0d9aa --- /dev/null +++ b/Main/SimpleBackup.Views/VersionInformationWindow.xaml @@ -0,0 +1,66 @@ + + + + + + + + + + + + + + + + + diff --git a/Main/SimpleBackup.Views/VersionInformationWindow.xaml.cs b/Main/SimpleBackup.Views/VersionInformationWindow.xaml.cs new file mode 100644 index 0000000..2fe79f0 --- /dev/null +++ b/Main/SimpleBackup.Views/VersionInformationWindow.xaml.cs @@ -0,0 +1,59 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System.Reflection; + using System.Windows; + using SimpleBackup.Core.Views; + + /// + /// The Code-Behind of VersionInformationWindow.xaml. + /// + internal partial class VersionInformationWindow : Window, IVersionInformationWindow + { + /// + /// Initializes a new instance of the class. + /// + public VersionInformationWindow() + { + this.InitializeComponent(); + + this.VersionInfoTextBox.Text = string.Format( + "{0} Ver.{1}\r\n{2}", + SimpleBackup.Resources.Resources.Views_CopyrightApplicationName, + Assembly.GetExecutingAssembly().GetName().Version, + SimpleBackup.Resources.Resources.Version_Copyright); + this.CopyrightTextBox.Text = SimpleBackup.Resources.Resources.Version_CopyrightDescription; + } + + /// + /// Shows the dialog window. + /// + /// + /// The result. + /// + public bool? ShowDialogWindow() + { + return this.ShowDialog(); + } + } +} diff --git a/Main/SimpleBackup.Views/ViewComponent.cs b/Main/SimpleBackup.Views/ViewComponent.cs new file mode 100644 index 0000000..6c881ea --- /dev/null +++ b/Main/SimpleBackup.Views/ViewComponent.cs @@ -0,0 +1,41 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using SimpleBackup.Core; + using SimpleBackup.Core.AppInfrastructure; + using SimpleBackup.Core.Views; + + /// + /// The view component. + /// + internal class ViewComponent : IAppComponent + { + /// + /// Initializes this application component. + /// + public void Initialize() + { + ObjectContainer.Register(new ViewFactory()); + } + } +} diff --git a/Main/SimpleBackup.Views/ViewFactory.cs b/Main/SimpleBackup.Views/ViewFactory.cs new file mode 100644 index 0000000..ea89c16 --- /dev/null +++ b/Main/SimpleBackup.Views/ViewFactory.cs @@ -0,0 +1,69 @@ +//----------------------------------------------------------------------- +// +// Copyright (c) Takayoshi Matsuyama. All rights reserved. +// +//----------------------------------------------------------------------- + +// This file is part of Simple Backup. +// +// Simple Backup is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// Simple Backup is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with Simple Backup. If not, see . + +namespace SimpleBackup.Views +{ + using System.Windows; + using SimpleBackup.Core.Views; + + /// + /// Creates view objects. + /// + internal class ViewFactory : IViewFactory + { + /// + /// Creates the main window. + /// + /// + /// The main window. + /// + public IMainWindow CreateMainWindow() + { + return MainWindow.CreateMainWindow(); + } + + /// + /// Creates the version information window. + /// + /// + /// The version information window. + /// + public IVersionInformationWindow CreateVersionInformationWindow() + { + return new VersionInformationWindow + { + Owner = Application.Current.MainWindow, + WindowStartupLocation = WindowStartupLocation.CenterOwner + }; + } + + /// + /// Creates the file folder dialog. + /// + /// + /// The file folder dialog. + /// + public IFileFolderDialog CreateFileFolderDialog() + { + return new FileFolderDialog(); + } + } +} diff --git a/Main/SimpleBackup.csproj b/Main/SimpleBackup.csproj index 2aaad22..05dd942 100644 --- a/Main/SimpleBackup.csproj +++ b/Main/SimpleBackup.csproj @@ -59,25 +59,22 @@ SimpleBackupKey.snk - Resources\Images\ApplicationIcon.ico + + - - False Lib\Expression\Blend\.NETFramework\v4.5\Libraries\System.Windows.Interactivity.dll + - - 4.0 - @@ -87,83 +84,11 @@ MSBuild:Compile Designer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - VersionInformationWindow.xaml - - - MSBuild:Compile - Designer - + App.xaml Code - - - True - True - Resources.resx - - - - - - - - - - - - - - - - - - - - - Component - - - MainWindow.xaml - Code - - - Designer - MSBuild:Compile - @@ -183,11 +108,6 @@ ResXFileCodeGenerator Resources.Designer.cs - - - ResXFileCodeGenerator - Resources.Designer.cs - PreserveNewest @@ -206,9 +126,6 @@ - - - False Microsoft .NET Framework 4.5 %28x86 および x64%29 @@ -226,63 +143,16 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + {33f1d454-9962-4eb6-aad3-8d11d9a78d1f} + SimpleBackup.Core + + + {a655131e-d439-4de1-bc39-5c955306183f} + SimpleBackup.Resources + +