diff --git a/src/IronyModManager.Shared/LocalizationResources.cs b/src/IronyModManager.Shared/LocalizationResources.cs
index af7db1e9..e70209f9 100644
--- a/src/IronyModManager.Shared/LocalizationResources.cs
+++ b/src/IronyModManager.Shared/LocalizationResources.cs
@@ -839,6 +839,7 @@ public static class Mod_App_Actions
public const string OpenInSteam = Prefix + "OpenInSteam";
public const string Open = Prefix + "Open";
public const string Copy = Prefix + "Copy";
+ public const string CopyPath = Prefix + "CopyPath";
public const string OpenInAssociatedApp = Prefix + "OpenInAssociatedApp";
}
public static class Descriptor_Actions
diff --git a/src/IronyModManager/Localization/de.json b/src/IronyModManager/Localization/de.json
index d1c49d07..09f19aef 100644
--- a/src/IronyModManager/Localization/de.json
+++ b/src/IronyModManager/Localization/de.json
@@ -627,6 +627,7 @@
"OpenInSteam": "In Steam Öffnen",
"Open": "Mod-URL Öffnen",
"Copy": "Mod-URL Kopieren",
+ "CopyPath": "Mod-Pfad kopieren",
"OpenInAssociatedApp": "Mod-Ordner/Mod-Datei Öffnen"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/en.json b/src/IronyModManager/Localization/en.json
index 479fe1dc..027f2dbb 100644
--- a/src/IronyModManager/Localization/en.json
+++ b/src/IronyModManager/Localization/en.json
@@ -627,6 +627,7 @@
"OpenInSteam": "Open In Steam",
"Open": "Open Mod Url",
"Copy": "Copy Mod Url",
+ "CopyPath": "Copy Mod Path",
"OpenInAssociatedApp": "Open Mod Folder/File"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/es.json b/src/IronyModManager/Localization/es.json
index dd415c7d..02a0c425 100644
--- a/src/IronyModManager/Localization/es.json
+++ b/src/IronyModManager/Localization/es.json
@@ -627,6 +627,7 @@
"OpenInSteam": "Abrir en Steam",
"Open": "Abrir Mod Url",
"Copy": "Copiar Mod Url",
+ "CopyPath": "Copiar Ruta Mod",
"OpenInAssociatedApp": "Abrir Mod Folder/Archivo"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/fr.json b/src/IronyModManager/Localization/fr.json
index be2d8e9c..66d379fd 100644
--- a/src/IronyModManager/Localization/fr.json
+++ b/src/IronyModManager/Localization/fr.json
@@ -627,6 +627,7 @@
"OpenInSteam": "Ouvrir dans Steam",
"Open": "Ouvrir l'URL du mod",
"Copy": "Copier l'URL du mod",
+ "CopyPath": "Copier le chemin du module",
"OpenInAssociatedApp": "Ouvrir le dossier/fichier de mod"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/hr.json b/src/IronyModManager/Localization/hr.json
index e13ef6d3..bb089968 100644
--- a/src/IronyModManager/Localization/hr.json
+++ b/src/IronyModManager/Localization/hr.json
@@ -627,6 +627,7 @@
"OpenInSteam": "Otvori u steamu",
"Open": "Otvori adresu moda",
"Copy": "Kopiraj adresu moda",
+ "CopyPath": "Kopiraj putanju moda",
"OpenInAssociatedApp": "Otvorite Mod mapu/datoteku"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/ru.json b/src/IronyModManager/Localization/ru.json
index 15e50d0d..1398584d 100644
--- a/src/IronyModManager/Localization/ru.json
+++ b/src/IronyModManager/Localization/ru.json
@@ -627,6 +627,7 @@
"OpenInSteam": "Открыть в Steam",
"Open": "Открыть ссылку на мод",
"Copy": "Копировать ссылку на мод",
+ "CopyPath": "Копирование пути к модулю",
"OpenInAssociatedApp": "Открыть папку/файл мода"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/Localization/zh.json b/src/IronyModManager/Localization/zh.json
index 2baa9298..9fea8174 100644
--- a/src/IronyModManager/Localization/zh.json
+++ b/src/IronyModManager/Localization/zh.json
@@ -627,6 +627,7 @@
"OpenInSteam": "在 Steam 中打开",
"Open": "打开模组链接",
"Copy": "复制模组链接",
+ "CopyPath": "复制模块路径",
"OpenInAssociatedApp": "打开模组目录或文件"
},
"Descriptor_Actions": {
diff --git a/src/IronyModManager/ViewModels/Controls/CollectionModsControlViewModel.cs b/src/IronyModManager/ViewModels/Controls/CollectionModsControlViewModel.cs
index 0c619376..0e6fa004 100644
--- a/src/IronyModManager/ViewModels/Controls/CollectionModsControlViewModel.cs
+++ b/src/IronyModManager/ViewModels/Controls/CollectionModsControlViewModel.cs
@@ -1,5 +1,4 @@
-
-// ***********************************************************************
+// ***********************************************************************
// Assembly : IronyModManager
// Author : Mario
// Created : 03-03-2020
@@ -12,6 +11,7 @@
//
//
// ***********************************************************************
+
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -47,7 +47,6 @@
namespace IronyModManager.ViewModels.Controls
{
-
///
/// Class CollectionModsControlViewModel.
/// Implements the
@@ -176,7 +175,7 @@ public class CollectionModsControlViewModel : BaseViewModel
///
/// The enable all toggled state
///
- private bool enableAllToggledState = false;
+ private bool enableAllToggledState;
///
/// The mod export progress
@@ -196,7 +195,7 @@ public class CollectionModsControlViewModel : BaseViewModel
///
/// The refresh in progress
///
- private bool refreshInProgress = false;
+ private bool refreshInProgress;
///
/// The reorder token
@@ -211,17 +210,17 @@ public class CollectionModsControlViewModel : BaseViewModel
///
/// The skip mod collection save
///
- private bool skipModCollectionSave = false;
+ private bool skipModCollectionSave;
///
/// The skip mod selection save
///
- private bool skipModSelectionSave = false;
+ private bool skipModSelectionSave;
///
/// The skip reorder
///
- private bool skipReorder = false;
+ private bool skipReorder;
#endregion Fields
@@ -453,6 +452,23 @@ public enum ImportProviderType
/// The context menu mod.
public virtual IMod ContextMenuMod { get; set; }
+ ///
+ /// Gets or sets a value representing the copy mod path.
+ ///
+ ///
+ /// The copy mod path.
+ ///
+ [StaticLocalization(LocalizationResources.Mod_App_Actions.CopyPath)]
+ public virtual string CopyModPath { get; protected set; }
+
+ ///
+ /// Gets or sets a value representing the copy mod path command.
+ ///
+ ///
+ /// The copy mod path command.
+ ///
+ public virtual ReactiveCommand CopyModPathCommand { get; protected set; }
+
///
/// Gets or sets the copy URL.
///
@@ -845,6 +861,7 @@ public virtual string GetContextMenuModSteamUrl()
var url = modService.BuildSteamUrl(ContextMenuMod);
return url;
}
+
return string.Empty;
}
@@ -859,6 +876,7 @@ public virtual string GetContextMenuModUrl()
var url = modService.BuildModUrl(ContextMenuMod);
return url;
}
+
return string.Empty;
}
@@ -874,6 +892,7 @@ public virtual void HandleEnableAllToggled(bool toggledState, bool enabled, IEnu
{
skipModCollectionSave = true;
}
+
if (!toggledState && enableAllToggledState)
{
skipModCollectionSave = false;
@@ -905,6 +924,7 @@ public virtual void HandleEnableAllToggled(bool toggledState, bool enabled, IEnu
SaveSelectedCollection();
RecognizeSortOrder(SelectedModCollection);
}
+
enableAllToggledState = toggledState;
}
@@ -920,6 +940,7 @@ public virtual void HandleModRefresh(bool isRefreshing, IEnumerable mods,
{
refreshInProgress = true;
}
+
if (!isRefreshing && mods?.Count() > 0)
{
SetMods(mods, activeGame);
@@ -943,8 +964,10 @@ async Task reorder()
{
reorderQueue.Add(mod);
}
+
await PerformModReorderAsync(true, reorderToken.Token);
}
+
reorder().ConfigureAwait(false);
}
@@ -997,6 +1020,7 @@ public virtual void Reset(bool fullReset = false)
{
previousValidatedMods.Clear();
}
+
PatchMod.SetParameters(SelectedModCollection);
HandleCollectionPatchStateAsync(SelectedModCollection?.Name).ConfigureAwait(false);
}
@@ -1035,9 +1059,6 @@ protected virtual void ApplySort()
SelectedMod = null;
SetSelectedModsState(SelectedMods.OrderByDescending(x => x.Name, StringComparer.OrdinalIgnoreCase).ToObservableCollection());
break;
-
- default:
- break;
}
}
@@ -1060,10 +1081,8 @@ protected virtual void AssignOptionalCollectionMetadata(IModCollection collectio
case ModSource.Paradox:
result.ParadoxId = p.RemoteId;
break;
-
- default:
- break;
}
+
return result;
}).ToList();
}
@@ -1075,7 +1094,7 @@ protected virtual void AssignOptionalCollectionMetadata(IModCollection collectio
protected virtual void EvalGameSpecificVisibility(IGame game = null)
{
game ??= gameService.GetSelected();
- ShowAdvancedFeatures = (game?.AdvancedFeatures) == GameAdvancedFeatures.Full;
+ ShowAdvancedFeatures = game?.AdvancedFeatures == GameAdvancedFeatures.Full;
SearchModsColSpan = ShowAdvancedFeatures ? 1 : 2;
}
@@ -1096,10 +1115,7 @@ protected virtual void EvaluateHighlight()
protected virtual async Task ExportCollectionAsync(string path, ImportProviderType providerType)
{
var id = idGenerator.GetNextId();
- var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new
- {
- PercentDone = 0.ToLocalizedPercentage()
- });
+ var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new { PercentDone = 0.ToLocalizedPercentage() });
await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Exporting_Message), overlayProgress);
var collection = modCollectionService.Get(SelectedModCollection.Name);
if (providerType == ImportProviderType.ParadoxLauncherJson)
@@ -1115,15 +1131,14 @@ protected virtual async Task ExportCollectionAsync(string path, ImportProviderTy
modExportProgress?.Dispose();
modExportProgress = modExportProgressHandler.Subscribe(s =>
{
- var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new
- {
- PercentDone = s.Progress.ToLocalizedPercentage()
- });
+ var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new { PercentDone = s.Progress.ToLocalizedPercentage() });
TriggerOverlay(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Exporting_Message), overlayProgress);
}).DisposeWith(Disposables);
- await Task.Run(async () => await modCollectionService.ExportAsync(path, collection, providerType == ImportProviderType.DefaultOrderOnly, providerType == ImportProviderType.DefaultWithAllMods).ConfigureAwait(false)).ConfigureAwait(false);
+ await Task.Run(async () => await modCollectionService.ExportAsync(path, collection, providerType == ImportProviderType.DefaultOrderOnly, providerType == ImportProviderType.DefaultWithAllMods).ConfigureAwait(false))
+ .ConfigureAwait(false);
modExportProgress?.Dispose();
}
+
var title = localizationManager.GetResource(LocalizationResources.Notifications.CollectionExported.Title);
var message = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Notifications.CollectionExported.Message), new { CollectionName = collection.Name });
notificationAction.ShowNotification(title, message, NotificationType.Success);
@@ -1141,7 +1156,7 @@ protected virtual async Task HandleCollectionPatchStateAsync(string collection)
if (activeGame != null && SelectedMods?.Count > 0)
{
ConflictSolverStateChanged?.Invoke(collection, true);
- if (!string.IsNullOrWhiteSpace(collection) && currentCollection.Equals(collection, StringComparison.OrdinalIgnoreCase) && SelectedModCollection.Game.Equals(activeGame.Type))
+ if (!string.IsNullOrWhiteSpace(collection) && currentCollection.Equals(collection, StringComparison.OrdinalIgnoreCase) && SelectedModCollection!.Game.Equals(activeGame.Type))
{
var result = await Task.Run(async () => await modPatchCollectionService.PatchModNeedsUpdateAsync(collection, SelectedMods.Select(p => p.DescriptorFile).ToList()));
ConflictSolverStateChanged?.Invoke(collection, !result);
@@ -1171,8 +1186,10 @@ protected virtual void HandleModCollectionChange(bool resetStack)
SelectedModCollection = restored;
}
}
+
restoreCollectionSelection = string.Empty;
}
+
skipModCollectionSave = true;
skipModSelectionSave = true;
ExportCollection.CollectionName = SelectedModCollection?.Name;
@@ -1184,6 +1201,7 @@ protected virtual void HandleModCollectionChange(bool resetStack)
item.IsSelected = false;
}
}
+
var existingCollection = modCollectionService.Get(SelectedModCollection?.Name ?? string.Empty);
var selectedMods = new ObservableCollection();
if (existingCollection?.Mods?.Count() > 0 && localMods != null)
@@ -1193,7 +1211,7 @@ protected virtual void HandleModCollectionChange(bool resetStack)
var mods = existingCollection.Mods.ToList();
var modPaths = existingCollection.ModPaths != null ? existingCollection.ModPaths.ToList() : [];
var modNames = hasModNames ? existingCollection.ModNames.ToList() : [];
- for (int i = 0; i < mods.Count; i++)
+ for (var i = 0; i < mods.Count; i++)
{
var item = mods[i];
var mod = localMods.FirstOrDefault(p => p.DescriptorFile.Equals(item, StringComparison.InvariantCultureIgnoreCase));
@@ -1202,6 +1220,7 @@ protected virtual void HandleModCollectionChange(bool resetStack)
item = modPaths[i];
mod = localMods.FirstOrDefault(p => p.FullPath.Equals(item, StringComparison.OrdinalIgnoreCase));
}
+
if (mod != null)
{
mod.IsSelected = true;
@@ -1219,6 +1238,7 @@ protected virtual void HandleModCollectionChange(bool resetStack)
}
}
}
+
if (missingMods.Count != 0 && activeGame != null && existingCollection.Game.Equals(activeGame.Type))
{
var title = localizationManager.GetResource(LocalizationResources.Collection_Mods.Prompts.ModsMissingTitle);
@@ -1226,11 +1246,13 @@ protected virtual void HandleModCollectionChange(bool resetStack)
Dispatcher.UIThread.SafeInvoke(() => notificationAction.ShowPromptAsync(title, title, message, NotificationType.Warning, PromptType.OK));
}
}
+
if (resetStack)
{
undoStack.Clear();
redoStack.Clear();
}
+
SetSelectedModsState(selectedMods, ignoreStack: true);
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
var state = appStateService.Get();
@@ -1250,15 +1272,13 @@ protected virtual void HandleModCollectionChange(bool resetStack)
protected virtual async Task ImportCollectionAsync(string path, ImportProviderType type)
{
List modNames = null;
+
async Task importDefault(long messageId)
{
modExportProgress?.Dispose();
modExportProgress = modExportProgressHandler.Subscribe(s =>
{
- var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new
- {
- PercentDone = s.Progress.ToLocalizedPercentage()
- });
+ var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new { PercentDone = s.Progress.ToLocalizedPercentage() });
TriggerOverlay(messageId, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Importing_Message), overlayProgress);
}).DisposeWith(Disposables);
var collection = await Task.Run(async () => await modCollectionService.ImportAsync(path));
@@ -1272,6 +1292,7 @@ async Task importDefault(long messageId)
return collection;
}
}
+
return null;
}
@@ -1286,14 +1307,12 @@ Task importInstance(IModCollection importData)
return Task.FromResult(importData);
}
}
+
return Task.FromResult((IModCollection)null);
}
var id = idGenerator.GetNextId();
- var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new
- {
- PercentDone = 0.ToLocalizedPercentage()
- });
+ var overlayProgress = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Import_Export_Progress), new { PercentDone = 0.ToLocalizedPercentage() });
await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.Overlay_Importing_Message), overlayProgress);
var importData = type switch
{
@@ -1302,13 +1321,14 @@ Task importInstance(IModCollection importData)
ImportProviderType.ParadoxLauncher => await modCollectionService.ImportParadoxLauncherAsync(),
ImportProviderType.ParadoxLauncherBeta => await modCollectionService.ImportParadoxLauncherBetaAsync(),
ImportProviderType.ParadoxLauncherJson => await modCollectionService.ImportParadoxLauncherJsonAsync(path),
- _ => await modCollectionService.GetImportedCollectionDetailsAsync(path),
+ _ => await modCollectionService.GetImportedCollectionDetailsAsync(path)
};
if (importData == null)
{
await TriggerOverlayAsync(id, false);
return;
}
+
bool proceed;
if (modCollectionService.Exists(importData.Name))
{
@@ -1320,13 +1340,14 @@ Task importInstance(IModCollection importData)
{
proceed = true;
}
+
var endOverlay = true;
if (proceed)
{
var result = type switch
{
ImportProviderType.Default => await importDefault(id),
- _ => await importInstance(importData),
+ _ => await importInstance(importData)
};
if (result != null)
{
@@ -1340,11 +1361,11 @@ Task importInstance(IModCollection importData)
var importedMods = new List();
var descriptors = result.Mods.ToList();
var paths = result.ModPaths != null ? result.ModPaths.ToList() : [];
- for (int i = 0; i < descriptors.Count; i++)
+ for (var i = 0; i < descriptors.Count; i++)
{
var descriptor = descriptors[i];
var name = modNames[i];
- var mod = mods.FirstOrDefault(p => p.Name.Equals(name) && System.IO.Path.GetDirectoryName(p.FullPath).EndsWith(System.IO.Path.DirectorySeparatorChar + result.MergedFolderName));
+ var mod = mods.FirstOrDefault(p => p.Name.Equals(name) && System.IO.Path.GetDirectoryName(p.FullPath)!.EndsWith(System.IO.Path.DirectorySeparatorChar + result.MergedFolderName));
if (mod != null)
{
importedMods.Add(mod.DescriptorFile);
@@ -1363,9 +1384,11 @@ Task importInstance(IModCollection importData)
}
}
}
+
result.Mods = importedMods;
modCollectionService.Save(result);
}
+
var modDescriptorPaths = result.Mods != null ? result.Mods.ToList() : [];
var modPaths = result.ModPaths != null ? result.ModPaths.ToList() : [];
restoreCollectionSelection = result.Name;
@@ -1392,6 +1415,7 @@ Task importInstance(IModCollection importData)
isInvalid = false;
}
}
+
if (isInvalid)
{
if (hasModNames)
@@ -1404,10 +1428,12 @@ Task importInstance(IModCollection importData)
}
}
}
+
if (nonExistingModNames.Count != 0)
{
var notExistingModTitle = localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Title);
- var nonExistingModMessage = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Message), new { Environment.NewLine, Mods = string.Join(Environment.NewLine, nonExistingModNames) });
+ var nonExistingModMessage = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Message),
+ new { Environment.NewLine, Mods = string.Join(Environment.NewLine, nonExistingModNames) });
endOverlay = false;
showImportNotification = false;
var title = localizationManager.GetResource(LocalizationResources.Notifications.CollectionImported.Title);
@@ -1418,6 +1444,7 @@ Task importInstance(IModCollection importData)
}
}
}
+
if (showImportNotification)
{
var title = localizationManager.GetResource(LocalizationResources.Notifications.CollectionImported.Title);
@@ -1426,6 +1453,7 @@ Task importInstance(IModCollection importData)
}
}
}
+
if (endOverlay)
{
await TriggerOverlayAsync(id, false);
@@ -1443,14 +1471,16 @@ protected virtual void InitSortersAndFilters(IAppState state, bool setFlag = tru
{
skipModSelectionSave = true;
}
+
CollectionJumpOnPositionChange = state.CollectionJumpOnPositionChange;
SearchMods.WatermarkText = SearchModsWatermark;
- SearchMods.Text = state?.CollectionModsSearchTerm;
+ SearchMods.Text = state.CollectionModsSearchTerm;
ModNameSortOrder.Text = ModName;
if (!string.IsNullOrWhiteSpace(state.CollectionModsSelectedMod) && SelectedMods != null)
{
SelectedMod = SelectedMods.FirstOrDefault(p => p.DescriptorFile.Equals(state.CollectionModsSelectedMod, StringComparison.OrdinalIgnoreCase));
}
+
RecognizeSortOrder(SelectedModCollection);
if (setFlag)
{
@@ -1522,14 +1552,12 @@ protected override void OnActivated(CompositeDisposable disposables)
HandleModCollectionChange(true);
}).DisposeWith(disposables);
- this.WhenAnyValue(v => v.AddNewCollection.IsActivated).Where(p => p == true).Subscribe(activated =>
+ // ReSharper disable once RedundantBoolCompare
+ this.WhenAnyValue(v => v.AddNewCollection.IsActivated).Where(p => p == true).Subscribe(_ =>
{
- Observable.Merge(AddNewCollection.CreateCommand, AddNewCollection.CancelCommand.Select(_ => new CommandResult(string.Empty, CommandState.NotExecuted))).Subscribe(result =>
+ AddNewCollection.CreateCommand.Merge(AddNewCollection.CancelCommand.Select(_ => new CommandResult(string.Empty, CommandState.NotExecuted))).Subscribe(result =>
{
- var notification = new
- {
- CollectionName = result.Result
- };
+ var notification = new { CollectionName = result.Result };
switch (result.State)
{
case CommandState.Success:
@@ -1543,6 +1571,7 @@ protected override void OnActivated(CompositeDisposable disposables)
mod.IsSelected = false;
}
}
+
SetSelectedModsState(Mods != null ? Mods.Where(p => p.IsSelected).ToObservableCollection() : []);
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
LoadModCollections();
@@ -1565,6 +1594,7 @@ await Task.Run(async () =>
notificationAction.ShowNotification(successTitle, successMessage, NotificationType.Success);
PatchMod.SetParameters(SelectedModCollection);
}
+
handleRenamePatchCollection().ConfigureAwait(true);
}
else
@@ -1574,6 +1604,7 @@ await Task.Run(async () =>
successMessage = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Notifications.CollectionCreated.Message), notification);
notificationAction.ShowNotification(successTitle, successMessage, NotificationType.Success);
}
+
break;
case CommandState.Exists:
@@ -1586,43 +1617,40 @@ await Task.Run(async () =>
MessageBus.Publish(new AllowEnterHotKeysEvent(false));
EnteringNewCollection = false;
break;
-
- default:
- break;
}
}).DisposeWith(disposables);
}).DisposeWith(disposables);
- this.WhenAnyValue(v => v.ExportCollection.IsActivated).Where(p => p).Subscribe(activated =>
+ this.WhenAnyValue(v => v.ExportCollection.IsActivated).Where(p => p).Subscribe(_ =>
{
Observable.Merge(ExportCollection.ExportCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.Default)),
- ExportCollection.ExportOrderOnlyCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.DefaultOrderOnly)),
- ExportCollection.ExportWholeCollectionCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.DefaultWithAllMods)),
- ExportCollection.ImportCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Default)),
- ExportCollection.ImportOtherParadoxosCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Paradoxos)),
- ExportCollection.ImportOtherParadoxCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Paradox)),
- ExportCollection.ImportOtherParadoxLauncherCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncher)),
- ExportCollection.ImportOtherParadoxLauncherBetaCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncherBeta)),
- ExportCollection.ImportOtherParadoxLauncherJsonCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncherJson)),
- ExportCollection.ExportParadoxLauncherJsonCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.ParadoxLauncherJson)),
- ExportCollection.ExportParadoxLauncherJson202110Command.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.ParadoxLauncherJson202110)))
- .Subscribe(s =>
- {
- if (s.Item2.State == CommandState.Success)
+ ExportCollection.ExportOrderOnlyCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.DefaultOrderOnly)),
+ ExportCollection.ExportWholeCollectionCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.DefaultWithAllMods)),
+ ExportCollection.ImportCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Default)),
+ ExportCollection.ImportOtherParadoxosCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Paradoxos)),
+ ExportCollection.ImportOtherParadoxCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.Paradox)),
+ ExportCollection.ImportOtherParadoxLauncherCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncher)),
+ ExportCollection.ImportOtherParadoxLauncherBetaCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncherBeta)),
+ ExportCollection.ImportOtherParadoxLauncherJsonCommand.Select(p => Tuple.Create(ImportActionType.Import, p, ImportProviderType.ParadoxLauncherJson)),
+ ExportCollection.ExportParadoxLauncherJsonCommand.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.ParadoxLauncherJson)),
+ ExportCollection.ExportParadoxLauncherJson202110Command.Select(p => Tuple.Create(ImportActionType.Export, p, ImportProviderType.ParadoxLauncherJson202110)))
+ .Subscribe(s =>
{
- if (s.Item1 == ImportActionType.Export)
+ if (s.Item2.State == CommandState.Success)
{
- ExportCollectionAsync(s.Item2.Result, s.Item3).ConfigureAwait(true);
- }
- else
- {
- ImportCollectionAsync(s.Item2.Result, s.Item3).ConfigureAwait(true);
+ if (s.Item1 == ImportActionType.Export)
+ {
+ ExportCollectionAsync(s.Item2.Result, s.Item3).ConfigureAwait(true);
+ }
+ else
+ {
+ ImportCollectionAsync(s.Item2.Result, s.Item3).ConfigureAwait(true);
+ }
}
- }
- }).DisposeWith(disposables);
+ }).DisposeWith(disposables);
}).DisposeWith(disposables);
- this.WhenAnyValue(v => v.ModifyCollection.IsActivated).Where(p => p).Subscribe(activated =>
+ this.WhenAnyValue(v => v.ModifyCollection.IsActivated).Where(p => p).Subscribe(_ =>
{
Observable.Merge(ModifyCollection.RenameCommand, ModifyCollection.DuplicateCommand, ModifyCollection.MergeBasicCommand, ModifyCollection.MergeCompressCommand).Subscribe(s =>
{
@@ -1630,6 +1658,7 @@ await Task.Run(async () =>
{
return;
}
+
if (s.Result == ModifyAction.Rename)
{
EnteringNewCollection = true;
@@ -1643,7 +1672,7 @@ await Task.Run(async () =>
{
ModCollections = modCollectionService.GetAll();
var selected = ModCollections?.FirstOrDefault(p => p.IsSelected);
- restoreCollectionSelection = selected.Name;
+ restoreCollectionSelection = selected!.Name;
NeedsModListRefresh = true;
var existsTitle = localizationManager.GetResource(LocalizationResources.Notifications.CollectionMerged.Title);
var existsMessage = localizationManager.GetResource(LocalizationResources.Notifications.CollectionMerged.Message);
@@ -1663,6 +1692,7 @@ await Task.Run(async () =>
mod.IsSelected = false;
}
}
+
SetSelectedModsState(Mods != null ? Mods.Where(p => p.IsSelected).ToObservableCollection() : []);
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
LoadModCollections();
@@ -1677,7 +1707,7 @@ await Task.Run(async () =>
}).DisposeWith(disposables);
}).DisposeWith(disposables);
- this.WhenAnyValue(s => s.SearchMods.IsActivated).Where(p => p).Subscribe(s =>
+ this.WhenAnyValue(s => s.SearchMods.IsActivated).Where(p => p).Subscribe(_ =>
{
this.WhenAnyValue(s => s.SearchMods.Text).Subscribe(async s =>
{
@@ -1688,8 +1718,10 @@ await Task.Run(async () =>
{
await MessageBus.PublishAsync(new EvalModAchievementsCompatibilityEvent(Mods, true, true));
}
+
SelectedMod = modService.FindMod(SelectedMods, s, false, null);
}
+
var modCount = SelectedModCollection?.Mods.Count();
var selectedModsCount = SelectedMods?.Count;
@@ -1700,23 +1732,27 @@ await Task.Run(async () =>
{
SelectedMod = null;
}
+
SaveState();
}
+
skipModSelectionSave = false;
}).DisposeWith(disposables);
- Observable.Merge(SearchMods.DownArrowCommand, SearchMods.UpArrowCommand).Subscribe(async s =>
+ SearchMods.DownArrowCommand.Merge(SearchMods.UpArrowCommand).Subscribe(async s =>
{
if (SelectedMods == null)
{
return;
}
+
skipModSelectionSave = true;
var index = -1;
if (SelectedMod != null)
{
index = SelectedMods.IndexOf(SelectedMod);
}
+
var searchString = SearchMods.Text ?? string.Empty;
if (!s.Result)
{
@@ -1724,6 +1760,7 @@ await Task.Run(async () =>
{
await MessageBus.PublishAsync(new EvalModAchievementsCompatibilityEvent(Mods, true, true));
}
+
var mod = modService.FindMod(SelectedMods, searchString, false, index + 1);
if (mod != null && mod != SelectedMod)
{
@@ -1737,20 +1774,23 @@ await Task.Run(async () =>
{
await MessageBus.PublishAsync(new EvalModAchievementsCompatibilityEvent(Mods, true, true));
}
+
var mod = modService.FindMod(SelectedMods, searchString, true, reverseIndex);
if (mod != null && mod != SelectedMod)
{
SelectedMod = mod;
}
}
+
skipModSelectionSave = false;
SaveState();
}).DisposeWith(disposables);
}).DisposeWith(disposables);
- this.WhenAnyValue(s => s.ModNameSortOrder.IsActivated).Where(p => p == true).Subscribe(s =>
+ // ReSharper disable once RedundantBoolCompare
+ this.WhenAnyValue(s => s.ModNameSortOrder.IsActivated).Where(p => p == true).Subscribe(_ =>
{
- ModNameSortOrder.SortCommand.Subscribe(s =>
+ ModNameSortOrder.SortCommand.Subscribe(_ =>
{
ApplySort();
SaveState();
@@ -1767,9 +1807,11 @@ await Task.Run(async () =>
{
item.IsSelected = false;
}
+
SetSelectedModsState([]);
SaveSelectedCollection();
}
+
skipModCollectionSave = false;
}).DisposeWith(disposables);
@@ -1808,13 +1850,21 @@ await Task.Run(async () =>
}
}).DisposeWith(disposables);
+ CopyModPathCommand = ReactiveCommand.Create(() =>
+ {
+ if (!string.IsNullOrWhiteSpace(ContextMenuMod?.FullPath))
+ {
+ appAction.CopyAsync(ContextMenuMod.FullPath).ConfigureAwait(true);
+ }
+ }).DisposeWith(disposables);
+
this.WhenAnyValue(p => p.AllowModSelection).Subscribe(s =>
{
ExportCollection.AllowModSelection = s;
ModifyCollection.AllowModSelection = s;
}).DisposeWith(disposables);
- this.WhenAnyValue(p => p.CollectionJumpOnPositionChange).Subscribe(s =>
+ this.WhenAnyValue(p => p.CollectionJumpOnPositionChange).Subscribe(_ =>
{
SetAutoFocusLabel();
}).DisposeWith(disposables);
@@ -1859,6 +1909,7 @@ await Task.Run(async () =>
mods.Add(item);
}
}
+
SetSelectedModsState(mods.OrderBy(p => modNames.IndexOf(p.Name)).ToObservableCollection());
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
var state = appStateService.Get();
@@ -1871,7 +1922,8 @@ await Task.Run(async () =>
if (nonExistingMods.Any())
{
var notExistingModTitle = localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Title);
- var nonExistingModMessage = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Message), new { Environment.NewLine, Mods = string.Join(Environment.NewLine, nonExistingMods) });
+ var nonExistingModMessage = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.ImportNonExistingMods.Message),
+ new { Environment.NewLine, Mods = string.Join(Environment.NewLine, nonExistingMods) });
await notificationAction.ShowPromptAsync(notExistingModTitle, notExistingModTitle, nonExistingModMessage, NotificationType.Warning, PromptType.OK);
}
}
@@ -1888,12 +1940,12 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
if (useImportOverlay)
{
TriggerOverlay(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ImportOverlay),
- IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ProgressImport), new { Progress = s.Percentage.ToLocalizedPercentage(), Count = s.Step, TotalCount = 2 }));
+ IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ProgressImport), new { Progress = s.Percentage.ToLocalizedPercentage(), Count = s.Step, TotalCount = 2 }));
}
else
{
TriggerOverlay(id, true, localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ExportOverlay),
- IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ProgressExport), new { Progress = s.Percentage.ToLocalizedPercentage() }));
+ IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Collection_Mods.FileHash.ProgressExport), new { Progress = s.Percentage.ToLocalizedPercentage() }));
}
}).DisposeWith(disposables);
}
@@ -1914,11 +1966,13 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
{
reports.AddRange(collectionReports);
}
+
var gameReports = await Task.Run(() => gameService.ImportHashReportAsync(activeGame, rawReports.ToList()));
if (gameReports != null && gameReports.Any())
{
reports.AddRange(gameReports);
}
+
if (reports.Count != 0)
{
await TriggerOverlayAsync(id, false);
@@ -1930,6 +1984,7 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
notificationAction.ShowNotification(localizationManager.GetResource(LocalizationResources.Notifications.ReportValid.Title),
localizationManager.GetResource(LocalizationResources.Notifications.ReportValid.Message), NotificationType.Success);
}
+
reportDisposable?.Dispose();
}
}).DisposeWith(disposables);
@@ -1948,6 +2003,7 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
notificationAction.ShowNotification(localizationManager.GetResource(LocalizationResources.Notifications.ReportExported.Title),
localizationManager.GetResource(LocalizationResources.Notifications.ReportExported.Message), NotificationType.Success);
}
+
await TriggerOverlayAsync(id, false);
reportDisposable?.Dispose();
}
@@ -1967,22 +2023,17 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
notificationAction.ShowNotification(localizationManager.GetResource(LocalizationResources.Notifications.ReportExported.Title),
localizationManager.GetResource(LocalizationResources.Notifications.ReportExported.Message), NotificationType.Success);
}
+
await TriggerOverlayAsync(id, false);
reportDisposable?.Dispose();
}
}).DisposeWith(disposables);
- UndoCommand = ReactiveCommand.Create(() =>
- {
- PerformUndo();
- }).DisposeWith(disposables);
+ UndoCommand = ReactiveCommand.Create(PerformUndo).DisposeWith(disposables);
- RedoCommand = ReactiveCommand.Create(() =>
- {
- PerformRedo();
- }).DisposeWith(disposables);
+ RedoCommand = ReactiveCommand.Create(PerformRedo).DisposeWith(disposables);
- this.WhenAnyValue(p => p.SelectedMod).Where(p => !skipModSelectionSave).Subscribe(s =>
+ this.WhenAnyValue(p => p.SelectedMod).Where(_ => !skipModSelectionSave).Subscribe(_ =>
{
var modCount = SelectedModCollection?.Mods.Count();
var selectedModsCount = SelectedMods?.Count;
@@ -2024,16 +2075,14 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
break;
case Enums.HotKeys.Ctrl_Z:
- Dispatcher.UIThread.SafeInvoke(() => PerformUndo());
+ await Dispatcher.UIThread.SafeInvokeAsync(PerformUndo);
break;
case Enums.HotKeys.Ctrl_Y:
- Dispatcher.UIThread.SafeInvoke(() => PerformRedo());
- break;
-
- default:
+ await Dispatcher.UIThread.SafeInvokeAsync(PerformRedo);
break;
}
+
if (!(order < 1 || order > MaxOrder) && order != mod.Order)
{
// Check access because it's probably coming from a background thread
@@ -2042,9 +2091,11 @@ void registerReportHandlers(long id, bool useImportOverlay = false)
}
}).DisposeWith(disposables);
- this.WhenAnyValue(p => p.PatchMod.IsActivated).Where(p => p == true).Subscribe(state =>
+ // ReSharper disable once RedundantBoolCompare
+ this.WhenAnyValue(p => p.PatchMod.IsActivated).Where(p => p == true).Subscribe(_ =>
{
- this.WhenAnyValue(p => p.PatchMod.PatchDeleted).Where(p => p == true).Subscribe(state =>
+ // ReSharper disable once RedundantBoolCompare
+ this.WhenAnyValue(p => p.PatchMod.PatchDeleted).Where(p => p == true).Subscribe(_ =>
{
modPatchCollectionService.InvalidatePatchModState(PatchMod.CollectionName);
modPatchCollectionService.ResetPatchStateCache();
@@ -2077,6 +2128,7 @@ protected virtual async Task PerformModReorderAsync(bool instant, CancellationTo
{
await Task.Delay(450, cancellationToken);
}
+
if (!cancellationToken.IsCancellationRequested)
{
if (SelectedMods != null)
@@ -2097,24 +2149,27 @@ protected virtual async Task PerformModReorderAsync(bool instant, CancellationTo
mods.Remove(modItem);
mods.Insert(index, modItem);
index = mods.IndexOf(swapItem);
- for (int i = 0; i <= index; i++)
+ for (var i = 0; i <= index; i++)
{
- if (!reorderQueue.Any(m => m == mods[i].Mod))
+ if (reorderQueue.All(m => m != mods[i].Mod))
{
mods[i].Order = i + 1;
}
}
}
}
+
SetSelectedModsState(mods.Select(p => p.Mod).ToList());
if (CollectionJumpOnPositionChange)
{
SelectedMod = reorderQueue.Last();
}
+
if (!string.IsNullOrWhiteSpace(SelectedModCollection?.Name))
{
SaveSelectedCollection();
}
+
SaveState();
RecognizeSortOrder(SelectedModCollection);
ModReordered?.Invoke(reorderQueue.Last(), instant);
@@ -2122,7 +2177,6 @@ protected virtual async Task PerformModReorderAsync(bool instant, CancellationTo
reorderQueue.Clear();
scrollState.SetState(true);
}
- mutex.Dispose();
}
}
}
@@ -2136,6 +2190,7 @@ protected virtual void PerformRedo()
{
return;
}
+
undoStack.Push(SelectedMods.Select(p => p.DescriptorFile).ToList());
PerformRedoUndoOrdering(redoStack.Pop());
}
@@ -2157,6 +2212,7 @@ protected virtual void PerformRedoUndoOrdering(IEnumerable descriptors)
{
item.IsSelected = false;
}
+
var mods = new List();
foreach (var item in descriptors)
{
@@ -2167,11 +2223,13 @@ protected virtual void PerformRedoUndoOrdering(IEnumerable descriptors)
mods.Add(mod);
}
}
+
SetSelectedModsState(mods, ignoreStack: true);
if (!string.IsNullOrWhiteSpace(SelectedModCollection?.Name))
{
SaveSelectedCollection();
}
+
SaveState();
RecognizeSortOrder(SelectedModCollection);
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
@@ -2190,6 +2248,7 @@ protected virtual void PerformUndo()
{
return;
}
+
redoStack.Push(SelectedMods.Select(p => p.DescriptorFile).ToList());
PerformRedoUndoOrdering(undoStack.Pop());
}
@@ -2206,7 +2265,7 @@ protected virtual void RecognizeSortOrder(IModCollection modCollection)
var mods = new List();
var colMods = modCollection.Mods.ToList();
var colPaths = modCollection.ModPaths != null ? modCollection.ModPaths.ToList() : [];
- for (int i = 0; i < colMods.Count; i++)
+ for (var i = 0; i < colMods.Count; i++)
{
var item = colMods[i];
var mod = Mods.FirstOrDefault(p => p.DescriptorFile.Equals(item, StringComparison.OrdinalIgnoreCase));
@@ -2215,11 +2274,13 @@ protected virtual void RecognizeSortOrder(IModCollection modCollection)
item = colPaths[i];
mod = Mods.FirstOrDefault(p => p.FullPath.Equals(item, StringComparison.OrdinalIgnoreCase));
}
+
if (mod != null)
{
mods.Add(mod);
}
}
+
if (mods.Count != 0)
{
var ascending = mods.OrderBy(p => p.Name, StringComparer.OrdinalIgnoreCase).Select(p => p.DescriptorFile);
@@ -2263,6 +2324,7 @@ protected async Task RemoveCollectionAsync(string collectionName)
localizationManager.GetResource(LocalizationResources.Collection_Mods.DeleteMerge.DeleteHeader),
localizationManager.GetResource(LocalizationResources.Collection_Mods.DeleteMerge.DeleteMessage), NotificationType.Info);
}
+
if (modCollectionService.Delete(collectionName))
{
modPatchCollectionService.InvalidatePatchModState(collectionName);
@@ -2271,7 +2333,7 @@ await Task.Run(async () =>
await modPatchCollectionService.CleanPatchCollectionAsync(collectionName).ConfigureAwait(false);
if (deleteMergedMod)
{
- await modService.PurgeModDirectoryAsync(collection.MergedFolderName).ConfigureAwait(false);
+ await modService.PurgeModDirectoryAsync(collection!.MergedFolderName).ConfigureAwait(false);
}
}).ConfigureAwait(false);
LoadModCollections();
@@ -2290,6 +2352,7 @@ await Task.Run(async () =>
notificationAction.ShowNotification(notificationTitle, notificationMessage, NotificationType.Success);
}
}
+
await TriggerOverlayAsync(id, false);
}
}
@@ -2309,6 +2372,7 @@ protected virtual void SaveSelectedCollection()
{
return;
}
+
collection.Game = game;
collection.Name = SelectedModCollection.Name;
var selectedMods = SelectedMods != null ? SelectedMods.Where(p => p.IsSelected) : [];
@@ -2353,6 +2417,7 @@ protected virtual async Task ScheduleToReorderQueueAsync(IMod mod)
{
reorderQueue.Add(mod);
}
+
reorderToken?.Cancel();
reorderToken = new CancellationTokenSource();
await PerformModReorderAsync(false, reorderToken.Token);
@@ -2381,7 +2446,8 @@ protected virtual void SetSelectedModsState(IList selectedMods, bool canSh
{
skipReorder = true;
}
- int counter = 0;
+
+ var counter = 0;
if (selectedMods != null)
{
foreach (var item in selectedMods)
@@ -2390,6 +2456,7 @@ protected virtual void SetSelectedModsState(IList selectedMods, bool canSh
item.Order = counter;
}
}
+
SelectedMods = selectedMods;
if (SelectedModCollection != null)
{
@@ -2398,20 +2465,23 @@ protected virtual void SetSelectedModsState(IList selectedMods, bool canSh
{
oldMods.AddRange(SelectedMods);
}
+
previousValidatedMods.TryGetValue(SelectedModCollection.Name, out var prevMods);
if (SelectedMods?.Count > 0 && (prevMods == null ||
- !(prevMods.Count() == SelectedMods.Count && !prevMods.Select(p => p.DescriptorFile).Except(SelectedMods.Select(p => p.DescriptorFile)).Any())
- || !prevMods.Select(p => p.DescriptorFile).SequenceEqual(SelectedMods.Select(p => p.DescriptorFile))))
+ !(prevMods.Count() == SelectedMods.Count && !prevMods.Select(p => p.DescriptorFile).Except(SelectedMods.Select(p => p.DescriptorFile)).Any())
+ || !prevMods.Select(p => p.DescriptorFile).SequenceEqual(SelectedMods.Select(p => p.DescriptorFile))))
{
modPatchCollectionService.InvalidatePatchModState(SelectedModCollection.Name);
}
- previousValidatedMods.AddOrUpdate(SelectedModCollection.Name, oldMods, (k, v) => oldMods);
+
+ previousValidatedMods.AddOrUpdate(SelectedModCollection.Name, oldMods, (_, _) => oldMods);
if (!ignoreStack && !prevMods.ListsSame(selectedMods))
{
undoStack.Push((prevMods ?? []).Select(p => p.DescriptorFile).ToList());
redoStack.Clear();
}
}
+
ModifyCollection.SelectedMods = selectedMods;
HandleCollectionPatchStateAsync(SelectedModCollection?.Name).ConfigureAwait(false);
var order = 1;
@@ -2419,6 +2489,7 @@ protected virtual void SetSelectedModsState(IList selectedMods, bool canSh
{
order = SelectedMods.Count;
}
+
MaxOrder = order;
if (canShutdownReorder)
{
@@ -2457,6 +2528,7 @@ protected virtual void SubscribeToMods()
{
SaveState();
}
+
needsSave = true;
}
}
@@ -2468,10 +2540,12 @@ protected virtual void SubscribeToMods()
needsSave = true;
}
}
+
if (!string.IsNullOrWhiteSpace(SelectedModCollection?.Name) && needsSave)
{
SaveSelectedCollection();
}
+
Dispatcher.UIThread.SafeInvoke(() =>
{
SetSelectedModsState(selectedMods, false);
@@ -2479,9 +2553,11 @@ protected virtual void SubscribeToMods()
{
InstantReorderSelectedItems(s.Sender, s.Sender.Order);
}
+
RecognizeSortOrder(SelectedModCollection);
});
}
+
AllModsEnabled = SelectedMods?.Count > 0 && SelectedMods.All(p => p.IsSelected);
skipReorder = false;
}).DisposeWith(Disposables);
@@ -2508,7 +2584,7 @@ private async Task ExportModsAsync(bool fullMetadata = false)
var sb = new StringBuilder();
foreach (var item in SelectedMods)
{
- var entries = new List() { item.Name };
+ var entries = new List { item.Name };
if (fullMetadata)
{
var version = item.Version;
@@ -2516,14 +2592,17 @@ private async Task ExportModsAsync(bool fullMetadata = false)
{
entries.Add(version);
}
+
var url = modService.BuildModUrl(item);
if (!string.IsNullOrWhiteSpace(url))
{
entries.Add(url);
}
}
+
sb.AppendLine(string.Join(ClipboardSeparator, entries));
}
+
await appAction.CopyAsync(sb.ToString());
}
}
diff --git a/src/IronyModManager/ViewModels/Controls/InstalledModsControlViewModel.cs b/src/IronyModManager/ViewModels/Controls/InstalledModsControlViewModel.cs
index f14e4963..9c59b2d3 100644
--- a/src/IronyModManager/ViewModels/Controls/InstalledModsControlViewModel.cs
+++ b/src/IronyModManager/ViewModels/Controls/InstalledModsControlViewModel.cs
@@ -4,7 +4,7 @@
// Created : 02-29-2020
//
// Last Modified By : Mario
-// Last Modified On : 01-11-2023
+// Last Modified On : 06-06-2024
// ***********************************************************************
//
// Mario
@@ -117,7 +117,7 @@ public class InstalledModsControlViewModel : BaseViewModel
///
/// The checking state
///
- private bool checkingState = false;
+ private bool checkingState;
///
/// The eval mod token
@@ -132,12 +132,12 @@ public class InstalledModsControlViewModel : BaseViewModel
///
/// The showing invalid notification
///
- private bool showingInvalidNotification = false;
+ private bool showingInvalidNotification;
///
/// The showing prompt
///
- private bool showingPrompt = false;
+ private bool showingPrompt;
///
/// The sort orders
@@ -237,6 +237,19 @@ public InstalledModsControlViewModel(EvalModAchievementCompatibilityHandler eval
/// The context menu mod.
public virtual IMod ContextMenuMod { get; set; }
+ ///
+ /// Gets or sets a value representing the copy mod path.
+ ///
+ /// The copy mod path.
+ [StaticLocalization(LocalizationResources.Mod_App_Actions.CopyPath)]
+ public virtual string CopyModPath { get; protected set; }
+
+ ///
+ /// Gets or sets a value representing the copy mod path command.
+ ///
+ /// The copy mod path command.
+ public virtual ReactiveCommand CopyModPathCommand { get; protected set; }
+
///
/// Gets or sets the copy URL.
///
@@ -511,6 +524,7 @@ public virtual string GetContextMenuModModSteamUrl()
var url = modService.BuildSteamUrl(ContextMenuMod);
return url;
}
+
return string.Empty;
}
@@ -525,6 +539,7 @@ public virtual string GetContextMenuModModUrl()
var url = modService.BuildModUrl(ContextMenuMod);
return url;
}
+
return string.Empty;
}
@@ -564,6 +579,7 @@ public virtual async Task RefreshModsAsync(bool skipOverlay = false)
}
}
}
+
RefreshingMods = false;
}
@@ -596,9 +612,6 @@ protected virtual void ApplySort(string sortBy)
case ModVersionKey:
SortFunction(x => x.VersionData, sortModel.Key);
break;
-
- default:
- break;
}
}
@@ -627,6 +640,7 @@ protected virtual async Task BindAsync(IGame game = null, bool skipOverlay = fal
{
await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Installed_Mods.LoadingMods));
}
+
game ??= gameService.GetSelected();
ActiveGame = game;
if (game != null)
@@ -635,6 +649,7 @@ protected virtual async Task BindAsync(IGame game = null, bool skipOverlay = fal
{
GameChangedRefresh = true;
}
+
var mods = await Task.Run(async () => await modService.GetInstalledModsAsync(game));
await Task.Delay(100);
Mods = mods.ToObservableCollection();
@@ -647,11 +662,13 @@ await Dispatcher.UIThread.SafeInvokeAsync(async () =>
await RemoveInvalidModsPromptAsync(invalidMods).ConfigureAwait(false);
});
}
+
var searchString = FilterMods.Text ?? string.Empty;
if (Mods != null && Mods.Any(p => p.AchievementStatus == AchievementStatus.NotEvaluated) && modService.QueryContainsAchievements(searchString))
{
await MessageBus.PublishAsync(new EvalModAchievementsCompatibilityEvent(Mods, skipOverlay, true));
}
+
FilteredMods = modService.FilterMods(Mods, searchString).ToObservableCollection();
AllModsEnabled = FilteredMods.Where(p => p.IsValid).Any() && FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected);
@@ -659,7 +676,7 @@ await Dispatcher.UIThread.SafeInvokeAsync(async () =>
{
modChanged?.Dispose();
modChanged = null;
- modChanged = Mods.ToSourceList().Connect().WhenPropertyChanged(s => s.IsSelected).Subscribe(s =>
+ modChanged = Mods.ToSourceList().Connect().WhenPropertyChanged(s => s.IsSelected).Subscribe(_ =>
{
if (!checkingState)
{
@@ -675,13 +692,10 @@ await Dispatcher.UIThread.SafeInvokeAsync(async () =>
}
else
{
- if (raiseGameChanged)
- {
- GameChangedRefresh = true;
- }
Mods = FilteredMods = new System.Collections.ObjectModel.ObservableCollection();
AllMods = Mods.ToHashSet();
}
+
if (!skipOverlay)
{
await TriggerOverlayAsync(id, false);
@@ -707,12 +721,13 @@ protected virtual async Task CheckModEnabledStateAsync()
protected virtual async Task CheckNewModsAsync()
{
var id = idGenerator.GetNextId();
- await TriggerOverlayAsync(id, true, message: localizationManager.GetResource(LocalizationResources.Installed_Mods.RefreshingModList));
+ await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Installed_Mods.RefreshingModList));
var result = await modService.InstallModsAsync(Mods);
if (result != null && result.Any(p => p.Invalid))
{
await ShowInvalidModsNotificationAsync(result.Where(p => p.Invalid).ToList());
}
+
await RefreshModsAsync();
var title = localizationManager.GetResource(LocalizationResources.Notifications.NewDescriptorsChecked.Title);
var message = localizationManager.GetResource(LocalizationResources.Notifications.NewDescriptorsChecked.Message);
@@ -730,13 +745,14 @@ protected virtual async Task DeleteDescriptorAsync(IEnumerable mods)
if (mods?.Count() > 0)
{
var id = idGenerator.GetNextId();
- await TriggerOverlayAsync(id, true, message: localizationManager.GetResource(LocalizationResources.Installed_Mods.RefreshingModList));
+ await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Installed_Mods.RefreshingModList));
await modService.DeleteDescriptorsAsync(mods);
var result = await modService.InstallModsAsync(Mods);
if (result != null && result.Any(p => p.Invalid))
{
await ShowInvalidModsNotificationAsync(result.Where(p => p.Invalid).ToList());
}
+
await RefreshModsAsync();
var title = localizationManager.GetResource(LocalizationResources.Notifications.DescriptorsRefreshed.Title);
var message = localizationManager.GetResource(LocalizationResources.Notifications.DescriptorsRefreshed.Message);
@@ -759,6 +775,7 @@ async Task performEval(CancellationToken token)
{
await Task.Delay(100, token);
}
+
if (!token.IsCancellationRequested || hasPriority)
{
if (evalModsQueue.Any())
@@ -770,6 +787,7 @@ async Task performEval(CancellationToken token)
}
}
}
+
evalModToken?.Cancel();
evalModToken = new CancellationTokenSource();
if (mods.Any())
@@ -779,6 +797,7 @@ async Task performEval(CancellationToken token)
{
mutex = await evalLock.LockAsync();
}
+
mods.ToList().ForEach(m => evalModsQueue.Add(m));
try
{
@@ -787,6 +806,7 @@ async Task performEval(CancellationToken token)
catch (OperationCanceledException)
{
}
+
mutex?.Dispose();
}
}
@@ -817,6 +837,7 @@ protected virtual void InitDefaultSortOrder(string dictKey, SortOrderControlView
{
vm.SortOrder = defaultOrder;
}
+
vm.Text = text;
sortOrders[dictKey] = vm;
}
@@ -865,15 +886,15 @@ protected override void OnActivated(CompositeDisposable disposables)
Bind();
this.WhenAnyValue(v => v.ModNameSortOrder.IsActivated, v => v.ModVersionSortOrder.IsActivated, v => v.ModSelectedSortOrder.IsActivated).Where(s => s.Item1 && s.Item2 && s.Item3)
- .Subscribe(s =>
- {
- Observable.Merge(ModNameSortOrder.SortCommand.Select(_ => ModNameKey),
- ModVersionSortOrder.SortCommand.Select(_ => ModVersionKey),
- ModSelectedSortOrder.SortCommand.Select(_ => ModSelectedKey)).Subscribe(s =>
- {
- ApplySort(s);
- }).DisposeWith(disposables);
- }).DisposeWith(disposables);
+ .Subscribe(_ =>
+ {
+ Observable.Merge(ModNameSortOrder.SortCommand.Select(_ => ModNameKey),
+ ModVersionSortOrder.SortCommand.Select(_ => ModVersionKey),
+ ModSelectedSortOrder.SortCommand.Select(_ => ModSelectedKey)).Subscribe(s =>
+ {
+ ApplySort(s);
+ }).DisposeWith(disposables);
+ }).DisposeWith(disposables);
OpenUrlCommand = ReactiveCommand.CreateFromTask(async () =>
{
@@ -910,13 +931,22 @@ protected override void OnActivated(CompositeDisposable disposables)
}
}).DisposeWith(disposables);
- this.WhenAnyValue(s => s.FilterMods.Text).Subscribe(async s =>
+ CopyModPathCommand = ReactiveCommand.Create(() =>
+ {
+ if (!string.IsNullOrWhiteSpace(ContextMenuMod?.FullPath))
+ {
+ appAction.CopyAsync(ContextMenuMod.FullPath).ConfigureAwait(true);
+ }
+ }).DisposeWith(disposables);
+
+ this.WhenAnyValue(s => s.FilterMods.Text).Subscribe(async _ =>
{
var searchString = FilterMods.Text ?? string.Empty;
if (Mods != null && Mods.Any(p => p.AchievementStatus == AchievementStatus.NotEvaluated) && modService.QueryContainsAchievements(searchString))
{
await MessageBus.PublishAsync(new EvalModAchievementsCompatibilityEvent(Mods, true, true));
}
+
FilteredMods = modService.FilterMods(Mods, searchString);
AllModsEnabled = FilteredMods != null && FilteredMods.Where(p => p.IsValid).Any() && FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected);
ApplyDefaultSort();
@@ -928,11 +958,12 @@ protected override void OnActivated(CompositeDisposable disposables)
if (FilteredMods?.Count() > 0)
{
PerformingEnableAll = true;
- bool enabled = FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected);
+ var enabled = FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected);
foreach (var item in FilteredMods)
{
item.IsSelected = !enabled;
}
+
AllModsEnabled = FilteredMods.Where(p => p.IsValid).Any() && FilteredMods.Where(p => p.IsValid).All(p => p.IsSelected);
PerformingEnableAll = false;
}
@@ -942,7 +973,7 @@ protected override void OnActivated(CompositeDisposable disposables)
{
if (ContextMenuMod != null)
{
- await DeleteDescriptorAsync(new List() { ContextMenuMod }).ConfigureAwait(true);
+ await DeleteDescriptorAsync(new List { ContextMenuMod }).ConfigureAwait(true);
}
}).DisposeWith(disposables);
@@ -958,7 +989,7 @@ protected override void OnActivated(CompositeDisposable disposables)
{
if (ContextMenuMod != null)
{
- await LockDescriptorAsync(new List() { ContextMenuMod }, true).ConfigureAwait(true);
+ await LockDescriptorAsync(new List { ContextMenuMod }, true).ConfigureAwait(true);
}
}).DisposeWith(disposables);
@@ -974,7 +1005,7 @@ protected override void OnActivated(CompositeDisposable disposables)
{
if (ContextMenuMod != null)
{
- await LockDescriptorAsync(new List() { ContextMenuMod }, false).ConfigureAwait(true);
+ await LockDescriptorAsync(new List { ContextMenuMod }, false).ConfigureAwait(true);
}
}).DisposeWith(disposables);
@@ -998,6 +1029,7 @@ protected override void OnActivated(CompositeDisposable disposables)
{
await TriggerOverlayAsync(id, true, localizationManager.GetResource(LocalizationResources.Installed_Mods.LoadingMods));
}
+
await EvalModAchievementAsync(s.Mods, s.HasPriority).ConfigureAwait(false);
if (s.ShowOverlay)
{
@@ -1030,22 +1062,21 @@ protected virtual async Task RemoveInvalidModsPromptAsync(IEnumerable mods
{
return;
}
+
showingPrompt = true;
var messages = new List();
foreach (var item in mods)
{
messages.Add($"{item.Name} ({item.DescriptorFile})");
}
+
var title = localizationManager.GetResource(LocalizationResources.Installed_Mods.InvalidMods.Title);
- var message = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Installed_Mods.InvalidMods.Message), new
- {
- Mods = string.Join(Environment.NewLine, messages),
- Environment.NewLine
- });
+ var message = IronyFormatter.Format(localizationManager.GetResource(LocalizationResources.Installed_Mods.InvalidMods.Message), new { Mods = string.Join(Environment.NewLine, messages), Environment.NewLine });
if (await notificationAction.ShowPromptAsync(title, title, message, NotificationType.Warning))
{
await DeleteDescriptorAsync(mods);
}
+
showingPrompt = false;
}
@@ -1061,6 +1092,7 @@ protected virtual IComparer ResolveComparer(string dictKey)
{
return (IComparer)StringComparer.OrdinalIgnoreCase;
}
+
return null;
}
@@ -1106,7 +1138,7 @@ protected virtual void SortFunction(Func sortProp, string dictKey)
if (FilteredMods != null)
{
var sortOrder = sortOrders[dictKey];
- IComparer comparer = ResolveComparer(dictKey);
+ var comparer = ResolveComparer(dictKey);
switch (sortOrder.SortOrder)
{
case Implementation.SortOrder.Asc:
@@ -1120,6 +1152,7 @@ protected virtual void SortFunction(Func sortProp, string dictKey)
FilteredMods = FilteredMods.OrderBy(sortProp).ToObservableCollection();
AllMods = AllMods.OrderBy(sortProp).ToHashSet();
}
+
SelectedMod = null;
break;
@@ -1134,16 +1167,16 @@ protected virtual void SortFunction(Func sortProp, string dictKey)
FilteredMods = FilteredMods.OrderByDescending(sortProp).ToObservableCollection();
AllMods = AllMods.OrderByDescending(sortProp).ToHashSet();
}
- SelectedMod = null;
- break;
- default:
+ SelectedMod = null;
break;
}
+
foreach (var sort in sortOrders.Where(p => p.Value != sortOrder))
{
sort.Value.SetSortOrder(Implementation.SortOrder.None);
}
+
SaveState();
}
}
diff --git a/src/IronyModManager/Views/Controls/CollectionModsControlView.xaml.cs b/src/IronyModManager/Views/Controls/CollectionModsControlView.xaml.cs
index d4c1727c..b7e0d154 100644
--- a/src/IronyModManager/Views/Controls/CollectionModsControlView.xaml.cs
+++ b/src/IronyModManager/Views/Controls/CollectionModsControlView.xaml.cs
@@ -1,22 +1,21 @@
-
-// ***********************************************************************
+// ***********************************************************************
// Assembly : IronyModManager
// Author : Mario
// Created : 03-03-2020
//
// Last Modified By : Mario
-// Last Modified On : 12-05-2023
+// Last Modified On : 06-06-2024
// ***********************************************************************
//
// Mario
//
//
// ***********************************************************************
+
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reactive.Disposables;
-using System.Reactive.Linq;
using System.Threading.Tasks;
using Avalonia.Controls;
using Avalonia.LogicalTree;
@@ -34,7 +33,6 @@
namespace IronyModManager.Views.Controls
{
-
///
/// Class CollectionModsControlView.
/// Implements the
@@ -118,7 +116,7 @@ protected virtual void HandleItemDragged()
{
var sourceMod = source as IMod;
var destinationMod = destination as IMod;
- ViewModel.InstantReorderSelectedItems(sourceMod, destinationMod.Order);
+ ViewModel!.InstantReorderSelectedItems(sourceMod, destinationMod!.Order);
};
}
@@ -127,13 +125,13 @@ protected virtual void HandleItemDragged()
///
protected virtual void HandlePointerMoved()
{
- modList.PointerMoved += (sender, args) =>
+ modList.PointerMoved += (_, _) =>
{
var hoveredItem = modList.GetLogicalChildren().Cast().FirstOrDefault(p => p.IsPointerOver);
if (hoveredItem != null)
{
- ViewModel.HoveredMod = hoveredItem.Content as IMod;
- };
+ ViewModel!.HoveredMod = hoveredItem.Content as IMod;
+ }
};
}
@@ -152,6 +150,7 @@ protected override void OnActivated(CompositeDisposable disposables)
HandleItemDragged();
HandlePointerMoved();
}
+
base.OnActivated(disposables);
}
@@ -160,14 +159,15 @@ protected override void OnActivated(CompositeDisposable disposables)
///
protected virtual void SetContextMenus()
{
- modList.ContextMenuOpening += (item) =>
+ modList.ContextMenuOpening += item =>
{
List
//
// ***********************************************************************
+
using System;
using System.Collections.Generic;
using System.Linq;
@@ -68,6 +69,7 @@ async Task updateLayout()
{
await Task.Delay(25);
}
+
performingLayoutUpdate = true;
await Dispatcher.UIThread.SafeInvokeAsync(() =>
{
@@ -77,7 +79,7 @@ await Dispatcher.UIThread.SafeInvokeAsync(() =>
var grid = item.GetLogicalChildren().OfType().FirstOrDefault();
if (grid != null)
{
- for (int i = 0; i < grid.ColumnDefinitions.Count; i++)
+ for (var i = 0; i < grid.ColumnDefinitions.Count; i++)
{
var col = grid.ColumnDefinitions[i];
var width = header.ColumnDefinitions[i].ActualWidth;
@@ -94,19 +96,20 @@ await Dispatcher.UIThread.SafeInvokeAsync(() =>
if (modList != null && header != null)
{
- modList.ContextMenuOpening += (item) =>
+ modList.ContextMenuOpening += item =>
{
List menuItems = null;
if (item != null)
{
- ViewModel.ContextMenuMod = item.Content as IMod;
+ ViewModel!.ContextMenuMod = item.Content as IMod;
menuItems = !string.IsNullOrEmpty(ViewModel.GetContextMenuModModUrl()) || !string.IsNullOrEmpty(ViewModel.GetContextMenuModModSteamUrl()) ? GetAllMenuItems() : GetActionMenuItems();
}
+
menuItems ??= GetStaticMenuItems();
modList.SetContextMenuItems(menuItems);
};
var mbus = DIResolver.Get();
- modList.LayoutUpdated += (sender, args) =>
+ modList.LayoutUpdated += (_, _) =>
{
var visibleItems = modList.ItemContainerGenerator.Containers.ToList();
if (visibleItems.Any())
@@ -121,9 +124,11 @@ await Dispatcher.UIThread.SafeInvokeAsync(() =>
}
}
}
+
updateLayout().ConfigureAwait(false);
};
}
+
base.OnActivated(disposables);
}
@@ -133,62 +138,25 @@ await Dispatcher.UIThread.SafeInvokeAsync(() =>
/// List<MenuItem>.
private List GetActionMenuItems()
{
- var menuItems = new List()
+ var menuItems = new List
{
- new MenuItem()
- {
- Header = ViewModel.CheckNewMods,
- Command = ViewModel.CheckNewModsCommand
- },
- new MenuItem()
- {
- Header = ViewModel.DeleteDescriptor,
- Command = ViewModel.DeleteDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.DeleteAllDescriptors,
- Command = ViewModel.DeleteAllDescriptorsCommand
- },
- new MenuItem()
- {
- Header = "-"
- },
- new MenuItem()
- {
- Header = ViewModel.LockDescriptor,
- Command = ViewModel.LockDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.LockAllDescriptors,
- Command = ViewModel.LockAllDescriptorsCommand
- },
- new MenuItem()
- {
- Header = ViewModel.UnlockDescriptor,
- Command = ViewModel.UnlockDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.UnlockAllDescriptors,
- Command = ViewModel.UnlockAllDescriptorsCommand
- }
+ new() { Header = ViewModel!.CheckNewMods, Command = ViewModel.CheckNewModsCommand },
+ new() { Header = ViewModel.DeleteDescriptor, Command = ViewModel.DeleteDescriptorCommand },
+ new() { Header = ViewModel.DeleteAllDescriptors, Command = ViewModel.DeleteAllDescriptorsCommand },
+ new() { Header = "-" },
+ new() { Header = ViewModel.LockDescriptor, Command = ViewModel.LockDescriptorCommand },
+ new() { Header = ViewModel.LockAllDescriptors, Command = ViewModel.LockAllDescriptorsCommand },
+ new() { Header = ViewModel.UnlockDescriptor, Command = ViewModel.UnlockDescriptorCommand },
+ new() { Header = ViewModel.UnlockAllDescriptors, Command = ViewModel.UnlockAllDescriptorsCommand }
};
if (!string.IsNullOrWhiteSpace(ViewModel.ContextMenuMod?.FullPath))
{
- var menuItem = new MenuItem()
- {
- Header = ViewModel.OpenInAssociatedApp,
- Command = ViewModel.OpenInAssociatedAppCommand
- };
+ var menuItem = new MenuItem { Header = ViewModel.OpenInAssociatedApp, Command = ViewModel.OpenInAssociatedAppCommand };
menuItems.Insert(0, menuItem);
- menuItems.Insert(1, new MenuItem()
- {
- Header = "-"
- });
+ menuItems.Insert(1, new MenuItem { Header = "-" });
}
+
return menuItems;
}
@@ -199,26 +167,15 @@ private List GetActionMenuItems()
private List GetAllMenuItems()
{
var menuItems = new List();
- if (!string.IsNullOrEmpty(ViewModel.GetContextMenuModModUrl()))
+ if (!string.IsNullOrEmpty(ViewModel!.GetContextMenuModModUrl()))
{
- menuItems.Add(new MenuItem()
- {
- Header = ViewModel.OpenUrl,
- Command = ViewModel.OpenUrlCommand
- });
- menuItems.Add(new MenuItem()
- {
- Header = ViewModel.CopyUrl,
- Command = ViewModel.CopyUrlCommand
- });
+ menuItems.Add(new MenuItem { Header = ViewModel.OpenUrl, Command = ViewModel.OpenUrlCommand });
+ menuItems.Add(new MenuItem { Header = ViewModel.CopyUrl, Command = ViewModel.CopyUrlCommand });
}
+
if (!string.IsNullOrEmpty(ViewModel.GetContextMenuModModSteamUrl()))
{
- var menuItem = new MenuItem()
- {
- Header = ViewModel.OpenInSteam,
- Command = ViewModel.OpenInSteamCommand
- };
+ var menuItem = new MenuItem { Header = ViewModel.OpenInSteam, Command = ViewModel.OpenInSteamCommand };
if (menuItems.Count == 0)
{
menuItems.Add(menuItem);
@@ -227,14 +184,14 @@ private List GetAllMenuItems()
{
menuItems.Insert(1, menuItem);
}
+
+ menuItem = new MenuItem { Header = ViewModel.CopyModPath, Command = ViewModel.CopyModPathCommand };
+ menuItems.Add(menuItem);
}
+
if (!string.IsNullOrWhiteSpace(ViewModel.ContextMenuMod?.FullPath))
{
- var menuItem = new MenuItem()
- {
- Header = ViewModel.OpenInAssociatedApp,
- Command = ViewModel.OpenInAssociatedAppCommand
- };
+ var menuItem = new MenuItem { Header = ViewModel.OpenInAssociatedApp, Command = ViewModel.OpenInAssociatedAppCommand };
if (menuItems.Count == 0)
{
menuItems.Add(menuItem);
@@ -244,51 +201,18 @@ private List GetAllMenuItems()
menuItems.Insert(0, menuItem);
}
}
- menuItems.AddRange(new List()
+
+ menuItems.AddRange(new List
{
- new MenuItem()
- {
- Header = "-"
- },
- new MenuItem()
- {
- Header = ViewModel.CheckNewMods,
- Command = ViewModel.CheckNewModsCommand
- },
- new MenuItem()
- {
- Header = ViewModel.DeleteDescriptor,
- Command = ViewModel.DeleteDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.DeleteAllDescriptors,
- Command = ViewModel.DeleteAllDescriptorsCommand
- },
- new MenuItem()
- {
- Header = "-"
- },
- new MenuItem()
- {
- Header = ViewModel.LockDescriptor,
- Command = ViewModel.LockDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.LockAllDescriptors,
- Command = ViewModel.LockAllDescriptorsCommand
- },
- new MenuItem()
- {
- Header = ViewModel.UnlockDescriptor,
- Command = ViewModel.UnlockDescriptorCommand
- },
- new MenuItem()
- {
- Header = ViewModel.UnlockAllDescriptors,
- Command = ViewModel.UnlockAllDescriptorsCommand
- }
+ new() { Header = "-" },
+ new() { Header = ViewModel.CheckNewMods, Command = ViewModel.CheckNewModsCommand },
+ new() { Header = ViewModel.DeleteDescriptor, Command = ViewModel.DeleteDescriptorCommand },
+ new() { Header = ViewModel.DeleteAllDescriptors, Command = ViewModel.DeleteAllDescriptorsCommand },
+ new() { Header = "-" },
+ new() { Header = ViewModel.LockDescriptor, Command = ViewModel.LockDescriptorCommand },
+ new() { Header = ViewModel.LockAllDescriptors, Command = ViewModel.LockAllDescriptorsCommand },
+ new() { Header = ViewModel.UnlockDescriptor, Command = ViewModel.UnlockDescriptorCommand },
+ new() { Header = ViewModel.UnlockAllDescriptors, Command = ViewModel.UnlockAllDescriptorsCommand }
});
return menuItems;
}
@@ -299,19 +223,7 @@ private List GetAllMenuItems()
/// System.Collections.Generic.List<Avalonia.Controls.MenuItem>.
private List GetStaticMenuItems()
{
- var menuItems = new List()
- {
- new MenuItem()
- {
- Header = ViewModel.CheckNewMods,
- Command = ViewModel.CheckNewModsCommand
- },
- new MenuItem()
- {
- Header = ViewModel.DeleteAllDescriptors,
- Command = ViewModel.DeleteAllDescriptorsCommand
- }
- };
+ var menuItems = new List { new() { Header = ViewModel!.CheckNewMods, Command = ViewModel.CheckNewModsCommand }, new() { Header = ViewModel.DeleteAllDescriptors, Command = ViewModel.DeleteAllDescriptorsCommand } };
return menuItems;
}