using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Input;
using VBASync.Localization;
using VBASync.Model;
namespace VBASync.WPF {
internal sealed partial class MainWindow : IDisposable {
internal const int CopyrightYear = 2017;
internal const string SupportUrl = "https://github.com/chelh/VBASync";
internal static readonly Version Version = new Version(2, 2, 0);
private readonly MainViewModel _vm;
private bool _doUpdateIncludeAll = true;
public MainWindow(Startup startup) {
InitializeComponent();
DataContext = _vm = new MainViewModel(startup, QuietRefreshIfInputsOk);
DataContextChanged += (s, e) => QuietRefreshIfInputsOk();
_vm.Session.PropertyChanged += (s, e) => QuietRefreshIfInputsOk();
QuietRefreshIfInputsOk();
SessionCtl.FileBrowseBox.LostFocus += (s, e) => QuietRefreshIfInputsOk();
SessionCtl.FolderBrowseBox.LostFocus += (s, e) => QuietRefreshIfInputsOk();
SessionCtl.FileBrowseBox.Drop += (s, e) => QuietRefreshIfInputsOk();
SessionCtl.FolderBrowseBox.Drop += (s, e) => QuietRefreshIfInputsOk();
}
private ISession Session => _vm.Session;
public void Dispose()
{
_vm.Dispose();
}
internal void SettingsMenu_Click(object sender, RoutedEventArgs e)
{
new SettingsWindow(_vm.Settings, s => { _vm.Settings = s; QuietRefreshIfInputsOk(); }).ShowDialog();
}
private void AboutMenu_Click(object sender, RoutedEventArgs e)
{
new AboutWindow().ShowDialog();
}
private void ApplyButton_Click(object sender, RoutedEventArgs e)
{
var changes = _vm.Changes;
var committedChanges = changes?.Where(p => p.Commit).ToList();
if (committedChanges == null || committedChanges.Count == 0)
{
return;
}
_vm.ActiveSession.Apply(committedChanges);
QuietRefreshIfInputsOk();
}
private void CancelButton_Click(object sender, RoutedEventArgs e) {
Application.Current.Shutdown();
}
private void ChangesGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
var sel = (Patch)ChangesGrid.SelectedItem;
ILocateModules oldModuleLocator;
ILocateModules newModuleLocator;
if (Session.Action == ActionType.Extract) {
oldModuleLocator = _vm.ActiveSession.TemporaryFolderModuleLocator;
newModuleLocator = _vm.ActiveSession.RepositoryFolderModuleLocator;
} else {
oldModuleLocator = _vm.ActiveSession.RepositoryFolderModuleLocator;
newModuleLocator = _vm.ActiveSession.TemporaryFolderModuleLocator;
}
string oldPath;
string newPath;
if (sel.ChangeType == ChangeType.ChangeFormControls)
{
oldPath = oldModuleLocator.GetFrxPath(sel.ModuleName);
newPath = newModuleLocator.GetFrxPath(sel.ModuleName);
}
else
{
oldPath = oldModuleLocator.GetModulePath(sel.ModuleName, sel.ModuleType);
newPath = newModuleLocator.GetModulePath(sel.ModuleName, sel.ModuleType);
}
if (sel.ChangeType == ChangeType.ChangeFormControls) {
Lib.FrxFilesAreDifferent(oldPath, newPath, out var explain);
MessageBox.Show(explain, VBASyncResources.ExplainFrxTitle, MessageBoxButton.OK, MessageBoxImage.Information);
} else {
var diffExePath = Environment.ExpandEnvironmentVariables(_vm.Settings.DiffTool);
if (!File.Exists(oldPath) || !File.Exists(newPath) || !File.Exists(diffExePath)) {
return;
}
var p = new Process {
StartInfo = new ProcessStartInfo(diffExePath, _vm.Settings.DiffToolParameters.Replace("{OldFile}", oldPath).Replace("{NewFile}", newPath)) {
UseShellExecute = false
}
};
p.Start();
}
}
private void CheckAndFixErrors()
{
if (!SessionCtl.DataValidationFaulted)
{
return;
}
var filePath = SessionCtl.FaultedFilePath;
var folderPath = SessionCtl.FaultedFolderPath;
if (!string.IsNullOrEmpty(filePath) && filePath.Length > 2 && !FileOrFolderExists(filePath)
&& filePath.StartsWith("\"") && filePath.EndsWith("\"")
&& FileOrFolderExistsOrIsRooted(filePath.Substring(1, filePath.Length - 2)))
{
filePath = filePath.Substring(1, filePath.Length - 2);
_vm.Session.FilePath = filePath;
}
if (!string.IsNullOrEmpty(folderPath) && folderPath.Length > 2 && !FileOrFolderExists(folderPath)
&& folderPath.StartsWith("\"") && folderPath.EndsWith("\"")
&& FileOrFolderExistsOrIsRooted(folderPath.Substring(1, folderPath.Length - 2)))
{
folderPath = folderPath.Substring(1, folderPath.Length - 2);
_vm.Session.FolderPath = folderPath;
}
if (!string.IsNullOrEmpty(filePath) && !string.IsNullOrEmpty(folderPath)
&& !File.Exists(filePath) && !Directory.Exists(folderPath)
&& File.Exists(folderPath) && Directory.Exists(filePath))
{
_vm.Session.FolderPath = filePath;
_vm.Session.FilePath = folderPath;
}
bool FileOrFolderExists(string path) => File.Exists(path) || Directory.Exists(path);
bool FileOrFolderExistsOrIsRooted(string path) => FileOrFolderExists(path) || Path.IsPathRooted(path);
}
private void ExitMenu_Click(object sender, RoutedEventArgs e) {
CancelButton_Click(null, null);
}
private void IncludeAllBox_Click(object sender, RoutedEventArgs e)
{
var vm = _vm.Changes;
if (vm == null || IncludeAllBox.IsChecked == null) {
return;
}
try {
_doUpdateIncludeAll = false;
foreach (var ch in vm) {
ch.Commit = IncludeAllBox.IsChecked.Value;
}
} finally {
_doUpdateIncludeAll = true;
}
ChangesGrid.Items.Refresh();
}
private void OkButton_Click(object sender, RoutedEventArgs e) {
ApplyButton_Click(null, null);
Application.Current.Shutdown();
}
private void QuietRefreshIfInputsOk() {
CheckAndFixErrors();
if (SessionCtl.DataValidationFaulted) {
_vm.Changes = null;
ApplyButton.IsEnabled = false;
return;
}
try {
RefreshButton_Click(null, null);
} catch {
_vm.Changes = null;
ApplyButton.IsEnabled = false;
}
}
private void RefreshButton_Click(object sender, RoutedEventArgs e) {
try
{
CheckAndFixErrors();
if (SessionCtl.DataValidationFaulted)
{
_vm.Changes = null;
return;
}
_vm.RefreshActiveSession();
var changes = new ChangesViewModel(_vm.ActiveSession.GetPatches());
_vm.Changes = changes;
foreach (var p in changes)
{
p.CommitChanged += (s2, e2) => UpdateIncludeAllBox();
}
UpdateIncludeAllBox();
}
finally
{
ApplyButton.IsEnabled = _vm.Changes?.Count > 0;
}
}
private void UpdateIncludeAllBox() {
if (!_doUpdateIncludeAll) {
return;
}
var vm = _vm.Changes;
if (vm.All(p => p.Commit)) {
IncludeAllBox.IsChecked = true;
} else if (vm.All(p => !p.Commit)) {
IncludeAllBox.IsChecked = false;
} else {
IncludeAllBox.IsChecked = null;
}
}
private void Window_Closed(object sender, EventArgs e) {
_vm.ActiveSession?.Dispose();
string lastSessionPath;
if (_vm.Settings.Portable)
{
var exeDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
lastSessionPath = Path.Combine(exeDir, "LastSession.ini");
}
else
{
lastSessionPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"VBA Sync Tool", "LastSession.ini");
Directory.CreateDirectory(Path.GetDirectoryName(lastSessionPath));
}
using (var st = new FileStream(lastSessionPath, FileMode.Create))
{
_vm.SaveSession(st, true, true);
}
}
private void Window_Loaded(object sender, RoutedEventArgs e) {
QuietRefreshIfInputsOk();
if (Session.AutoRun) {
OkButton_Click(null, null);
}
}
}
}