wabbajack/Wabbajack/View Models/MainWindowVM.cs

207 lines
7.1 KiB
C#
Raw Normal View History

2020-02-11 23:02:12 +00:00
using DynamicData;
using DynamicData.Binding;
using ReactiveUI;
2019-11-02 23:23:11 +00:00
using ReactiveUI.Fody.Helpers;
2019-10-22 02:12:55 +00:00
using System;
2019-12-20 20:51:10 +00:00
using System.Collections.Generic;
2019-12-14 23:31:53 +00:00
using System.Diagnostics;
2019-10-22 02:12:55 +00:00
using System.Linq;
using System.Reactive;
using System.Reactive.Disposables;
using System.Reactive.Linq;
using System.Reflection;
using System.Threading.Tasks;
2019-12-04 04:12:08 +00:00
using System.Windows;
2019-12-14 23:31:53 +00:00
using System.Windows.Input;
using System.Windows.Threading;
using Alphaleonis.Win32.Filesystem;
using Wabbajack.Common;
2019-12-04 04:12:08 +00:00
using Wabbajack.Common.StatusFeed;
2019-10-22 02:12:55 +00:00
using Wabbajack.Lib;
namespace Wabbajack
{
/// <summary>
/// Main View Model for the application.
/// Keeps track of which sub view is being shown in the window, and has some singleton wiring like WorkQueue and Logging.
/// </summary>
2019-10-22 02:12:55 +00:00
public class MainWindowVM : ViewModel
{
public MainWindow MainWindow { get; }
2019-10-22 02:12:55 +00:00
public MainSettings Settings { get; }
2019-11-24 08:12:28 +00:00
[Reactive]
public ViewModel ActivePane { get; private set; }
2019-10-22 02:12:55 +00:00
2019-12-04 04:12:08 +00:00
public ObservableCollectionExtended<IStatusMessage> Log { get; } = new ObservableCollectionExtended<IStatusMessage>();
2019-11-24 08:12:28 +00:00
public readonly Lazy<CompilerVM> Compiler;
public readonly Lazy<InstallerVM> Installer;
public readonly Lazy<SettingsVM> SettingsPane;
2019-11-30 09:08:04 +00:00
public readonly Lazy<ModListGalleryVM> Gallery;
2019-11-24 08:12:28 +00:00
public readonly ModeSelectionVM ModeSelectionVM;
2019-12-08 17:00:22 +00:00
public readonly UserInterventionHandlers UserInterventionHandlers;
2019-12-20 20:51:10 +00:00
2019-12-14 23:31:53 +00:00
public ICommand CopyVersionCommand { get; }
2019-12-20 20:51:10 +00:00
public ICommand ShowLoginManagerVM { get; }
public ICommand OpenSettingsCommand { get; }
public ICommand OpenTerminalCommand { get; }
2019-12-14 23:31:53 +00:00
public string VersionDisplay { get; }
[Reactive]
public bool UpdateAvailable { get; private set; }
2019-11-24 08:12:28 +00:00
public MainWindowVM(MainWindow mainWindow, MainSettings settings)
2019-10-22 02:12:55 +00:00
{
ConverterRegistration.Register();
2019-11-21 15:04:33 +00:00
MainWindow = mainWindow;
Settings = settings;
2019-11-24 08:12:28 +00:00
Installer = new Lazy<InstallerVM>(() => new InstallerVM(this));
Compiler = new Lazy<CompilerVM>(() => new CompilerVM(this));
SettingsPane = new Lazy<SettingsVM>(() => new SettingsVM(this));
2019-11-30 09:08:04 +00:00
Gallery = new Lazy<ModListGalleryVM>(() => new ModListGalleryVM(this));
2019-11-24 08:12:28 +00:00
ModeSelectionVM = new ModeSelectionVM(this);
UserInterventionHandlers = new UserInterventionHandlers(this);
// Set up logging
Utils.LogMessages
.ObserveOn(RxApp.TaskpoolScheduler)
.ToObservableChangeSet()
.Buffer(TimeSpan.FromMilliseconds(250), RxApp.TaskpoolScheduler)
.Where(l => l.Count > 0)
.FlattenBufferResult()
2020-01-09 03:22:49 +00:00
.ObserveOnGuiThread()
2019-11-21 15:04:33 +00:00
.Bind(Log)
.Subscribe()
2019-11-21 15:04:33 +00:00
.DisposeWith(CompositeDisposable);
2020-02-06 05:30:31 +00:00
var singleton_lock = new AsyncLock();
2019-11-17 04:16:42 +00:00
2019-12-04 04:12:08 +00:00
Utils.LogMessages
2019-12-08 17:00:22 +00:00
.OfType<IUserIntervention>()
.ObserveOnGuiThread()
.SelectTask(async msg =>
{
using var _ = await singleton_lock.WaitAsync();
try
{
await UserInterventionHandlers.Handle(msg);
}
catch (Exception ex)
2020-02-06 05:30:31 +00:00
when (ex.GetType() != typeof(TaskCanceledException))
{
Utils.Error(ex, $"Error while handling user intervention of type {msg?.GetType()}");
try
{
if (!msg.Handled)
{
msg.Cancel();
}
}
catch (Exception cancelEx)
{
Utils.Error(cancelEx, $"Error while cancelling user intervention of type {msg?.GetType()}");
}
}
})
.Subscribe()
.DisposeWith(CompositeDisposable);
if (IsStartingFromModlist(out var path))
{
2019-12-03 05:40:59 +00:00
Installer.Value.ModListLocation.TargetPath = path;
NavigateTo(Installer.Value);
}
else
{
// Start on mode selection
NavigateTo(ModeSelectionVM);
}
2019-12-14 23:31:53 +00:00
try
{
2020-02-24 15:29:33 +00:00
var assembly = Assembly.GetExecutingAssembly();
var fvi = FileVersionInfo.GetVersionInfo(assembly.Location);
2019-12-14 23:31:53 +00:00
VersionDisplay = $"v{fvi.FileVersion}";
2020-02-24 15:29:33 +00:00
Utils.Log($"Wabbajack Version: {fvi.FileVersion}");
2020-05-09 23:23:41 +00:00
var _ = Metrics.Send("started_wabbajack", fvi.FileVersion);
2019-12-14 23:31:53 +00:00
}
catch (Exception ex)
{
Utils.Error(ex);
VersionDisplay = "ERROR";
}
CopyVersionCommand = ReactiveCommand.Create(() =>
{
Clipboard.SetText($"Wabbajack {VersionDisplay}\n{ThisAssembly.Git.Sha}");
});
OpenSettingsCommand = ReactiveCommand.Create(
canExecute: this.WhenAny(x => x.ActivePane)
.Select(active => !SettingsPane.IsValueCreated || !object.ReferenceEquals(active, SettingsPane.Value)),
execute: () => NavigateTo(SettingsPane.Value));
OpenTerminalCommand = ReactiveCommand.Create(() => OpenTerminal());
2020-05-09 23:23:41 +00:00
}
private void OpenTerminal()
{
var process = new ProcessStartInfo
{
FileName = "cmd.exe",
WorkingDirectory = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location)
};
Process.Start(process);
ShutdownApplication();
}
2020-03-28 20:04:22 +00:00
private static bool IsStartingFromModlist(out AbsolutePath modlistPath)
{
if (CLIArguments.InstallPath == null)
{
modlistPath = default;
return false;
}
2020-03-28 20:04:22 +00:00
modlistPath = (AbsolutePath)CLIArguments.InstallPath;
return true;
}
2019-11-30 09:08:04 +00:00
2019-12-20 20:51:10 +00:00
2020-03-28 20:04:22 +00:00
public void OpenInstaller(AbsolutePath path)
2019-11-30 09:08:04 +00:00
{
2020-03-28 20:04:22 +00:00
if (path == default) return;
2019-11-30 09:08:04 +00:00
var installer = Installer.Value;
Settings.Installer.LastInstalledListLocation = path;
NavigateTo(installer);
2019-12-03 05:40:59 +00:00
installer.ModListLocation.TargetPath = path;
2019-11-30 09:08:04 +00:00
}
2019-12-11 04:59:15 +00:00
public void NavigateTo(ViewModel vm)
2019-12-20 20:51:10 +00:00
{
ActivePane = vm;
2019-12-20 20:51:10 +00:00
}
public void NavigateTo<T>(T vm)
where T : ViewModel, IBackNavigatingVM
2019-12-20 20:51:10 +00:00
{
vm.NavigateBackTarget = ActivePane;
2019-12-20 20:51:10 +00:00
ActivePane = vm;
}
2019-12-11 04:59:15 +00:00
public void ShutdownApplication()
{
Dispose();
Settings.PosX = MainWindow.Left;
Settings.PosY = MainWindow.Top;
Settings.Width = MainWindow.Width;
Settings.Height = MainWindow.Height;
MainSettings.SaveSettings(Settings).AsTask().Wait();
2019-12-11 04:59:15 +00:00
Application.Current.Shutdown();
}
2019-10-22 02:12:55 +00:00
}
}