//-----------------------------------------------------------------------
//
// 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 Foobar. If not, see .
using System;
using System.IO;
using System.Linq;
using System.Windows;
using System.Windows.Input;
using System.Xml.Linq;
using SimpleBackup.Core.Models;
using SimpleBackup.Core.Services;
using SimpleBackup.Core.Utilities;
using SimpleBackup.Models;
namespace SimpleBackup.Services
{
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.
///
public 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 backupSetting = new BackupSetting { Modified = true };
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 backupInfo = new BackupInfo();
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 backupInfo = new BackupInfo(sourceBackupInfo);
return backupInfo;
}
///
/// 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";
}
BackupSetting backupSetting = ModelHelper.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;
}
///
/// 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));
}
}
}
}