45 Commits

Author SHA1 Message Date
b87d896b8f update 2025-11-17 19:15:53 +01:00
26a807c8be appupdater 2025-11-17 19:02:40 +01:00
4e657469b3 move to right directory 2025-11-17 18:40:37 +01:00
535679d4ee fix publish script 2025-11-17 18:38:06 +01:00
c220d7f2b8 publish script for manager 2025-11-17 18:34:55 +01:00
ada6f59434 hotkey fix & contextmenu 2025-11-17 18:25:21 +01:00
ce09b47456 optimizations 2025-11-17 16:54:15 +01:00
cd1006b422 fixes 2025-11-17 16:44:49 +01:00
b2331926d7 translation update 2025-11-17 16:37:11 +01:00
e04e5f0b13 local folder workspace 2025-11-17 16:35:02 +01:00
5df8019cfb update nuget packages 2025-11-17 16:02:27 +01:00
fb36f897d6 fixes 2025-11-17 15:59:49 +01:00
d68df750a6 progressbar tweaks 2025-11-17 15:51:50 +01:00
ea8d1522f1 fixes 2025-11-17 15:08:31 +01:00
1a8b03696d add missing icon 2025-11-17 15:02:58 +01:00
7e2a103dbe complete 2025-11-17 15:02:47 +01:00
d80f5c47b1 localization of enums 2025-11-17 13:57:19 +01:00
c2ac96938e work 2025-11-17 09:45:25 +01:00
0bc93bb24b fix 2025-11-17 07:36:20 +01:00
c9eb3e32b4 fix search 2025-11-17 07:35:19 +01:00
afc9ceaa1f fix 2025-11-17 07:31:46 +01:00
7c745cc2f7 visible fix 2025-11-17 07:21:00 +01:00
e584996043 work 2025-11-17 07:19:43 +01:00
72a81e05ad fixes 2025-11-16 22:34:14 +01:00
da79ada91e fix 2025-11-16 20:09:30 +01:00
e47d6599b5 work 2025-11-16 19:48:28 +01:00
7469d037d5 ui(client): improve margin of window & minheight of status label 2025-11-16 13:55:15 +01:00
8f132afe92 complete visual ui 2025-11-16 13:36:47 +01:00
a5db244bc1 update 2025-11-16 10:06:37 +01:00
0b50f1ade2 and even more work 2025-11-16 09:48:03 +01:00
f6b39cb678 progress 2025-11-15 22:55:15 +01:00
d2a454aca0 update 2025-11-15 18:38:17 +01:00
795e3dd1a7 fix 2025-11-15 17:20:29 +01:00
b9ddc20b7d a lot of work 2025-11-15 17:17:52 +01:00
Pascal
336b6ad1fd more work 2025-11-14 11:40:30 +01:00
Pascal
a22f6238d4 more work 2025-11-14 11:38:51 +01:00
Pascal
bb96755232 update 2025-11-14 11:38:25 +01:00
Pascal
b4e4154445 update 2025-11-14 11:35:40 +01:00
Pascal
cd766f73fc part of manager main window 2025-11-14 08:10:42 +01:00
d798eea1d8 update 2025-11-12 14:29:31 +01:00
8ab1689309 width & height 2025-11-10 19:07:30 +01:00
6cf27b4867 manager: migrate base project structure & deps 2025-11-10 18:28:20 +01:00
da25510543 ui(client): more theme tests 2025-11-09 17:55:08 +01:00
a2d15425d1 ui(client): use fluent normal theme (again) 2025-11-09 17:50:18 +01:00
3618d83ef8 ui(client): use fluent compact theme 2025-11-09 17:48:49 +01:00
112 changed files with 3773 additions and 6364 deletions

View File

@@ -1,5 +1,12 @@
<Project> <Project>
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup> <PropertyGroup>
<PackageProjectUrl>https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater</PackageProjectUrl> <PackageProjectUrl>https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater</PackageProjectUrl>
<PackageLicenseExpression>MIT</PackageLicenseExpression> <PackageLicenseExpression>MIT</PackageLicenseExpression>

View File

@@ -1,15 +0,0 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" />
</ItemGroup>
</Project>

View File

@@ -6,5 +6,6 @@
<Application.Styles> <Application.Styles>
<FluentTheme /> <FluentTheme />
<StyleInclude Source="avares://Pilz.UI.AvaloniaUI/Assets/Styles/EnhancedDefaults.axaml"/>
</Application.Styles> </Application.Styles>
</Application> </Application>

View File

@@ -9,6 +9,7 @@ public partial class App : Application
public override void Initialize() public override void Initialize()
{ {
AvaloniaXamlLoader.Load(this); AvaloniaXamlLoader.Load(this);
AppGlobals.Initialize();
} }
public override void OnFrameworkInitializationCompleted() public override void OnFrameworkInitializationCompleted()

View File

@@ -1,121 +1,113 @@
<Window xmlns="https://github.com/avaloniaui" <Window xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:lang="clr-namespace:ModpackUpdater.Apps.Client.Gui.LangRes" xmlns:lang="clr-namespace:ModpackUpdater.Apps.Client.Gui.LangRes"
xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz" xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz"
mc:Ignorable="d" xmlns:symbols="clr-namespace:Pilz.UI.Symbols;assembly=Pilz.UI"
x:Class="ModpackUpdater.Apps.Client.Gui.MainForm" mc:Ignorable="d"
Width="520" x:Class="ModpackUpdater.Apps.Client.Gui.MainForm"
SizeToContent="Height" Width="520"
WindowStartupLocation="CenterScreen" SizeToContent="Height"
CanMaximize="false" WindowStartupLocation="CenterScreen"
Title="Minecraft Modpack Updater" CanMaximize="false"
Icon="/Assets/app.ico" Title="Minecraft Modpack Updater"
> Icon="/Assets/app.ico">
<Grid <Grid
RowDefinitions="Auto,Auto,Auto,Auto,Auto" RowDefinitions="Auto,Auto,Auto,Auto,Auto"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
VerticalAlignment="Top" VerticalAlignment="Top"
x:Name="MainGrid" Margin="3"
> x:Name="MainGrid">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*" MinWidth="250"/> <ColumnDefinition Width="*" MinWidth="250"/>
<ColumnDefinition Width="Auto"/> <ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Labels --> <!-- Labels -->
<Label Grid.Row="0" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.MinecraftProfile}" /> <Label Grid.Row="0" Grid.Column="0" Margin="3" Content="{x:Static lang:GeneralLangRes.MinecraftProfile}" Target="TextBoxMinecraftProfileFolder"/>
<Label Grid.Row="1" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.ModpackConfigUrl}" /> <Label Grid.Row="1" Grid.Column="0" Margin="3" Content="{x:Static lang:GeneralLangRes.ModpackConfigUrl}" Target="TextBoxModpackConfig"/>
<Label Grid.Row="2" Grid.Column="0" Margin="3" VerticalAlignment="Center" IsVisible="false" x:Name="LabelInstallKey" Content="{x:Static lang:GeneralLangRes.InstallationKey}" /> <Label Grid.Row="2" Grid.Column="0" Margin="3" IsVisible="false" x:Name="LabelInstallKey" Content="{x:Static lang:GeneralLangRes.InstallationKey}" Target="TextBoxInstallKey"/>
<Label Grid.Row="3" Grid.Column="0" Margin="3" VerticalAlignment="Center" Content="{x:Static lang:GeneralLangRes.Status}" /> <TextBlock Grid.Row="3" Grid.Column="0" Margin="3" Text="{x:Static lang:GeneralLangRes.Status}"/>
<Label Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="3" VerticalAlignment="Center"> <StackPanel Grid.Row="3" Grid.Column="1" Grid.ColumnSpan="2" Margin="3" Orientation="Horizontal" Spacing="6" MinHeight="{Binding MinHeight, ElementName=TextBoxMinecraftProfileFolder}">
<StackPanel Orientation="Horizontal" Spacing="6"> <Image Width="{x:Static symbols:SymbolGlobals.DefaultImageSmallSize}" x:Name="ImageStatus"/>
<Image Width="16" Height="16" x:Name="ImageStatus" /> <TextBlock x:Name="TextStatus"/>
<TextBlock x:Name="TextStatus" /> </StackPanel>
</StackPanel>
</Label>
<!-- TextBoxes: Profile --> <!-- TextBoxes: Profile -->
<TextBox <TextBox
x:Name="TextBoxMinecraftProfileFolder" x:Name="TextBoxMinecraftProfileFolder"
Grid.Row="0" Grid.Row="0"
Grid.Column="1" Grid.Column="1"
Margin="3" Margin="3"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="C:\..." Watermark="C:\..."
TextChanged="TextBoxMinecraftProfileFolder_TextChanged" TextChanged="TextBoxMinecraftProfileFolder_TextChanged"/>
/>
<!-- TextBoxes: ModpackConfig --> <!-- TextBoxes: ModpackConfig -->
<TextBox <TextBox
x:Name="TextBoxModpackConfig" x:Name="TextBoxModpackConfig"
Grid.Row="1" Grid.Row="1"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Margin="3" Margin="3"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="https://..." Watermark="https://..."
TextChanged="TextBoxModpackConfig_TextChanged" TextChanged="TextBoxModpackConfig_TextChanged"/>
/>
<!-- TextBoxes: InstallKey --> <!-- TextBoxes: InstallKey -->
<TextBox <TextBox
x:Name="TextBoxInstallKey" x:Name="TextBoxInstallKey"
Grid.Row="2" Grid.Row="2"
Grid.Column="1" Grid.Column="1"
Grid.ColumnSpan="2" Grid.ColumnSpan="2"
Margin="3" Margin="3"
VerticalAlignment="Center" VerticalAlignment="Center"
Watermark="XXXXX-YYYYY-ZZZZZ-AAAAA-BBBBB" Watermark="XXXXX-YYYYY-ZZZZZ-AAAAA-BBBBB"
TextChanged="TextBoxInstallKey_TextChanged" TextChanged="TextBoxInstallKey_TextChanged"
IsVisible="false" IsVisible="false"/>
/>
<!-- Button: SearchProfileFolder --> <!-- Button: SearchProfileFolder -->
<pilz:ImageButton <pilz:ImageButton
x:Name="ButtonSearchProfileFolder" x:Name="ButtonSearchProfileFolder"
Grid.Row="0" Grid.Row="0"
Grid.Column="2" Grid.Column="2"
Margin="3" Margin="3"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Text="{x:Static lang:GeneralLangRes.Select}" Text="{x:Static lang:GeneralLangRes.Select}"
Click="ButtonSearchProfileFolder_Click" Click="ButtonSearchProfileFolder_Click"/>
/>
<!-- Button: CheckForUpdates --> <!-- Button: CheckForUpdates -->
<pilz:ImageButton <pilz:ImageButton
x:Name="ButtonCheckForUpdates" x:Name="ButtonCheckForUpdates"
Grid.Row="4" Grid.Row="4"
Grid.Column="1" Grid.Column="1"
Margin="3" Margin="3"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
Text="{x:Static lang:GeneralLangRes.CheckForUpdates}" Text="{x:Static lang:GeneralLangRes.CheckForUpdates}"
Click="ButtonCheckForUpdates_Click" Click="ButtonCheckForUpdates_Click"/>
/>
<!-- Button: Install --> <!-- Button: Install -->
<pilz:ImageSplitButton <pilz:ImageSplitButton
x:Name="ButtonInstall" x:Name="ButtonInstall"
Grid.Row="4" Grid.Row="4"
Grid.Column="2" Grid.Column="2"
Margin="3" Margin="3"
VerticalAlignment="Stretch" VerticalAlignment="Stretch"
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"
Text="{x:Static lang:GeneralLangRes.Install}" Text="{x:Static lang:GeneralLangRes.Install}"
Click="ButtonInstall_Click" Click="ButtonInstall_Click">
> <SplitButton.Flyout>
<SplitButton.Flyout> <MenuFlyout>
<MenuFlyout> <MenuItem x:Name="MenuItemRepair" Header="{x:Static lang:GeneralLangRes.Repair}" Click="MenuItemRepair_Click"/>
<MenuItem x:Name="MenuItemRepair" Header="{x:Static lang:GeneralLangRes.Repair}" Click="MenuItemRepair_Click" /> </MenuFlyout>
</MenuFlyout> </SplitButton.Flyout>
</SplitButton.Flyout> </pilz:ImageSplitButton>
</pilz:ImageSplitButton> </Grid>
</Grid>
</Window> </Window>

View File

@@ -12,8 +12,6 @@ using MsBox.Avalonia.Enums;
using Pilz; using Pilz;
using Pilz.Extensions; using Pilz.Extensions;
using Pilz.Runtime; using Pilz.Runtime;
using Pilz.SymbolPacks.Sets;
using Pilz.UI.AvaloniaUI.Symbols;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.Updating.Client; using Pilz.Updating.Client;
@@ -39,10 +37,10 @@ public partial class MainForm : Window
Closing += MainForm_Closing; Closing += MainForm_Closing;
Loaded += MainForm_Loaded; Loaded += MainForm_Loaded;
ButtonSearchProfileFolder.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.opened_folder); ButtonSearchProfileFolder.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder);
ButtonCheckForUpdates.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.update); ButtonCheckForUpdates.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ButtonInstall.ImageSource = Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer); ButtonInstall.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer);
MenuItemRepair.Icon = Symbols.Fluent.GetImage(SymbolsFluent.wrench, SymbolSize.Small); MenuItemRepair.Icon = AppGlobals.Symbols.GetImage(AppSymbols.wrench, SymbolSize.Small);
ClearStatus(); ClearStatus();
LoadProfileToUi(); LoadProfileToUi();
@@ -66,7 +64,7 @@ public partial class MainForm : Window
{ {
loadingData = true; loadingData = true;
TextBoxMinecraftProfileFolder.Text = modpackInfo.LocaLPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text; TextBoxMinecraftProfileFolder.Text = modpackInfo.LocalPath ?? AppConfig.Instance.LastMinecraftProfilePath ?? TextBoxMinecraftProfileFolder.Text;
TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text; TextBoxModpackConfig.Text = modpackInfo.ConfigUrl ?? TextBoxModpackConfig.Text;
TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text; TextBoxInstallKey.Text = modpackInfo.ExtrasKey ?? TextBoxInstallKey.Text;
@@ -110,36 +108,33 @@ public partial class MainForm : Window
// Ignore // Ignore
} }
if (modpackInfo != null) features = new(updateConfig);
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim();
if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras())
{ {
features = new(updateConfig); SetStatus(GeneralLangRes.InstallationKeyNotValid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
modpackInfo.ExtrasKey = TextBoxInstallKey.Text?.Trim(); return false;
if (!features.IsInvalid() && !string.IsNullOrWhiteSpace(TextBoxInstallKey.Text) && !AllowExtras())
{
SetStatus(GeneralLangRes.InstallationKeyNotValid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield));
return false;
}
} }
LabelInstallKey.IsVisible = TextBoxInstallKey.IsVisible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl); LabelInstallKey.IsVisible = TextBoxInstallKey.IsVisible = !string.IsNullOrWhiteSpace(updateConfig.UnleashApiUrl);
if (modpackInfo == null || string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/) if (string.IsNullOrWhiteSpace(TextBoxMinecraftProfileFolder.Text) /*|| modpackInfo.Valid*/)
{ {
SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); SetStatus(GeneralLangRes.MinecraftProfileFolderSeemsInvalid, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
} }
else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text)) else if (string.IsNullOrWhiteSpace(TextBoxModpackConfig.Text))
{ {
SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, Symbols.Fluent.GetImageSource(SymbolsFluent.warning_shield)); SetStatus(GeneralLangRes.ConfigIncompleteOrNotLoaded, AppGlobals.Symbols.GetImageSource(AppSymbols.general_warning_sign));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
} }
else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance) else if (updateConfig.Maintenance && !updateOptions.IgnoreMaintenance)
{ {
SetStatus(GeneralLangRes.UpdateServerInMaintenance, Symbols.Fluent.GetImageSource(SymbolsFluent.services)); SetStatus(GeneralLangRes.UpdateServerInMaintenance, AppGlobals.Symbols.GetImageSource(AppSymbols.services));
ButtonCheckForUpdates.IsEnabled = false; ButtonCheckForUpdates.IsEnabled = false;
ButtonInstall.IsEnabled = false; ButtonInstall.IsEnabled = false;
return false; return false;
@@ -161,28 +156,28 @@ public partial class MainForm : Window
void error() void error()
{ {
SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, Symbols.Fluent.GetImageSource(SymbolsFluent.close)); SetStatus(GeneralLangRes.ErrorOnUpdateCheckOrUpdating, AppGlobals.Symbols.GetImageSource(AppSymbols.close));
currentUpdating = false; currentUpdating = false;
} }
void installing() void installing()
{ {
SetStatus(GeneralLangRes.Installing, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(GeneralLangRes.Installing, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
currentUpdating = true; currentUpdating = true;
} }
void updatesAvailable() void updatesAvailable()
{ {
SetStatus(GeneralLangRes.AnUpdateIsAvailable, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(GeneralLangRes.AnUpdateIsAvailable, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
} }
void everythingOk() void everythingOk()
{ {
SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, Symbols.Fluent.GetImageSource(SymbolsFluent.done)); SetStatus(GeneralLangRes.EverythingIsRightAndUpToDate, AppGlobals.Symbols.GetImageSource(AppSymbols.done));
currentUpdating = false; currentUpdating = false;
} }
// Check only if not pressed "install", not really needed otherwise. // Check only if not pressed "install", not really needed otherwise.
if (lastUpdateCheckResult is null || !doInstall || repair) if (lastUpdateCheckResult is null || !doInstall || repair)
{ {
SetStatus(GeneralLangRes.CheckingForUpdates, Symbols.Fluent.GetImageSource(SymbolsFluent.update)); SetStatus(GeneralLangRes.CheckingForUpdates, AppGlobals.Symbols.GetImageSource(AppSymbols.update_done));
// Check for extras once again // Check for extras once again
updateOptions.IncludeExtras = AllowExtras(); updateOptions.IncludeExtras = AllowExtras();
@@ -259,13 +254,13 @@ public partial class MainForm : Window
private void Updated_CheckingProgresssUpdated(int toCheck, int processed) private void Updated_CheckingProgresssUpdated(int toCheck, int processed)
{ {
SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.update)); SetStatus(Math.Round(processed / (double)toCheck * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.update_done));
} }
private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs) private void Update_InstallProgessUpdated(UpdateCheckResult result, int processedSyncs)
{ {
var actionCount = result.Actions.Count; var actionCount = result.Actions.Count;
SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer)); SetStatus(Math.Round(processedSyncs / (double)actionCount * 100d, 1) + "%", AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
} }
#endregion #endregion
@@ -277,47 +272,12 @@ public partial class MainForm : Window
AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim(); AppConfig.Instance.LastMinecraftProfilePath = TextBoxMinecraftProfileFolder.Text?.Trim();
} }
private async Task UpdateApp()
{
if (Debugger.IsAttached)
return;
var myAppPath = EnvironmentEx.ProcessPath!;
var updater = new UpdateClient(Program.UpdateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
{
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
};
if (await updater.CheckForUpdate() is {} packageToInstall
&& await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, MsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(this) == ButtonResult.Yes)
{
SetStatus(GeneralLangRes.DownloadProgramUpdate, Symbols.Fluent.GetImageSource(SymbolsFluent.software_installer));
IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
{
IsVisible = false;
await Process.Start(myAppPath).WaitForExitAsync();
Environment.Exit(0);
return;
}
IsEnabled = true;
}
}
private async void MainForm_Loaded(object? sender, RoutedEventArgs e) private async void MainForm_Loaded(object? sender, RoutedEventArgs e)
{ {
#if !DISABLE_UPDATE var updates = new AppUpdates(Program.UpdateUrl, this);
try updates.OnDownloadProgramUpdate += (o, args) => SetStatus(GeneralLangRes.DownloadProgramUpdate, AppGlobals.Symbols.GetImageSource(AppSymbols.software_installer));
{ await updates.UpdateApp();
await UpdateApp(); ClearStatus();
}
catch (Exception ex)
{
await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.UpdateAvailable_Title, string.Format(MsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowAsync();
IsEnabled = true;
}
#endif
CheckStatusAndUpdate(true); CheckStatusAndUpdate(true);
} }

View File

@@ -2,22 +2,13 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ApplicationIcon>Assets\app.ico</ApplicationIcon> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<AssemblyName>MinecraftModpackUpdater</AssemblyName> <AssemblyName>MinecraftModpackUpdater</AssemblyName>
<ImplicitUsings>true</ImplicitUsings>
<Nullable>enable</Nullable>
<IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<BuiltInComInteropSupport>true</BuiltInComInteropSupport> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<LangVersion>latest</LangVersion>
</PropertyGroup> </PropertyGroup>
<ItemGroup>
<TrimmerRootAssembly Include="Newtonsoft.Json" />
<TrimmerRootAssembly Include="Pilz.SymbolPacks.Fluent" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Version.cs" /> <Compile Include="..\Version.cs" />
</ItemGroup> </ItemGroup>
@@ -64,9 +55,6 @@
<PrivateAssets>all</PrivateAssets> <PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets> <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
</PackageReference> </PackageReference>
<PackageReference Include="HarfBuzzSharp" Version="8.3.1.2" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.Linux" Version="8.3.1.2" />
<PackageReference Include="HarfBuzzSharp.NativeAssets.WebAssembly" Version="8.3.1.2" />
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" /> <PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="Mono.Options" Version="6.12.0.148" /> <PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
@@ -74,9 +62,8 @@
<PackageReference Include="Pilz.Configuration" Version="3.2.7" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.Cryptography" Version="2.1.2" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.IO" Version="2.1.0" /> <PackageReference Include="Pilz.IO" Version="2.1.0" />
<PackageReference Include="Pilz.SymbolPacks.Fluent" Version="1.0.12" /> <PackageReference Include="Pilz.UI" Version="3.1.4" />
<PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.1.3" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.18" />
<PackageReference Include="Pilz.UI.AvaloniaUI.Symbols" Version="1.0.0" />
<PackageReference Include="Avalonia" Version="11.3.8" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.8" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="Avalonia.Svg" Version="11.3.0" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
@@ -92,7 +79,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.csproj" /> <ProjectReference Include="..\ModpackUpdater.Apps\ModpackUpdater.Apps.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" /> <ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" /> <ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -12,7 +12,6 @@ public static class Program
private static readonly SettingsManager settingsManager; private static readonly SettingsManager settingsManager;
public static string ProcessPath = EnvironmentEx.ProcessPath!;
public static ISettings Settings => settingsManager.Instance; public static ISettings Settings => settingsManager.Instance;
public static ILogger Log { get; } = new ConsoleLogger(); public static ILogger Log { get; } = new ConsoleLogger();

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip_path_1">
<rect width="480" height="480" />
</clipPath>
</defs>
<g clip-path="url(#clip_path_1)">
<path d="M360 40L180 40L140 0C140 0 40 0 40 0C17.91 0 0 17.91 0 40C0 40 0 120 0 120L400 120C400 120 400 80 400 80C400 57.91 382.09 40 360 40C360 40 360 40 360 40Z" fill="#FFA000" transform="translate(20 100)" />
<g transform="translate(53 -7)">
<path d="M160.042 63.3334L0 7.91667L13.9167 213.75L160.042 300.833L278.333 205.833L292.25 0L160.042 63.3334Z" fill="#5D4037" fill-rule="evenodd" transform="translate(20.875 63.333)" />
<path d="M0 0L13.9167 205.834L160.042 292.917L160.042 55.4167L0 0Z" fill="#8D6E63" fill-rule="evenodd" transform="translate(20.875 71.25)" />
<path d="M13.9167 112.084L13.9167 79.1667L27.8333 72.2554L27.8333 95L41.75 87.0833L41.75 118.75L62.625 109.028L62.625 55.4167L76.5417 48.6954L76.5417 87.0833L90.4583 80.5679L90.4583 63.3333L104.375 55.4167L104.375 35.3637L118.292 28.6979L118.292 47.5L129.425 41.1667L132.208 0L0 63.3333L0 118.75L13.9167 112.084Z" fill="#43A047" fill-rule="evenodd" transform="translate(180.917 63.333)" />
<path d="M0 47.5L139.167 0L292.25 39.5833L160.042 102.917L0 47.5Z" fill="#B2FF59" fill-rule="evenodd" transform="translate(20.875 23.75)" />
<path d="M0 0L2.78333 40.6442L13.9167 44.3888L13.9167 34.9363L27.8333 39.5833L27.8333 65.0513L48.7083 72.2792L48.7083 34.6196L62.625 39.5833L62.625 77.1004L76.5417 81.9217L76.5417 58.9713L90.4583 63.7925L90.4583 86.743L104.375 91.5563L104.375 82.1671L118.292 87.0834L118.292 74.6067L132.208 79.1667L132.208 101.199L160.042 110.833L160.042 55.4167L0 0Z" fill="#66BB6A" fill-rule="evenodd" transform="translate(20.875 71.25)" />
</g>
<path d="M360 0C360 0 40 0 40 0C17.91 0 0 15.1595 0 33.8571C0 33.8571 0 203.143 0 203.143C0 221.84 17.91 237 40 237C40 237 360 237 360 237C382.09 237 400 221.84 400 203.143C400 203.143 400 33.8571 400 33.8571C400 15.1595 382.09 0 360 0C360 0 360 0 360 0Z" fill="#FFCA28" transform="translate(20 183)" />
<path d="M70 80L0 0L140 0L70 80Z" fill="#1565C0" transform="translate(150 380)" />
<path d="M0 0L60 0L60 111.25L0 111.25L0 0Z" fill="#1565C0" transform="translate(190 280)" />
<path d="M30 15C30 23.28 23.29 30 15 30C6.71002 30 0 23.28 0 15C0 6.72 6.71002 0 15 0C23.29 0 30 6.72 30 15C30 15 30 15 30 15Z" fill="#4A148C" transform="translate(430 60)" />
<path d="M125 100C72.62 100 30 57.38 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.84 74.93 55.08 127.16 120 129.75C120 129.75 120 130 120 130L130 130L130 100L125 100C125 100 125 100 125 100Z" fill="#9C27B0" transform="translate(330 60)" />
<path d="M75 50C50.19 50 30 29.81 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.73004 47.36 32.63 77.27 70 79.75C70 79.75 70 80 70 80L80 80L80 50L75 50C75 50 75 50 75 50Z" fill="#7B1FA2" transform="translate(380 60)" />
<path d="M175 150C95.05 150 30 84.95 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.88998 102.5 77.51 177.11 170 179.75C170 179.75 170 180 170 180L180 180L180 150L175 150C175 150 175 150 175 150Z" fill="#BA68C8" transform="translate(280 60)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -2,9 +2,7 @@
<PropertyGroup> <PropertyGroup>
<OutputType>Exe</OutputType> <OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<AssemblyName>MinecraftModpackUpdaterCli</AssemblyName> <AssemblyName>MinecraftModpackUpdaterCli</AssemblyName>
</PropertyGroup> </PropertyGroup>
@@ -12,6 +10,10 @@
<Compile Include="..\Version.cs" /> <Compile Include="..\Version.cs" />
</ItemGroup> </ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Mono.Options" Version="6.12.0.148" /> <PackageReference Include="Mono.Options" Version="6.12.0.148" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
@@ -21,7 +23,6 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\ModpackUpdater.Apps.AppUpdates\ModpackUpdater.Apps.AppUpdates.csproj" />
<ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" /> <ProjectReference Include="..\ModpackUpdater.Manager\ModpackUpdater.Manager.csproj" />
<ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" /> <ProjectReference Include="..\ModpackUpdater\ModpackUpdater.csproj" />
</ItemGroup> </ItemGroup>

View File

@@ -23,7 +23,7 @@ PublisherLinkUrl = https://pilzinsel64.de
PublisherEmail = PublisherEmail =
# DESKTOP INTEGRATION # DESKTOP INTEGRATION
DesktopNoDisplay = false DesktopNoDisplay = true
DesktopTerminal = false DesktopTerminal = false
DesktopFile = DesktopFile =
StartCommand = StartCommand =

View File

@@ -1,4 +1,4 @@
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager.Api;
public static class FeatureTypes public static class FeatureTypes
{ {

View File

@@ -1,14 +1,12 @@
namespace ModpackUpdater.Apps.Manager.Api.Model; using Avalonia.Controls;
using ModpackUpdater.Apps.Manager.Ui.Models;
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
namespace ModpackUpdater.Apps.Manager.Api.Model;
public interface IMainApi public interface IMainApi
{ {
IWorkspace? CurWorkspace { get; } Window MainWindow { get; }
MainWindowViewModel Model { get; }
IActionSetInfos? CurActionSet { get; } bool HasClosed { get; }
Form MainWindow { get; }
void UpdateItem(InstallAction action);
void UpdateItem(IActionSetInfos actionSetInfos);
} }

View File

@@ -0,0 +1,8 @@
namespace ModpackUpdater.Apps.Manager.Api.Model;
public class WorkspaceContext(IMainApi mainApi, IWorkspace? workspace)
{
public IMainApi MainApi => mainApi;
public IWorkspace? Workspace { get; set; } = workspace;
public bool Canceled { get; set; }
}

View File

@@ -10,16 +10,12 @@ public abstract class WorkspaceFeature(string identifier, string name) : PluginF
return workspace?.Config == null || workspace.Config.ProviderId == Identifier; return workspace?.Config == null || workspace.Config.ProviderId == Identifier;
} }
public virtual bool Configure(ref IWorkspace? workspace) public virtual async Task Configure(WorkspaceContext context)
{ {
OnConfigure(ref workspace); await OnConfigure(context);
if (workspace?.Config is null) if (!context.Canceled && context.Workspace?.Config is not null)
return false; context.Workspace.Config.ProviderId = Identifier;
workspace.Config.ProviderId = Identifier;
return true;
} }
public virtual IWorkspace CreateFromConfig(WorkspaceConfig config) public virtual IWorkspace CreateFromConfig(WorkspaceConfig config)
@@ -30,5 +26,5 @@ public abstract class WorkspaceFeature(string identifier, string name) : PluginF
protected abstract void OnCreate(out IWorkspace workspace, WorkspaceConfig config); protected abstract void OnCreate(out IWorkspace workspace, WorkspaceConfig config);
protected abstract bool OnConfigure(ref IWorkspace? workspace); protected abstract Task OnConfigure(WorkspaceContext context);
} }

View File

@@ -0,0 +1,15 @@
<Application xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="ModpackUpdater.Apps.Manager.App"
RequestedThemeVariant="Default">
<!-- "Default" ThemeVariant follows system theme variant. "Dark" or "Light" are other available options. -->
<Application.Styles>
<FluentTheme DensityStyle="Normal" />
<!-- <FluentTheme DensityStyle="Compact" /> -->
<!-- <SimpleTheme /> -->
<StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Fluent.xaml"/>
<!-- <StyleInclude Source="avares://Avalonia.Controls.DataGrid/Themes/Simple.xaml"/> -->
<StyleInclude Source="avares://Pilz.UI.AvaloniaUI/Assets/Styles/EnhancedDefaults.axaml"/>
</Application.Styles>
</Application>

View File

@@ -0,0 +1,24 @@
using Avalonia;
using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Markup.Xaml;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features;
namespace ModpackUpdater.Apps.Manager;
public partial class App : Application
{
public override void Initialize()
{
AvaloniaXamlLoader.Load(this);
AppGlobals.Initialize();
PluginFeatureController.Instance.RegisterAllOwn();
}
public override void OnFrameworkInitializationCompleted()
{
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
desktop.MainWindow = new MainWindow();
base.OnFrameworkInitializationCompleted();
}
}

View File

@@ -0,0 +1 @@
[assembly: PropertyChanged.FilterType("ModpackUpdater.Apps.Manager.Ui.Models")]

Binary file not shown.

After

Width:  |  Height:  |  Size: 108 KiB

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<svg width="480" height="480" viewBox="0 0 480 480" fill="none" xmlns="http://www.w3.org/2000/svg">
<defs>
<clipPath id="clip_path_1">
<rect width="480" height="480" />
</clipPath>
</defs>
<g clip-path="url(#clip_path_1)">
<path d="M360 40L180 40L140 0C140 0 40 0 40 0C17.91 0 0 17.91 0 40C0 40 0 120 0 120L400 120C400 120 400 80 400 80C400 57.91 382.09 40 360 40C360 40 360 40 360 40Z" fill="#FFA000" transform="translate(20 100)" />
<g transform="translate(53 -7)">
<path d="M160.042 63.3334L0 7.91667L13.9167 213.75L160.042 300.833L278.333 205.833L292.25 0L160.042 63.3334Z" fill="#5D4037" fill-rule="evenodd" transform="translate(20.875 63.333)" />
<path d="M0 0L13.9167 205.834L160.042 292.917L160.042 55.4167L0 0Z" fill="#8D6E63" fill-rule="evenodd" transform="translate(20.875 71.25)" />
<path d="M13.9167 112.084L13.9167 79.1667L27.8333 72.2554L27.8333 95L41.75 87.0833L41.75 118.75L62.625 109.028L62.625 55.4167L76.5417 48.6954L76.5417 87.0833L90.4583 80.5679L90.4583 63.3333L104.375 55.4167L104.375 35.3637L118.292 28.6979L118.292 47.5L129.425 41.1667L132.208 0L0 63.3333L0 118.75L13.9167 112.084Z" fill="#43A047" fill-rule="evenodd" transform="translate(180.917 63.333)" />
<path d="M0 47.5L139.167 0L292.25 39.5833L160.042 102.917L0 47.5Z" fill="#B2FF59" fill-rule="evenodd" transform="translate(20.875 23.75)" />
<path d="M0 0L2.78333 40.6442L13.9167 44.3888L13.9167 34.9363L27.8333 39.5833L27.8333 65.0513L48.7083 72.2792L48.7083 34.6196L62.625 39.5833L62.625 77.1004L76.5417 81.9217L76.5417 58.9713L90.4583 63.7925L90.4583 86.743L104.375 91.5563L104.375 82.1671L118.292 87.0834L118.292 74.6067L132.208 79.1667L132.208 101.199L160.042 110.833L160.042 55.4167L0 0Z" fill="#66BB6A" fill-rule="evenodd" transform="translate(20.875 71.25)" />
</g>
<path d="M360 0C360 0 40 0 40 0C17.91 0 0 15.1595 0 33.8571C0 33.8571 0 203.143 0 203.143C0 221.84 17.91 237 40 237C40 237 360 237 360 237C382.09 237 400 221.84 400 203.143C400 203.143 400 33.8571 400 33.8571C400 15.1595 382.09 0 360 0C360 0 360 0 360 0Z" fill="#FFCA28" transform="translate(20 183)" />
<path d="M70 80L0 0L140 0L70 80Z" fill="#1565C0" transform="translate(150 380)" />
<path d="M0 0L60 0L60 111.25L0 111.25L0 0Z" fill="#1565C0" transform="translate(190 280)" />
<path d="M30 15C30 23.28 23.29 30 15 30C6.71002 30 0 23.28 0 15C0 6.72 6.71002 0 15 0C23.29 0 30 6.72 30 15C30 15 30 15 30 15Z" fill="#4A148C" transform="translate(430 60)" />
<path d="M125 100C72.62 100 30 57.38 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.84 74.93 55.08 127.16 120 129.75C120 129.75 120 130 120 130L130 130L130 100L125 100C125 100 125 100 125 100Z" fill="#9C27B0" transform="translate(330 60)" />
<path d="M75 50C50.19 50 30 29.81 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.73004 47.36 32.63 77.27 70 79.75C70 79.75 70 80 70 80L80 80L80 50L75 50C75 50 75 50 75 50Z" fill="#7B1FA2" transform="translate(380 60)" />
<path d="M175 150C95.05 150 30 84.95 30 5C30 5 30 0 30 0L0 0L0 10C0 10 0.25 10 0.25 10C2.88998 102.5 77.51 177.11 170 179.75C170 179.75 170 180 170 180L180 180L180 150L175 150C175 150 175 150 175 150Z" fill="#BA68C8" transform="translate(280 60)" />
</g>
</svg>

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,11 +0,0 @@
namespace ModpackUpdater.Apps.Manager;
internal static class Extensions
{
public static string? Nullify(this string? @this)
{
if (string.IsNullOrEmpty(@this))
return null;
return @this;
}
}

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,19 +12,15 @@ internal class CheckSingleActionHealthyFeature : PluginFunction, IPluginFeatureP
public CheckSingleActionHealthyFeature() : base(FeatureTypes.ActionsContextMenu, "origin.checksingleactionhearlthy", FeatureNamesLangRes.CheckSingleActionHealthy) public CheckSingleActionHealthyFeature() : base(FeatureTypes.ActionsContextMenu, "origin.checksingleactionhearlthy", FeatureNamesLangRes.CheckSingleActionHealthy)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.heart_with_pulse, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.heart_with_pulse, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not { } row)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault() is not GridViewRowInfo row
|| row.Tag is not InstallAction)
return null; return null;
SharedFunctions.CheckActionHealthy(p.Api, row); await SharedFunctions.CheckActionHealthy(p.Api, row);
return null; return null;
} }

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,19 +12,13 @@ internal class ClearDirectLinkFeature : PluginFunction, IPluginFeatureProvider<C
public ClearDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.cleardirectlink", FeatureNamesLangRes.ClearDirectLinkFeature) public ClearDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.cleardirectlink", FeatureNamesLangRes.ClearDirectLinkFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.broom, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is MainApiParameters p && p.Api.Model.SelectedGridRow is { } row)
|| p.Api.MainWindow is not MainForm mainForm SharedFunctions.ClearDirectLinks(p.Api, row);
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView return Task.FromResult<object?>(null);
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null;
SharedFunctions.ClearDirectLinks(p.Api, selectedAction);
return null;
} }
} }

View File

@@ -1,9 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdateCollectorFeature> internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<UpdateCollectorFeature>
@@ -12,19 +11,15 @@ internal class UpdateCollectorFeature : PluginFunction, IPluginFeatureProvider<U
public UpdateCollectorFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatecollector", FeatureNamesLangRes.UpdateCollectorFeature) public UpdateCollectorFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatecollector", FeatureNamesLangRes.UpdateCollectorFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.search, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not { } row)
|| p.Api.CurWorkspace?.UpdateInfos is null
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null; return null;
SharedFunctions.CollectUpdates(p.Api, selectedAction); await SharedFunctions.CollectUpdates(p.Api, row.Action);
return null; return null;
} }

View File

@@ -1,8 +1,9 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.CM; namespace ModpackUpdater.Apps.Manager.Features.CM;
@@ -12,18 +13,15 @@ internal class UpdateDirectLinkFeature : PluginFunction, IPluginFeatureProvider<
public UpdateDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatedirectlink", FeatureNamesLangRes.UpdateDirectLinkFeature) public UpdateDirectLinkFeature() : base(FeatureTypes.ActionsContextMenu, "origin.updatedirectlink", FeatureNamesLangRes.UpdateDirectLinkFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.renew, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.SelectedGridRow is not MainWindowGridRow row)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| gridView.SelectedRows.FirstOrDefault()?.Tag is not InstallAction selectedAction)
return null; return null;
SharedFunctions.FindNewDirectLinks(p.Api, selectedAction); await SharedFunctions.FindNewDirectLinks(p.Api, row);
return null; return null;
} }

View File

@@ -1,98 +1,80 @@
using ModpackUpdater.Apps.Manager.Api.Model; using System.Text;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui; using ModpackUpdater.Apps.Manager.Ui;
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
using ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
using ModpackUpdater.Manager; using ModpackUpdater.Manager;
using MsBox.Avalonia;
using OfficeOpenXml; using OfficeOpenXml;
using Pilz.UI.WinForms.Extensions; using OfficeOpenXml.Table;
using System.Text; using Pilz.UI.AvaloniaUI.Dialogs;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features; namespace ModpackUpdater.Apps.Manager.Features;
internal static class SharedFunctions internal static class SharedFunctions
{ {
public static bool CheckActionHealthy(IMainApi api, params GridViewRowInfo[] selectedRows) private static readonly IImage? imageSourceSuccess = AppGlobals.Symbols.GetImageSource(AppSymbols.done);
private static readonly IImage? imageSourceWorking = AppGlobals.Symbols.GetImageSource(AppSymbols.hourglass);
private static readonly IImage? imageSourceFailed = AppGlobals.Symbols.GetImageSource(AppSymbols.close);
public static async Task CheckActionHealthy(IMainApi api, params MainWindowGridRow[] rows)
{ {
if (api.MainWindow is not MainForm mainForm var rowsCount = rows.Length;
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView
|| mainForm.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() is not RadWaitingBar rwb)
return false;
rwb.StartWaiting();
rwb.ShowText = true;
var rowsCount = selectedRows.Length;
rwb.Text = "0 / " + rowsCount;
gridView.BeginUpdate();
var failed = false; var failed = false;
var msg = default(string);
var factory = new ModpackFactory(); var factory = new ModpackFactory();
var rows = new Dictionary<GridViewRowInfo, InstallAction>(); api.Model.Progress.Start(rowsCount);
for (var i = 0; i < selectedRows.Length; i++)
for (var i = 0; i < rowsCount; i++)
{ {
var row = selectedRows[i]; var row = rows[i];
if (row.SourceType == SourceType.DirectLink)
continue;
row.StateImage = imageSourceWorking;
if (row.Tag is InstallAction action) try
{ {
Task.Run(async () => var result = await factory.ResolveSourceUrl(row.Action);
{ failed = string.IsNullOrWhiteSpace(result);
try }
{ catch (Exception ex)
var result = await factory.ResolveSourceUrl(action); {
failed = string.IsNullOrWhiteSpace(result); // Ignore
}
catch (Exception ex)
{
msg = ex.Message;
}
}).Wait();
} }
foreach (var c in row.Cells) if (api.HasClosed)
{ return;
c.Style.CustomizeFill = true;
c.Style.BackColor = failed ? Color.IndianRed : Color.ForestGreen;
}
rwb.Text = $"{i} / {rowsCount}"; row.StateImage = failed ? imageSourceFailed : imageSourceSuccess;
api.Model.Progress.Set(i);
Application.DoEvents();
} }
gridView.EndUpdate(); api.Model.Progress.Stop();
rwb.ShowText = false;
rwb.StopWaiting();
if (rowsCount == 1 && failed && !string.IsNullOrWhiteSpace(msg))
MessageBox.Show(msg);
return true;
} }
public static bool CollectUpdates(IMainApi api, params InstallAction[] actions) public static async Task<bool> CollectUpdates(IMainApi api, params InstallAction[] actions)
{ {
if (api.CurWorkspace?.UpdateInfos is null) if (api.Model.CurrentWorkspace?.UpdateInfos is null || api.Model.CurrentTreeNodes is null)
return false; return false;
// Collect updates // Collect updates
var ucDialog = new UpdatesCollectorUi(api.CurWorkspace, actions); var result = await AvaloniaFlyoutBase.Show(new UpdatesCollectorView(api.Model.CurrentWorkspace, actions), api.MainWindow);
if (!ucDialog.ShowDialog(api.MainWindow).IsOk() || ucDialog.CurrentUpdates is null) if (api.HasClosed || result.Result is not ModUpdates resultUpdates)
return false; return false;
// Collect versions with changes // Collect versions with changes
var updates = new List<UpdatesCollectorUi.ModUpdateInfo>(); var updates = resultUpdates.List.Where(update => update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Key).ToList();
foreach (var update in ucDialog.CurrentUpdates.List)
{
if (update.Origin.SourceTag != update.AvailableVersions[update.NewVersion].Value)
updates.Add(update);
}
// Path install actions // Path install actions
foreach (var update in updates) foreach (var update in updates)
{ {
update.Origin.SourceTag = update.AvailableVersions[update.NewVersion].Value; var sourceTag = update.AvailableVersions[update.NewVersion].Key;
api.UpdateItem(update.Origin); if (api.Model.CurrentGridRows?.FirstOrDefault(n => n.Action == update.Origin) is { } row)
row.SourceTag = sourceTag;
else
update.Origin.SourceTag = sourceTag;
} }
// Create update actions // Create update actions
@@ -104,65 +86,59 @@ internal static class SharedFunctions
InheritFrom = update.Origin.Id, InheritFrom = update.Origin.Id,
}); });
} }
api.CurWorkspace.UpdateInfos.Updates.Insert(0, updateSet); api.Model.CurrentWorkspace.UpdateInfos.Updates.Insert(0, updateSet);
api.UpdateItem(updateSet);
// Add update to ui
api.Model.CurrentTreeNodes[1].Nodes.Insert(0, new ActionSetTreeNode(updateSet));
return true; return true;
} }
public static void FindNewDirectLinks(IMainApi api, params InstallAction[] actions) public static async Task FindNewDirectLinks(IMainApi api, params MainWindowGridRow[] rows)
{ {
var mainForm = api.MainWindow as MainForm;
var gridView = mainForm?.Controls.Find("radGridView_Actions", true).FirstOrDefault() as RadGridView;
var rwb = mainForm?.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() as RadWaitingBar;
var factory = new ModpackFactory(); var factory = new ModpackFactory();
rwb?.StartWaiting(); api.Model.Progress.Start(rows.Length);
gridView?.BeginUpdate();
foreach (var action in actions) for (var i = 0; i < rows.Length; i++)
{ {
if (action.SourceType != SourceType.DirectLink) var row = rows[i];
if (row.SourceType == SourceType.DirectLink)
continue;
row.StateImage = imageSourceWorking;
try
{ {
try row.SourceUrl = await factory.ResolveSourceUrl(row.Action);
{ row.StateImage = imageSourceSuccess;
Task.Run(async () =>
{
action.SourceUrl = await factory.ResolveSourceUrl(action);
}).Wait();
}
catch (Exception)
{
// Fail silently
}
api.UpdateItem(action);
} }
catch (Exception)
{
row.StateImage = imageSourceFailed;
}
if (api.HasClosed)
return;
api.Model.Progress.Set(i);
} }
gridView?.EndUpdate(); api.Model.Progress.Stop();
rwb?.StopWaiting();
} }
public static void ClearDirectLinks(IMainApi api, params InstallAction[] actions) public static void ClearDirectLinks(IMainApi api, params MainWindowGridRow[] rows)
{ {
var mainForm = api.MainWindow as MainForm; api.Model.Progress.Start(rows.Length);
var gridView = mainForm?.Controls.Find("radGridView_Actions", true).FirstOrDefault() as RadGridView;
var rwb = mainForm?.Controls.Find("radWaitingBar_Actions", true).FirstOrDefault() as RadWaitingBar;
rwb?.StartWaiting(); for (var i = 0; i < rows.Length; i++)
gridView?.BeginUpdate();
foreach (var action in actions)
{ {
if (action.SourceType != SourceType.DirectLink) var row = rows[i];
{ if (row.SourceType != SourceType.DirectLink)
action.SourceUrl = null; row.SourceUrl = null;
api.UpdateItem(action); row.StateImage = null;
} api.Model.Progress.Set(i);
} }
gridView?.EndUpdate(); api.Model.Progress.Stop();
rwb?.StopWaiting();
} }
public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos) public static string GenerateChangelog(InstallInfos installInfos, UpdateInfo updateInfos)
@@ -250,10 +226,10 @@ internal static class SharedFunctions
return sb.ToString().TrimEnd(); return sb.ToString().TrimEnd();
} }
public static ExcelPackage? GenerateModlistAsExcel(InstallInfos installInfos) public static ExcelPackage GenerateModlistAsExcel(InstallInfos installInfos)
{ {
var pkg = new ExcelPackage(); var pkg = new ExcelPackage();
var ws = pkg.Workbook.Worksheets.Add(string.Format(GeneralLangRes.Text_ModlistForVersion, installInfos.Version)); var ws = pkg.Workbook.Worksheets.Add(string.Format(GeneralLangRes.ModlistForVersionX, installInfos.Version));
var cr = 1; var cr = 1;
var cc = 1; var cc = 1;
@@ -301,7 +277,7 @@ internal static class SharedFunctions
ws.Column(cc++).Width = 20; ws.Column(cc++).Width = 20;
ws.Column(cc++).Width = 30; ws.Column(cc++).Width = 30;
var tableDef = ws.Tables.Add(ws.Cells[1, 1, cr - 1, cc - 1], "Table"); var tableDef = ws.Tables.Add(ws.Cells[1, 1, cr - 1, cc - 1], "Table");
tableDef.TableStyle = OfficeOpenXml.Table.TableStyles.Medium16; tableDef.TableStyle = TableStyles.Medium16;
tableDef.ShowHeader = true; tableDef.ShowHeader = true;
return pkg; return pkg;

View File

@@ -1,8 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls.UI; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -12,17 +12,15 @@ internal class CheckAllActionsHealthyFeature : PluginFunction, IPluginFeaturePro
public CheckAllActionsHealthyFeature() : base(FeatureTypes.Tools, "origin.checkallactionshearlthy", FeatureNamesLangRes.CheckAllActionsHealthy) public CheckAllActionsHealthyFeature() : base(FeatureTypes.Tools, "origin.checkallactionshearlthy", FeatureNamesLangRes.CheckAllActionsHealthy)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.heart_with_pulse, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.heart_with_pulse, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
|| p.Api.MainWindow is not MainForm mainForm
|| mainForm.Controls.Find("radGridView_Actions", true).FirstOrDefault() is not RadGridView gridView)
return null; return null;
SharedFunctions.CheckActionHealthy(p.Api, [.. gridView.Rows]); await SharedFunctions.CheckActionHealthy(p.Api, [.. p.Api.Model.CurrentGridRows]);
return null; return null;
} }

View File

@@ -1,6 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -10,16 +12,13 @@ internal class ClearDirectLinksFeature : PluginFunction, IPluginFeatureProvider<
public ClearDirectLinksFeature() : base(FeatureTypes.Tools, "origin.cleardirectlinks", FeatureNamesLangRes.ClearDirectLinksFeature) public ClearDirectLinksFeature() : base(FeatureTypes.Tools, "origin.cleardirectlinks", FeatureNamesLangRes.ClearDirectLinksFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.broom, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.broom, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is MainApiParameters p && p.Api.Model.CurrentGridRows is not null)
return null; SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows]);
return Task.FromResult<object?>(null);
SharedFunctions.ClearDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]);
return null;
} }
} }

View File

@@ -1,7 +1,11 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -11,20 +15,23 @@ internal class GenerateChangelogFeature : PluginFunction, IPluginFeatureProvider
public GenerateChangelogFeature() : base(FeatureTypes.Tools, "origin.genchangelog", FeatureNamesLangRes.GenerateChangelogFeature) public GenerateChangelogFeature() : base(FeatureTypes.Tools, "origin.genchangelog", FeatureNamesLangRes.GenerateChangelogFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.time_machine, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurActionSet is not UpdateInfo updateInfos) if (@params is not MainApiParameters p
|| p.Api.Model.CurrentWorkspace?.InstallInfos is null
|| p.Api.Model.SelectedTreeNode is not ActionSetTreeNode node
|| node.Infos is not UpdateInfo updateInfo)
return null; return null;
var changelog = SharedFunctions.GenerateChangelog(p.Api.CurWorkspace.InstallInfos, updateInfos); var changelog = SharedFunctions.GenerateChangelog(p.Api.Model.CurrentWorkspace.InstallInfos, updateInfo);
if (!string.IsNullOrWhiteSpace(changelog)) if (string.IsNullOrWhiteSpace(changelog))
{ return null;
Clipboard.SetText(changelog);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ChangelogCopiedToClipboard, MsgBoxLangRes.ChangelogCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info); await p.Api.MainWindow.Clipboard?.SetTextAsync(changelog);
} await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ChangelogCopiedToClipboard_Title, MsgBoxLangRes.ChangelogCopiedToClipboard, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
return null; return null;
} }

View File

@@ -1,8 +1,12 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using Avalonia.Controls;
using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Utils;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsExcelFeature> internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsExcelFeature>
@@ -11,28 +15,28 @@ internal class GenerateModlistAsExcelFeature : PluginFunction, IPluginFeaturePro
public GenerateModlistAsExcelFeature() : base(FeatureTypes.Tools, "origin.genmodlist.xlsx", FeatureNamesLangRes.GenerateModlistAsExcelFeature) public GenerateModlistAsExcelFeature() : base(FeatureTypes.Tools, "origin.genmodlist.xlsx", FeatureNamesLangRes.GenerateModlistAsExcelFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.list_view, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
using var pkg = SharedFunctions.GenerateModlistAsExcel(p.Api.CurWorkspace.InstallInfos); // Generate excel
if (pkg is null) using var pkg = SharedFunctions.GenerateModlistAsExcel(p.Api.Model.CurrentWorkspace.InstallInfos);
// Ask for save
var file = await TopLevel.GetTopLevel(p.Api.MainWindow)!.StorageProvider.SaveFilePickerAsync(new()
{
FileTypeChoices = [MyFilePickerFileTypes.Excel]
});
if (file is null)
return null; return null;
using var sfd = new RadSaveFileDialog // Save file
{ await pkg.SaveAsAsync(file.Path.AbsolutePath);
Filter = "*.xlsx|*.xlsx|*|*" await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ModlistGenerated_Title, MsgBoxLangRes.ModlistGenerated, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
};
if (sfd.ShowDialog(p.Api.MainWindow) == DialogResult.OK)
{
pkg.SaveAs(sfd.FileName);
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistGenerated, MsgBoxLangRes.ModlistGenerated_Title, MessageBoxButtons.OK, RadMessageIcon.Info);
}
return null; return null;
} }

View File

@@ -1,26 +1,30 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz.Features; using Pilz.Features;
using Telerik.WinControls; using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
internal class GenerateModlistAsMarkdownFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsMarkdownFeature> internal class GenerateModlistAsMarkdownFeature : PluginFunction, IPluginFeatureProvider<GenerateModlistAsMarkdownFeature>
{ {
public static GenerateModlistAsMarkdownFeature Instance { get; } = new(); public static GenerateModlistAsMarkdownFeature Instance { get; } = new();
public GenerateModlistAsMarkdownFeature() : base(FeatureTypes.Tools, "origin.genmodlist.md", FeatureNamesLangRes.GenerateModlistAsMarkdownFeature) public GenerateModlistAsMarkdownFeature() : base(FeatureTypes.Tools, "origin.genmodlist.md", FeatureNamesLangRes.GenerateModlistAsMarkdownFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.list_view, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.list_view, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
Clipboard.SetText(SharedFunctions.GenerateModlistAsMarkdown(p.Api.CurWorkspace.InstallInfos)); p.Api.MainWindow.Clipboard?.SetTextAsync(SharedFunctions.GenerateModlistAsMarkdown(p.Api.Model.CurrentWorkspace.InstallInfos));
RadMessageBox.Show(p.Api.MainWindow, MsgBoxLangRes.ModlistCopiedToClipboard, MsgBoxLangRes.ModlistCopiedToClipboard_Title, MessageBoxButtons.OK, RadMessageIcon.Info); await MessageBoxManager.GetMessageBoxStandard(MsgBoxLangRes.ModlistCopiedToClipboard_Title, MsgBoxLangRes.ModlistCopiedToClipboard, ButtonEnum.Ok, MsBox.Avalonia.Enums.Icon.Info).ShowAsPopupAsync(p.Api.MainWindow);
return null; return null;
} }

View File

@@ -1,6 +1,8 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Tools; namespace ModpackUpdater.Apps.Manager.Features.Tools;
@@ -10,15 +12,15 @@ internal class UpdateDirectLinksFeature : PluginFunction, IPluginFeatureProvider
public UpdateDirectLinksFeature() : base(FeatureTypes.Tools, "origin.updatedirectlinks", FeatureNamesLangRes.UpdateDirectLinksFeature) public UpdateDirectLinksFeature() : base(FeatureTypes.Tools, "origin.updatedirectlinks", FeatureNamesLangRes.UpdateDirectLinksFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.renew, Pilz.UI.Symbols.SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.renew, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentGridRows is null)
return null; return null;
SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]); await SharedFunctions.FindNewDirectLinks(p.Api, [.. p.Api.Model.CurrentGridRows]);
return null; return null;
} }

View File

@@ -1,4 +1,5 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Params; using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
@@ -11,15 +12,15 @@ internal class UpdatesCollectorFeature : PluginFunction, IPluginFeatureProvider<
public UpdatesCollectorFeature() : base(FeatureTypes.Tools, "origin.updatescollector", FeatureNamesLangRes.UpdatesCollectorFeature) public UpdatesCollectorFeature() : base(FeatureTypes.Tools, "origin.updatescollector", FeatureNamesLangRes.UpdatesCollectorFeature)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.search, SymbolSize.Small); Icon = AppGlobals.Symbols.GetImage(AppSymbols.search, SymbolSize.Small);
} }
protected override object? ExecuteFunction(PluginFunctionParameter? @params) protected override async Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
{ {
if (@params is not MainApiParameters p || p.Api.CurWorkspace?.InstallInfos is null) if (@params is not MainApiParameters p || p.Api.Model.CurrentWorkspace?.InstallInfos is null)
return null; return null;
SharedFunctions.CollectUpdates(p.Api, [.. p.Api.CurWorkspace.InstallInfos.Actions]); await SharedFunctions.CollectUpdates(p.Api, [.. p.Api.Model.CurrentWorkspace.InstallInfos.Actions]);
return null; return null;
} }

View File

@@ -6,19 +6,14 @@ namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspace internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspace
{ {
private string? rawInstallInfos = null; private string? rawInstallInfos;
private string? rawUpdateInfos = null; private string? rawUpdateInfos;
public WorkspaceConfig Config => ConfigX; public WorkspaceConfig Config => ConfigX;
public GitLabRepoWorkspaceConfig ConfigX { get; } = config; public GitLabRepoWorkspaceConfig ConfigX { get; } = config;
public IGitLabClient Gitlab { get; } = new GitLabClient(config.InstanceUrl, config.ApiToken); public IGitLabClient Gitlab { get; } = new GitLabClient(config.InstanceUrl, config.ApiToken);
public ModpackConfig? ModpackConfig { get; private set; } public ModpackConfig? ModpackConfig { get; private set; }
public InstallInfos? InstallInfos { get; private set; } public InstallInfos? InstallInfos { get; private set; }
public UpdateInfos? UpdateInfos { get; private set; } public UpdateInfos? UpdateInfos { get; private set; }
public async Task<bool> Load() public async Task<bool> Load()
@@ -39,13 +34,17 @@ internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspac
public async Task<bool> Save() public async Task<bool> Save()
{ {
var failed = true;
if (InstallInfos != null) if (InstallInfos != null)
{ {
var newInstallInfos = InstallInfos.ToString(); var newInstallInfos = InstallInfos.ToString();
if (newInstallInfos != rawInstallInfos) if (newInstallInfos != rawInstallInfos)
{ {
await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos); if (await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos))
rawInstallInfos = newInstallInfos; rawInstallInfos = newInstallInfos;
else
failed = true;
} }
} }
@@ -54,12 +53,14 @@ internal class GitLabRepoWorkspace(GitLabRepoWorkspaceConfig config) : IWorkspac
var newUpdateInfos = UpdateInfos.ToString(); var newUpdateInfos = UpdateInfos.ToString();
if (newUpdateInfos != rawUpdateInfos) if (newUpdateInfos != rawUpdateInfos)
{ {
await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos); if (await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos))
rawUpdateInfos = newUpdateInfos; rawUpdateInfos = newUpdateInfos;
else
failed = true;
} }
} }
return true; return failed;
} }
private async Task<string> GetContent(string path) private async Task<string> GetContent(string path)

View File

@@ -2,21 +2,19 @@
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspaceConfig : WorkspaceConfig public class GitLabRepoWorkspaceConfig : WorkspaceConfig, ICloneable
{ {
public override string DisplayText => $"{RepoName ?? "?"} | {RepoBranche} | {InstanceUrl}"; public override string DisplayText => $"{RepoName ?? "?"} | {RepoBranche} | {InstanceUrl}";
public string? RepoName { get; set; } public string? RepoName { get; set; }
public string InstanceUrl { get; set; } = "https://gitlab.com"; public string InstanceUrl { get; set; } = "https://gitlab.com";
public string? ApiToken { get; set; } public string? ApiToken { get; set; }
public long RepoId { get; set; } = 0L; public long RepoId { get; set; } = 0L;
public string RepoBranche { get; set; } = "master"; public string RepoBranche { get; set; } = "master";
public string FileLocationInstallJson { get; set; } = "install.json"; public string FileLocationInstallJson { get; set; } = "install.json";
public string FileLocationUpdateJson { get; set; } = "updates.json"; public string FileLocationUpdateJson { get; set; } = "updates.json";
public object Clone()
{
return MemberwiseClone();
}
} }

View File

@@ -1,266 +0,0 @@
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
partial class GitLabRepoWorkspaceConfigEditor
{
/// <summary>
/// Erforderliche Designervariable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Verwendete Ressourcen bereinigen.
/// </summary>
/// <param name="disposing">True, wenn verwaltete Ressourcen gelöscht werden sollen; andernfalls False.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Vom Komponenten-Designer generierter Code
/// <summary>
/// Erforderliche Methode für die Designerunterstützung.
/// Der Inhalt der Methode darf nicht mit dem Code-Editor geändert werden.
/// </summary>
private void InitializeComponent()
{
tableLayoutPanel1 = new TableLayoutPanel();
radTextBox_FileLocUpdateJson = new Telerik.WinControls.UI.RadTextBox();
radTextBox_FileLocInstallJson = new Telerik.WinControls.UI.RadTextBox();
radTextBox_RepoBranche = new Telerik.WinControls.UI.RadTextBox();
radSpinEditor_RepoId = new Telerik.WinControls.UI.RadSpinEditor();
radTextBox_ApiToken = new Telerik.WinControls.UI.RadTextBox();
radTextBox_InstanceUrl = new Telerik.WinControls.UI.RadTextBox();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radLabel2 = new Telerik.WinControls.UI.RadLabel();
radLabel3 = new Telerik.WinControls.UI.RadLabel();
radLabel4 = new Telerik.WinControls.UI.RadLabel();
radLabel5 = new Telerik.WinControls.UI.RadLabel();
radLabel6 = new Telerik.WinControls.UI.RadLabel();
radLabel7 = new Telerik.WinControls.UI.RadLabel();
radTextBox_ModpackConfigUrl = new Telerik.WinControls.UI.RadTextBox();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocUpdateJson).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocInstallJson).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_RepoBranche).BeginInit();
((System.ComponentModel.ISupportInitialize)radSpinEditor_RepoId).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ApiToken).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstanceUrl).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel2).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel3).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel4).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel5).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel6).BeginInit();
((System.ComponentModel.ISupportInitialize)radLabel7).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ModpackConfigUrl).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.AutoSizeMode = AutoSizeMode.GrowAndShrink;
tableLayoutPanel1.ColumnCount = 1;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.Controls.Add(radTextBox_FileLocUpdateJson, 0, 11);
tableLayoutPanel1.Controls.Add(radTextBox_FileLocInstallJson, 0, 9);
tableLayoutPanel1.Controls.Add(radTextBox_RepoBranche, 0, 7);
tableLayoutPanel1.Controls.Add(radSpinEditor_RepoId, 0, 5);
tableLayoutPanel1.Controls.Add(radTextBox_ApiToken, 0, 3);
tableLayoutPanel1.Controls.Add(radTextBox_InstanceUrl, 0, 1);
tableLayoutPanel1.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel1.Controls.Add(radLabel2, 0, 2);
tableLayoutPanel1.Controls.Add(radLabel3, 0, 4);
tableLayoutPanel1.Controls.Add(radLabel4, 0, 6);
tableLayoutPanel1.Controls.Add(radLabel5, 0, 8);
tableLayoutPanel1.Controls.Add(radLabel6, 0, 10);
tableLayoutPanel1.Controls.Add(radLabel7, 0, 12);
tableLayoutPanel1.Controls.Add(radTextBox_ModpackConfigUrl, 0, 13);
tableLayoutPanel1.Dock = DockStyle.Fill;
tableLayoutPanel1.Location = new Point(0, 30);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 14;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(300, 406);
tableLayoutPanel1.TabIndex = 4;
//
// radTextBox_FileLocUpdateJson
//
radTextBox_FileLocUpdateJson.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_FileLocUpdateJson.Location = new Point(3, 321);
radTextBox_FileLocUpdateJson.Name = "radTextBox_FileLocUpdateJson";
radTextBox_FileLocUpdateJson.Size = new Size(294, 24);
radTextBox_FileLocUpdateJson.TabIndex = 4;
//
// radTextBox_FileLocInstallJson
//
radTextBox_FileLocInstallJson.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_FileLocInstallJson.Location = new Point(3, 263);
radTextBox_FileLocInstallJson.Name = "radTextBox_FileLocInstallJson";
radTextBox_FileLocInstallJson.Size = new Size(294, 24);
radTextBox_FileLocInstallJson.TabIndex = 3;
//
// radTextBox_RepoBranche
//
radTextBox_RepoBranche.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_RepoBranche.Location = new Point(3, 205);
radTextBox_RepoBranche.Name = "radTextBox_RepoBranche";
radTextBox_RepoBranche.Size = new Size(294, 24);
radTextBox_RepoBranche.TabIndex = 2;
//
// radSpinEditor_RepoId
//
radSpinEditor_RepoId.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radSpinEditor_RepoId.Location = new Point(3, 147);
radSpinEditor_RepoId.Maximum = new decimal(new int[] { -1, int.MaxValue, 0, 0 });
radSpinEditor_RepoId.Name = "radSpinEditor_RepoId";
radSpinEditor_RepoId.Size = new Size(294, 24);
radSpinEditor_RepoId.TabIndex = 6;
//
// radTextBox_ApiToken
//
radTextBox_ApiToken.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_ApiToken.Location = new Point(3, 89);
radTextBox_ApiToken.Name = "radTextBox_ApiToken";
radTextBox_ApiToken.Size = new Size(294, 24);
radTextBox_ApiToken.TabIndex = 1;
//
// radTextBox_InstanceUrl
//
radTextBox_InstanceUrl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_InstanceUrl.Location = new Point(3, 31);
radTextBox_InstanceUrl.Name = "radTextBox_InstanceUrl";
radTextBox_InstanceUrl.Size = new Size(294, 24);
radTextBox_InstanceUrl.TabIndex = 0;
//
// radLabel1
//
radLabel1.Location = new Point(3, 3);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(80, 22);
radLabel1.TabIndex = 7;
radLabel1.Text = "Instance url";
//
// radLabel2
//
radLabel2.Location = new Point(3, 61);
radLabel2.Name = "radLabel2";
radLabel2.Size = new Size(69, 22);
radLabel2.TabIndex = 8;
radLabel2.Text = "Api token";
//
// radLabel3
//
radLabel3.Location = new Point(3, 119);
radLabel3.Name = "radLabel3";
radLabel3.Size = new Size(91, 22);
radLabel3.TabIndex = 9;
radLabel3.Text = "Repository id";
//
// radLabel4
//
radLabel4.Location = new Point(3, 177);
radLabel4.Name = "radLabel4";
radLabel4.Size = new Size(130, 22);
radLabel4.TabIndex = 10;
radLabel4.Text = "Repository branche";
//
// radLabel5
//
radLabel5.Location = new Point(3, 235);
radLabel5.Name = "radLabel5";
radLabel5.Size = new Size(181, 22);
radLabel5.TabIndex = 11;
radLabel5.Text = "File location for install infos";
//
// radLabel6
//
radLabel6.Location = new Point(3, 293);
radLabel6.Name = "radLabel6";
radLabel6.Size = new Size(189, 22);
radLabel6.TabIndex = 12;
radLabel6.Text = "File location for updates info";
//
// radLabel7
//
radLabel7.Location = new Point(3, 351);
radLabel7.Name = "radLabel7";
radLabel7.Size = new Size(131, 22);
radLabel7.TabIndex = 13;
radLabel7.Text = "Modpack config url";
//
// radTextBox_ModpackConfigUrl
//
radTextBox_ModpackConfigUrl.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
radTextBox_ModpackConfigUrl.Location = new Point(3, 379);
radTextBox_ModpackConfigUrl.Name = "radTextBox_ModpackConfigUrl";
radTextBox_ModpackConfigUrl.Size = new Size(294, 24);
radTextBox_ModpackConfigUrl.TabIndex = 14;
//
// GitLabRepoWorkspaceConfigEditor
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
AutoSize = true;
AutoSizeMode = AutoSizeMode.GrowAndShrink;
BackColor = Color.Transparent;
Controls.Add(tableLayoutPanel1);
MinimumSize = new Size(300, 0);
Name = "GitLabRepoWorkspaceConfigEditor";
Size = new Size(300, 466);
Controls.SetChildIndex(tableLayoutPanel1, 0);
tableLayoutPanel1.ResumeLayout(false);
tableLayoutPanel1.PerformLayout();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocUpdateJson).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_FileLocInstallJson).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_RepoBranche).EndInit();
((System.ComponentModel.ISupportInitialize)radSpinEditor_RepoId).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ApiToken).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_InstanceUrl).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel2).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel3).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel4).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel5).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel6).EndInit();
((System.ComponentModel.ISupportInitialize)radLabel7).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBox_ModpackConfigUrl).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadTextBox radTextBox_InstanceUrl;
private Telerik.WinControls.UI.RadTextBox radTextBox_ApiToken;
private Telerik.WinControls.UI.RadTextBox radTextBox_RepoBranche;
private Telerik.WinControls.UI.RadTextBox radTextBox_FileLocInstallJson;
private Telerik.WinControls.UI.RadTextBox radTextBox_FileLocUpdateJson;
private Telerik.WinControls.UI.RadSpinEditor radSpinEditor_RepoId;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadLabel radLabel2;
private Telerik.WinControls.UI.RadLabel radLabel3;
private Telerik.WinControls.UI.RadLabel radLabel4;
private Telerik.WinControls.UI.RadLabel radLabel5;
private Telerik.WinControls.UI.RadLabel radLabel6;
private Telerik.WinControls.UI.RadLabel radLabel7;
private Telerik.WinControls.UI.RadTextBox radTextBox_ModpackConfigUrl;
}

View File

@@ -1,45 +0,0 @@
using Pilz.UI;
using Pilz.UI.WinForms.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal partial class GitLabRepoWorkspaceConfigEditor : RadFlyoutBase, ILoadContent
{
private readonly GitLabRepoWorkspaceConfig settings;
public GitLabRepoWorkspaceConfigEditor(GitLabRepoWorkspaceConfig settings)
{
this.settings = settings;
InitializeComponent();
var defaults = new GitLabRepoWorkspaceConfig();
radTextBox_InstanceUrl.NullText = defaults.InstanceUrl;
radTextBox_RepoBranche.NullText = defaults.RepoBranche;
radTextBox_FileLocInstallJson.NullText = defaults.InstanceUrl;
radTextBox_FileLocUpdateJson.NullText = defaults.FileLocationUpdateJson;
}
public void LoadContent()
{
radTextBox_InstanceUrl.Text = settings.InstanceUrl;
radTextBox_ApiToken.Text = settings.ApiToken;
radSpinEditor_RepoId.Value = settings.RepoId;
radTextBox_RepoBranche.Text = settings.RepoBranche;
radTextBox_FileLocInstallJson.Text = settings.FileLocationInstallJson;
radTextBox_FileLocUpdateJson.Text = settings.FileLocationUpdateJson;
radTextBox_ModpackConfigUrl.Text = settings.ModpackConfigUrl;
}
protected override bool ValidateOK()
{
settings.InstanceUrl = radTextBox_InstanceUrl.Text.Trim();
settings.ApiToken = radTextBox_ApiToken.Text.Trim();
settings.RepoId = (long)radSpinEditor_RepoId.Value;
settings.RepoBranche = radTextBox_RepoBranche.Text.Trim();
settings.FileLocationInstallJson = radTextBox_FileLocInstallJson.Text.Trim();
settings.FileLocationUpdateJson = radTextBox_FileLocUpdateJson.Text.Trim();
settings.ModpackConfigUrl = radTextBox_ModpackConfigUrl.Text.Trim();
return base.ValidateOK();
}
}

View File

@@ -0,0 +1,37 @@
<dialogs:AvaloniaFlyoutBase
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="https://git.pilzinsel64.de/pilz-framework/pilz"
xmlns:gitLabRepo="clr-namespace:ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo"
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
Width="300"
x:Class="ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo.GitLabRepoWorkspaceConfigEditorView"
x:DataType="gitLabRepo:GitLabRepoWorkspaceConfig">
<dialogs:AvaloniaFlyoutBase.MainContent>
<StackPanel Spacing="6">
<Label Target="TextBoxInstanceUrl" Content="{x:Static langRes:GeneralLangRes.GitLabInstanceUrl}"/>
<TextBox Name="TextBoxInstanceUrl" Text="{Binding InstanceUrl}"/>
<Label Target="TextBoxApiToken" Content="{x:Static langRes:GeneralLangRes.GitLabApiToken}"/>
<TextBox Name="TextBoxApiToken" Text="{Binding ApiToken}"/>
<Label Target="NumericUpDownRepoId" Content="{x:Static langRes:GeneralLangRes.RepositoryId}"/>
<NumericUpDown Name="NumericUpDownRepoId" Value="{Binding RepoId}"/>
<Label Target="TextBoxInstallJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfInstallJson}"/>
<TextBox Name="TextBoxInstallJson" Text="{Binding FileLocationInstallJson}"/>
<Label Target="TextBoxUpdateJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfUpdateJson}"/>
<TextBox Name="TextBoxUpdateJson" Text="{Binding FileLocationUpdateJson}"/>
<Label Target="TextBoxModpackConfigUrl" Content="{x:Static langRes:GeneralLangRes.ModpackConfigUrl}"/>
<TextBox Name="TextBoxModpackConfigUrl" Text="{Binding ModpackConfigUrl}"/>
</StackPanel>
</dialogs:AvaloniaFlyoutBase.MainContent>
</dialogs:AvaloniaFlyoutBase>

View File

@@ -0,0 +1,23 @@
using Avalonia;
using Avalonia.Controls;
using Avalonia.Markup.Xaml;
using Pilz.UI.AvaloniaUI.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
public partial class GitLabRepoWorkspaceConfigEditorView : AvaloniaFlyoutBase
{
public GitLabRepoWorkspaceConfig Settings { get; }
public GitLabRepoWorkspaceConfigEditorView(GitLabRepoWorkspaceConfig settings)
{
Settings = settings;
DataContext = settings;
InitializeComponent();
}
protected override object? GetResult()
{
return Settings;
}
}

View File

@@ -2,38 +2,36 @@
using ModpackUpdater.Apps.Manager.Api.Plugins.Features; using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes; using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features; using Pilz.Features;
using Pilz.UI.AvaloniaUI.Dialogs;
using Pilz.UI.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions;
using Pilz.UI.WinForms.Telerik.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo; namespace ModpackUpdater.Apps.Manager.Features.Workspaces.GitLabRepo;
internal class GitLabRepoWorkspaceFeature : WorkspaceFeature, IPluginFeatureProvider<GitLabRepoWorkspaceFeature> internal class GitLabRepoWorkspaceFeature() : WorkspaceFeature("origin.gitlab", FeatureNamesLangRes.GitLabWorkspace), IPluginFeatureProvider<GitLabRepoWorkspaceFeature>
{ {
public static GitLabRepoWorkspaceFeature Instance { get; } = new(); public static GitLabRepoWorkspaceFeature Instance { get; } = new();
public GitLabRepoWorkspaceFeature() : base("origin.gitlab", FeatureNamesLangRes.GitLabWorkspace) public override object? Icon => AppGlobals.Symbols.GetImage(AppSymbols.gitlab, SymbolSize.Small);
protected override async Task OnConfigure(WorkspaceContext context)
{ {
Icon = AppGlobals.Symbols.GetSvgImage(AppSymbols.gitlab, SymbolSize.Small); var settings = context.Workspace?.Config as GitLabRepoWorkspaceConfig ?? new();
}
protected override bool OnConfigure(ref IWorkspace? workspace) if ((await AvaloniaFlyoutBase.Show(
{ new GitLabRepoWorkspaceConfigEditorView((GitLabRepoWorkspaceConfig)settings.Clone()),
var settings = workspace?.Config as GitLabRepoWorkspaceConfig ?? new(); context.MainApi.MainWindow,
TitlesLangRes.GitLabRepoWorkspaceEditor,
if (RadDialogBase.ShowDialog(new GitLabRepoWorkspaceConfigEditor(settings), TitlesLangRes.GitLabRepoWorkspaceEditor, AppGlobals.Symbols.GetSvgImage(AppSymbols.gitlab, SymbolSize.Small)).Result.IsNotOk()) AppGlobals.Symbols.GetImageSource(AppSymbols.gitlab)))
return false; .Result is GitLabRepoWorkspaceConfig settingsNew)
context.Workspace = new GitLabRepoWorkspace(settingsNew);
workspace = new GitLabRepoWorkspace(settings); else
context.Canceled = true;
return true;
} }
protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config) protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config)
{ {
if (config is not GitLabRepoWorkspaceConfig gitlabConfig) if (config is not GitLabRepoWorkspaceConfig gitlabConfig)
throw new NotImplementedException($"Only configs of type {typeof(GitLabRepoWorkspaceConfig).Name} are allowed."); throw new NotSupportedException($"Only configs of type {nameof(GitLabRepoWorkspaceConfig)} are allowed.");
workspace = new GitLabRepoWorkspace(gitlabConfig); workspace = new GitLabRepoWorkspace(gitlabConfig);
} }
} }

View File

@@ -0,0 +1,85 @@
using ModpackUpdater.Apps.Manager.Api.Model;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
internal class LocalFolderWorkspace(LocalFolderWorkspaceConfig config) : IWorkspace
{
private string? rawInstallInfos;
private string? rawUpdateInfos;
public WorkspaceConfig Config => ConfigX;
public LocalFolderWorkspaceConfig ConfigX { get; } = config;
public ModpackConfig? ModpackConfig { get; private set; }
public InstallInfos? InstallInfos { get; private set; }
public UpdateInfos? UpdateInfos { get; private set; }
public async Task<bool> Load()
{
if (!string.IsNullOrWhiteSpace(Config.ModpackConfigUrl))
ModpackConfig = ModpackConfig.LoadFromUrl(Config.ModpackConfigUrl);
rawInstallInfos = await GetContent(ConfigX.FileLocationInstallJson);
InstallInfos = InstallInfos.Parse(rawInstallInfos);
rawUpdateInfos = await GetContent(ConfigX.FileLocationUpdateJson);
UpdateInfos = UpdateInfos.Parse(rawUpdateInfos);
if (string.IsNullOrWhiteSpace(ConfigX.FolderName))
ConfigX.FolderName = Path.GetFileName(ConfigX.RootFolderPath);
return InstallInfos != null && UpdateInfos != null;
}
public async Task<bool> Save()
{
var failed = false;
if (InstallInfos != null)
{
var newInstallInfos = InstallInfos.ToString();
if (newInstallInfos != rawInstallInfos)
{
if (await SaveContent(ConfigX.FileLocationInstallJson, newInstallInfos))
rawInstallInfos = newInstallInfos;
else
failed = true;
}
}
if (UpdateInfos != null)
{
var newUpdateInfos = UpdateInfos.ToString();
if (newUpdateInfos != rawUpdateInfos)
{
if (await SaveContent(ConfigX.FileLocationUpdateJson, newUpdateInfos))
rawUpdateInfos = newUpdateInfos;
else
failed = true;
}
}
return !failed;
}
private async Task<string?> GetContent(string path)
{
if (ConfigX.RootFolderPath == null)
return null;
var filePath = Path.Combine(ConfigX.RootFolderPath!, path);
return File.Exists(filePath) ? await File.ReadAllTextAsync(filePath) : null;
}
private async Task<bool> SaveContent(string path, string content)
{
if (ConfigX.RootFolderPath == null)
return false;
var filePath = Path.Combine(ConfigX.RootFolderPath!, path);
if (!File.Exists(filePath))
return false;
await File.WriteAllTextAsync(filePath, content);
return true;
}
}

View File

@@ -0,0 +1,17 @@
using ModpackUpdater.Apps.Manager.Api.Model;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
public class LocalFolderWorkspaceConfig : WorkspaceConfig, ICloneable
{
public override string DisplayText => FolderName ?? string.Empty;
public string? FolderName { get; set; }
public string? RootFolderPath { get; set; }
public string FileLocationInstallJson { get; set; } = "install.json";
public string FileLocationUpdateJson { get; set; } = "updates.json";
public object Clone()
{
return MemberwiseClone();
}
}

View File

@@ -0,0 +1,50 @@
<dialogs:AvaloniaFlyoutBase
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="https://git.pilzinsel64.de/pilz-framework/pilz"
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
xmlns:localFolder="clr-namespace:ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder"
mc:Ignorable="d"
d:DesignWidth="800"
d:DesignHeight="450"
Width="300"
x:Class="ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder.LocalFolderWorkspaceConfigEditorView"
x:DataType="localFolder:LocalFolderWorkspaceConfig">
<dialogs:AvaloniaFlyoutBase.MainContent>
<StackPanel Spacing="6">
<Label Target="TextBoxName" Content="{x:Static langRes:GeneralLangRes.Name}"/>
<TextBox Name="TextBoxName" Text="{Binding FolderName}"/>
<Label Target="TextBoxRootFolderPath" Content="{x:Static langRes:GeneralLangRes.RootFolderPath}"/>
<Grid
ColumnDefinitions="*,Auto"
ColumnSpacing="6">
<TextBox
Grid.Column="0"
x:Name="TextBoxRootFolderPath"
Text="{Binding RootFolderPath}"/>
<dialogs:ImageButton
Grid.Column="1"
x:Name="ButtonSearch"
VerticalAlignment="Stretch"
HorizontalAlignment="Right"
Text="{x:Static langRes:GeneralLangRes.Select}"
Click="ButtonSearch_OnClick"/>
</Grid>
<Label Target="TextBoxInstallJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfInstallJson}"/>
<TextBox Name="TextBoxInstallJson" Text="{Binding FileLocationInstallJson}"/>
<Label Target="TextBoxUpdateJson" Content="{x:Static langRes:GeneralLangRes.FileLocationOfUpdateJson}"/>
<TextBox Name="TextBoxUpdateJson" Text="{Binding FileLocationUpdateJson}"/>
<Label Target="TextBoxModpackConfigUrl" Content="{x:Static langRes:GeneralLangRes.ModpackConfigUrl}"/>
<TextBox Name="TextBoxModpackConfigUrl" Text="{Binding ModpackConfigUrl}"/>
</StackPanel>
</dialogs:AvaloniaFlyoutBase.MainContent>
</dialogs:AvaloniaFlyoutBase>

View File

@@ -0,0 +1,49 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.UI.AvaloniaUI.Dialogs;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
public partial class LocalFolderWorkspaceConfigEditorView : AvaloniaFlyoutBase
{
public LocalFolderWorkspaceConfig Settings { get; }
public LocalFolderWorkspaceConfigEditorView() : this(new())
{
}
public LocalFolderWorkspaceConfigEditorView(LocalFolderWorkspaceConfig settings)
{
Settings = settings;
DataContext = settings;
InitializeComponent();
ButtonSearch.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.opened_folder);
}
protected override object? GetResult()
{
return Settings;
}
private async void ButtonSearch_OnClick(object? sender, RoutedEventArgs e)
{
if (TopLevel.GetTopLevel(this) is not { } topLevel)
return;
var filePaths = await topLevel.StorageProvider.OpenFolderPickerAsync(new FolderPickerOpenOptions
{
Title = GeneralLangRes.SelectRootFolder,
AllowMultiple = false,
});
if (filePaths.Count < 1)
return;
TextBoxRootFolderPath.Text = filePaths[0].Path.AbsolutePath;
if (string.IsNullOrWhiteSpace(TextBoxName.Text))
TextBoxName.Text = filePaths[0].Name;
}
}

View File

@@ -0,0 +1,37 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.LangRes;
using Pilz.Features;
using Pilz.UI.AvaloniaUI.Dialogs;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Features.Workspaces.LocalFolder;
internal class LocalFolderWorkspaceFeature() : WorkspaceFeature("origin.localfolder", FeatureNamesLangRes.LocalFolderWorkspace), IPluginFeatureProvider<LocalFolderWorkspaceFeature>
{
public static LocalFolderWorkspaceFeature Instance { get; } = new();
public override object? Icon => AppGlobals.Symbols.GetImage(AppSymbols.opened_folder, SymbolSize.Small);
protected override async Task OnConfigure(WorkspaceContext context)
{
var settings = context.Workspace?.Config as LocalFolderWorkspaceConfig ?? new();
if ((await AvaloniaFlyoutBase.Show(
new LocalFolderWorkspaceConfigEditorView((LocalFolderWorkspaceConfig)settings.Clone()),
context.MainApi.MainWindow,
TitlesLangRes.LocalFolderWorkspaceEditor,
AppGlobals.Symbols.GetImageSource(AppSymbols.gitlab)))
.Result is LocalFolderWorkspaceConfig settingsNew)
context.Workspace = new LocalFolderWorkspace(settingsNew);
else
context.Canceled = true;
}
protected override void OnCreate(out IWorkspace workspace, WorkspaceConfig config)
{
if (config is not LocalFolderWorkspaceConfig gitlabConfig)
throw new NotSupportedException($"Only configs of type {nameof(LocalFolderWorkspaceConfig)} are allowed.");
workspace = new LocalFolderWorkspace(gitlabConfig);
}
}

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<Weavers xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="FodyWeavers.xsd">
<PropertyChanged />
</Weavers>

View File

@@ -0,0 +1,74 @@
<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<!-- This file was generated by Fody. Manual changes to this file will be lost when your project is rebuilt. -->
<xs:element name="Weavers">
<xs:complexType>
<xs:all>
<xs:element name="PropertyChanged" minOccurs="0" maxOccurs="1">
<xs:complexType>
<xs:attribute name="InjectOnPropertyNameChanged" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the On_PropertyName_Changed feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="TriggerDependentProperties" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the Dependent properties feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EnableIsChangedProperty" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if the IsChanged property feature is enabled.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="EventInvokerNames" type="xs:string">
<xs:annotation>
<xs:documentation>Used to change the name of the method that fires the notify event. This is a string that accepts multiple values in a comma separated form.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEquality" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should be inserted. If false, equality checking will be disabled for the project.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="CheckForEqualityUsingBaseEquals" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="UseStaticEqualsFromBase" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to control if equality checks should use the static Equals method resolved from the base class.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressWarnings" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings from this weaver.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="SuppressOnPropertyNameChangedWarning" type="xs:boolean">
<xs:annotation>
<xs:documentation>Used to turn off build warnings about mismatched On_PropertyName_Changed methods.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:all>
<xs:attribute name="VerifyAssembly" type="xs:boolean">
<xs:annotation>
<xs:documentation>'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="VerifyIgnoreCodes" type="xs:string">
<xs:annotation>
<xs:documentation>A comma-separated list of error codes that can be safely ignored in assembly verification.</xs:documentation>
</xs:annotation>
</xs:attribute>
<xs:attribute name="GenerateXsd" type="xs:boolean">
<xs:annotation>
<xs:documentation>'false' to turn off automatic generation of the XML Schema file.</xs:documentation>
</xs:annotation>
</xs:attribute>
</xs:complexType>
</xs:element>
</xs:schema>

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class ActionsListLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class ActionsListLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal ActionsListLangRes() { internal ActionsListLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.ActionsListLangRes", typeof(ActionsListLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.ActionsListLangRes", typeof(ActionsListLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,163 +45,109 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string Col_DestPath {
/// Sucht eine lokalisierte Zeichenfolge, die Destination path ähnelt.
/// </summary>
internal static string Col_DestPath {
get { get {
return ResourceManager.GetString("Col_DestPath", resourceCulture); return ResourceManager.GetString("Col_DestPath", resourceCulture);
} }
} }
/// <summary> public static string Col_Id {
/// Sucht eine lokalisierte Zeichenfolge, die Id ähnelt.
/// </summary>
internal static string Col_Id {
get { get {
return ResourceManager.GetString("Col_Id", resourceCulture); return ResourceManager.GetString("Col_Id", resourceCulture);
} }
} }
/// <summary> public static string Col_InheritFrom {
/// Sucht eine lokalisierte Zeichenfolge, die Inherit from ähnelt.
/// </summary>
internal static string Col_InheritFrom {
get { get {
return ResourceManager.GetString("Col_InheritFrom", resourceCulture); return ResourceManager.GetString("Col_InheritFrom", resourceCulture);
} }
} }
/// <summary> public static string Col_IsDir {
/// Sucht eine lokalisierte Zeichenfolge, die Is directory ähnelt.
/// </summary>
internal static string Col_IsDir {
get { get {
return ResourceManager.GetString("Col_IsDir", resourceCulture); return ResourceManager.GetString("Col_IsDir", resourceCulture);
} }
} }
/// <summary> public static string Col_IsExtra {
/// Sucht eine lokalisierte Zeichenfolge, die Is Extra ähnelt.
/// </summary>
internal static string Col_IsExtra {
get { get {
return ResourceManager.GetString("Col_IsExtra", resourceCulture); return ResourceManager.GetString("Col_IsExtra", resourceCulture);
} }
} }
/// <summary> public static string Col_IsZip {
/// Sucht eine lokalisierte Zeichenfolge, die Is ZIP ähnelt.
/// </summary>
internal static string Col_IsZip {
get { get {
return ResourceManager.GetString("Col_IsZip", resourceCulture); return ResourceManager.GetString("Col_IsZip", resourceCulture);
} }
} }
/// <summary> public static string Col_Name {
/// Sucht eine lokalisierte Zeichenfolge, die Name ähnelt.
/// </summary>
internal static string Col_Name {
get { get {
return ResourceManager.GetString("Col_Name", resourceCulture); return ResourceManager.GetString("Col_Name", resourceCulture);
} }
} }
/// <summary> public static string Col_Side {
/// Sucht eine lokalisierte Zeichenfolge, die Side ähnelt.
/// </summary>
internal static string Col_Side {
get { get {
return ResourceManager.GetString("Col_Side", resourceCulture); return ResourceManager.GetString("Col_Side", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcName {
/// Sucht eine lokalisierte Zeichenfolge, die Source name ähnelt.
/// </summary>
internal static string Col_SrcName {
get { get {
return ResourceManager.GetString("Col_SrcName", resourceCulture); return ResourceManager.GetString("Col_SrcName", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcOwner {
/// Sucht eine lokalisierte Zeichenfolge, die Source owner ähnelt.
/// </summary>
internal static string Col_SrcOwner {
get { get {
return ResourceManager.GetString("Col_SrcOwner", resourceCulture); return ResourceManager.GetString("Col_SrcOwner", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcPath {
/// Sucht eine lokalisierte Zeichenfolge, die Source path ähnelt.
/// </summary>
internal static string Col_SrcPath {
get { get {
return ResourceManager.GetString("Col_SrcPath", resourceCulture); return ResourceManager.GetString("Col_SrcPath", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcRegEx {
/// Sucht eine lokalisierte Zeichenfolge, die Source RegEx ähnelt.
/// </summary>
internal static string Col_SrcRegEx {
get { get {
return ResourceManager.GetString("Col_SrcRegEx", resourceCulture); return ResourceManager.GetString("Col_SrcRegEx", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcTag {
/// Sucht eine lokalisierte Zeichenfolge, die Source tag ähnelt.
/// </summary>
internal static string Col_SrcTag {
get { get {
return ResourceManager.GetString("Col_SrcTag", resourceCulture); return ResourceManager.GetString("Col_SrcTag", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcType {
/// Sucht eine lokalisierte Zeichenfolge, die Source type ähnelt.
/// </summary>
internal static string Col_SrcType {
get { get {
return ResourceManager.GetString("Col_SrcType", resourceCulture); return ResourceManager.GetString("Col_SrcType", resourceCulture);
} }
} }
/// <summary> public static string Col_SrcUrl {
/// Sucht eine lokalisierte Zeichenfolge, die Source URL ähnelt.
/// </summary>
internal static string Col_SrcUrl {
get { get {
return ResourceManager.GetString("Col_SrcUrl", resourceCulture); return ResourceManager.GetString("Col_SrcUrl", resourceCulture);
} }
} }
/// <summary> public static string Col_UpdateType {
/// Sucht eine lokalisierte Zeichenfolge, die Update type ähnelt.
/// </summary>
internal static string Col_UpdateType {
get { get {
return ResourceManager.GetString("Col_UpdateType", resourceCulture); return ResourceManager.GetString("Col_UpdateType", resourceCulture);
} }
} }
/// <summary> public static string Col_Website {
/// Sucht eine lokalisierte Zeichenfolge, die Website ähnelt.
/// </summary>
internal static string Col_Website {
get { get {
return ResourceManager.GetString("Col_Website", resourceCulture); return ResourceManager.GetString("Col_Website", resourceCulture);
} }
} }
/// <summary> public static string Col_ZipPath {
/// Sucht eine lokalisierte Zeichenfolge, die ZIP archive path ähnelt.
/// </summary>
internal static string Col_ZipPath {
get { get {
return ResourceManager.GetString("Col_ZipPath", resourceCulture); return ResourceManager.GetString("Col_ZipPath", resourceCulture);
} }

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class FeatureNamesLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class FeatureNamesLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal FeatureNamesLangRes() { internal FeatureNamesLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.FeatureNamesLangRes", typeof(FeatureNamesLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.FeatureNamesLangRes", typeof(FeatureNamesLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,109 +45,79 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string CheckAllActionsHealthy {
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckAllActionsHealthy {
get { get {
return ResourceManager.GetString("CheckAllActionsHealthy", resourceCulture); return ResourceManager.GetString("CheckAllActionsHealthy", resourceCulture);
} }
} }
/// <summary> public static string CheckSingleActionHealthy {
/// Sucht eine lokalisierte Zeichenfolge, die Check healthy ähnelt.
/// </summary>
internal static string CheckSingleActionHealthy {
get { get {
return ResourceManager.GetString("CheckSingleActionHealthy", resourceCulture); return ResourceManager.GetString("CheckSingleActionHealthy", resourceCulture);
} }
} }
/// <summary> public static string ClearDirectLinkFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct link ähnelt.
/// </summary>
internal static string ClearDirectLinkFeature {
get { get {
return ResourceManager.GetString("ClearDirectLinkFeature", resourceCulture); return ResourceManager.GetString("ClearDirectLinkFeature", resourceCulture);
} }
} }
/// <summary> public static string ClearDirectLinksFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Clear direct links ähnelt.
/// </summary>
internal static string ClearDirectLinksFeature {
get { get {
return ResourceManager.GetString("ClearDirectLinksFeature", resourceCulture); return ResourceManager.GetString("ClearDirectLinksFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateChangelogFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate changelog ähnelt.
/// </summary>
internal static string GenerateChangelogFeature {
get { get {
return ResourceManager.GetString("GenerateChangelogFeature", resourceCulture); return ResourceManager.GetString("GenerateChangelogFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateModlistAsExcelFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist excel file ähnelt.
/// </summary>
internal static string GenerateModlistAsExcelFeature {
get { get {
return ResourceManager.GetString("GenerateModlistAsExcelFeature", resourceCulture); return ResourceManager.GetString("GenerateModlistAsExcelFeature", resourceCulture);
} }
} }
/// <summary> public static string GenerateModlistAsMarkdownFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Generate modlist markdown table ähnelt.
/// </summary>
internal static string GenerateModlistAsMarkdownFeature {
get { get {
return ResourceManager.GetString("GenerateModlistAsMarkdownFeature", resourceCulture); return ResourceManager.GetString("GenerateModlistAsMarkdownFeature", resourceCulture);
} }
} }
/// <summary> public static string GitLabWorkspace {
/// Sucht eine lokalisierte Zeichenfolge, die GitLab workspace ähnelt.
/// </summary>
internal static string GitLabWorkspace {
get { get {
return ResourceManager.GetString("GitLabWorkspace", resourceCulture); return ResourceManager.GetString("GitLabWorkspace", resourceCulture);
} }
} }
/// <summary> public static string LocalFolderWorkspace {
/// Sucht eine lokalisierte Zeichenfolge, die Find update ähnelt. get {
/// </summary> return ResourceManager.GetString("LocalFolderWorkspace", resourceCulture);
internal static string UpdateCollectorFeature { }
}
public static string UpdateCollectorFeature {
get { get {
return ResourceManager.GetString("UpdateCollectorFeature", resourceCulture); return ResourceManager.GetString("UpdateCollectorFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdateDirectLinkFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Update direct link ähnelt.
/// </summary>
internal static string UpdateDirectLinkFeature {
get { get {
return ResourceManager.GetString("UpdateDirectLinkFeature", resourceCulture); return ResourceManager.GetString("UpdateDirectLinkFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdateDirectLinksFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Update direct links ähnelt.
/// </summary>
internal static string UpdateDirectLinksFeature {
get { get {
return ResourceManager.GetString("UpdateDirectLinksFeature", resourceCulture); return ResourceManager.GetString("UpdateDirectLinksFeature", resourceCulture);
} }
} }
/// <summary> public static string UpdatesCollectorFeature {
/// Sucht eine lokalisierte Zeichenfolge, die Find updates ähnelt.
/// </summary>
internal static string UpdatesCollectorFeature {
get { get {
return ResourceManager.GetString("UpdatesCollectorFeature", resourceCulture); return ResourceManager.GetString("UpdatesCollectorFeature", resourceCulture);
} }

View File

@@ -139,7 +139,10 @@
<value>Generate modlist markdown table</value> <value>Generate modlist markdown table</value>
</data> </data>
<data name="GitLabWorkspace" xml:space="preserve"> <data name="GitLabWorkspace" xml:space="preserve">
<value>GitLab workspace</value> <value>GitLab</value>
</data>
<data name="LocalFolderWorkspace" xml:space="preserve">
<value>Local folder</value>
</data> </data>
<data name="UpdateCollectorFeature" xml:space="preserve"> <data name="UpdateCollectorFeature" xml:space="preserve">
<value>Find update</value> <value>Find update</value>

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class GeneralLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class GeneralLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal GeneralLangRes() { internal GeneralLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.GeneralLangRes", typeof(GeneralLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,30 +45,273 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string ModlistForVersionX {
/// Sucht eine lokalisierte Zeichenfolge, die Installation: {0} ähnelt.
/// </summary>
internal static string Node_Install {
get { get {
return ResourceManager.GetString("Node_Install", resourceCulture); return ResourceManager.GetString("ModlistForVersionX", resourceCulture);
} }
} }
/// <summary> public static string GitLabInstanceUrl {
/// Sucht eine lokalisierte Zeichenfolge, die Update: {0} ähnelt.
/// </summary>
internal static string Node_Update {
get { get {
return ResourceManager.GetString("Node_Update", resourceCulture); return ResourceManager.GetString("GitLabInstanceUrl", resourceCulture);
} }
} }
/// <summary> public static string GitLabApiToken {
/// Sucht eine lokalisierte Zeichenfolge, die Modlist for v{0} ähnelt.
/// </summary>
internal static string Text_ModlistForVersion {
get { get {
return ResourceManager.GetString("Text_ModlistForVersion", resourceCulture); return ResourceManager.GetString("GitLabApiToken", resourceCulture);
}
}
public static string RepositoryId {
get {
return ResourceManager.GetString("RepositoryId", resourceCulture);
}
}
public static string RootFolderPath {
get {
return ResourceManager.GetString("RootFolderPath", resourceCulture);
}
}
public static string FileLocationOfInstallJson {
get {
return ResourceManager.GetString("FileLocationOfInstallJson", resourceCulture);
}
}
public static string FileLocationOfUpdateJson {
get {
return ResourceManager.GetString("FileLocationOfUpdateJson", resourceCulture);
}
}
public static string ModpackConfigUrl {
get {
return ResourceManager.GetString("ModpackConfigUrl", resourceCulture);
}
}
public static string Remove {
get {
return ResourceManager.GetString("Remove", resourceCulture);
}
}
public static string WorkspacePreferences {
get {
return ResourceManager.GetString("WorkspacePreferences", resourceCulture);
}
}
public static string SaveWorkspace {
get {
return ResourceManager.GetString("SaveWorkspace", resourceCulture);
}
}
public static string NewWorkspace {
get {
return ResourceManager.GetString("NewWorkspace", resourceCulture);
}
}
public static string RecentWorkspaces {
get {
return ResourceManager.GetString("RecentWorkspaces", resourceCulture);
}
}
public static string Workspace {
get {
return ResourceManager.GetString("Workspace", resourceCulture);
}
}
public static string CreateUpdate {
get {
return ResourceManager.GetString("CreateUpdate", resourceCulture);
}
}
public static string RemoveUpdate {
get {
return ResourceManager.GetString("RemoveUpdate", resourceCulture);
}
}
public static string Update {
get {
return ResourceManager.GetString("Update", resourceCulture);
}
}
public static string Tools {
get {
return ResourceManager.GetString("Tools", resourceCulture);
}
}
public static string Updates {
get {
return ResourceManager.GetString("Updates", resourceCulture);
}
}
public static string Add {
get {
return ResourceManager.GetString("Add", resourceCulture);
}
}
public static string Public {
get {
return ResourceManager.GetString("Public", resourceCulture);
}
}
public static string Id {
get {
return ResourceManager.GetString("Id", resourceCulture);
}
}
public static string Side {
get {
return ResourceManager.GetString("Side", resourceCulture);
}
}
public static string UpdateType {
get {
return ResourceManager.GetString("UpdateType", resourceCulture);
}
}
public static string SourceType {
get {
return ResourceManager.GetString("SourceType", resourceCulture);
}
}
public static string DestinationPath {
get {
return ResourceManager.GetString("DestinationPath", resourceCulture);
}
}
public static string State {
get {
return ResourceManager.GetString("State", resourceCulture);
}
}
public static string InheritFrom {
get {
return ResourceManager.GetString("InheritFrom", resourceCulture);
}
}
public static string SourcePath {
get {
return ResourceManager.GetString("SourcePath", resourceCulture);
}
}
public static string IsDirectory {
get {
return ResourceManager.GetString("IsDirectory", resourceCulture);
}
}
public static string General {
get {
return ResourceManager.GetString("General", resourceCulture);
}
}
public static string Name {
get {
return ResourceManager.GetString("Name", resourceCulture);
}
}
public static string IsExtra {
get {
return ResourceManager.GetString("IsExtra", resourceCulture);
}
}
public static string Destination {
get {
return ResourceManager.GetString("Destination", resourceCulture);
}
}
public static string Source {
get {
return ResourceManager.GetString("Source", resourceCulture);
}
}
public static string IsZipArchive {
get {
return ResourceManager.GetString("IsZipArchive", resourceCulture);
}
}
public static string SourceOwner {
get {
return ResourceManager.GetString("SourceOwner", resourceCulture);
}
}
public static string SourceName {
get {
return ResourceManager.GetString("SourceName", resourceCulture);
}
}
public static string SourceRegex {
get {
return ResourceManager.GetString("SourceRegex", resourceCulture);
}
}
public static string SourceUrl {
get {
return ResourceManager.GetString("SourceUrl", resourceCulture);
}
}
public static string ZipArchivePath {
get {
return ResourceManager.GetString("ZipArchivePath", resourceCulture);
}
}
public static string Metadata {
get {
return ResourceManager.GetString("Metadata", resourceCulture);
}
}
public static string Website {
get {
return ResourceManager.GetString("Website", resourceCulture);
}
}
public static string Select {
get {
return ResourceManager.GetString("Select", resourceCulture);
}
}
public static string SelectRootFolder {
get {
return ResourceManager.GetString("SelectRootFolder", resourceCulture);
} }
} }
} }

View File

@@ -117,13 +117,139 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="Node_Install" xml:space="preserve"> <data name="ModlistForVersionX" xml:space="preserve">
<value>Installation: {0}</value>
</data>
<data name="Node_Update" xml:space="preserve">
<value>Update: {0}</value>
</data>
<data name="Text_ModlistForVersion" xml:space="preserve">
<value>Modlist for v{0}</value> <value>Modlist for v{0}</value>
</data> </data>
<data name="GitLabInstanceUrl" xml:space="preserve">
<value>GitLab instance url</value>
</data>
<data name="GitLabApiToken" xml:space="preserve">
<value>GitLab Api token</value>
</data>
<data name="RepositoryId" xml:space="preserve">
<value>Repository Id</value>
</data>
<data name="RootFolderPath" xml:space="preserve">
<value>Root folder path</value>
</data>
<data name="FileLocationOfInstallJson" xml:space="preserve">
<value>File location of "install.json"</value>
</data>
<data name="FileLocationOfUpdateJson" xml:space="preserve">
<value>File location of "update.json"</value>
</data>
<data name="ModpackConfigUrl" xml:space="preserve">
<value>Modpack config url</value>
</data>
<data name="Remove" xml:space="preserve">
<value>Remove</value>
</data>
<data name="WorkspacePreferences" xml:space="preserve">
<value>Workspace preferences</value>
</data>
<data name="SaveWorkspace" xml:space="preserve">
<value>Save workspace</value>
</data>
<data name="NewWorkspace" xml:space="preserve">
<value>New workspace</value>
</data>
<data name="RecentWorkspaces" xml:space="preserve">
<value>Recent workspace</value>
</data>
<data name="Workspace" xml:space="preserve">
<value>Workspace</value>
</data>
<data name="CreateUpdate" xml:space="preserve">
<value>Create update</value>
</data>
<data name="RemoveUpdate" xml:space="preserve">
<value>Remove update</value>
</data>
<data name="Update" xml:space="preserve">
<value>Update</value>
</data>
<data name="Tools" xml:space="preserve">
<value>Tools</value>
</data>
<data name="Updates" xml:space="preserve">
<value>Updates</value>
</data>
<data name="Add" xml:space="preserve">
<value>Add</value>
</data>
<data name="Public" xml:space="preserve">
<value>Public</value>
</data>
<data name="Id" xml:space="preserve">
<value>Id</value>
</data>
<data name="Side" xml:space="preserve">
<value>Side</value>
</data>
<data name="UpdateType" xml:space="preserve">
<value>Update type</value>
</data>
<data name="SourceType" xml:space="preserve">
<value>Source type</value>
</data>
<data name="DestinationPath" xml:space="preserve">
<value>Destination path</value>
</data>
<data name="State" xml:space="preserve">
<value>State</value>
</data>
<data name="InheritFrom" xml:space="preserve">
<value>Inherit from</value>
</data>
<data name="SourcePath" xml:space="preserve">
<value>Source path</value>
</data>
<data name="IsDirectory" xml:space="preserve">
<value>Is directory</value>
</data>
<data name="General" xml:space="preserve">
<value>General</value>
</data>
<data name="Name" xml:space="preserve">
<value>Name</value>
</data>
<data name="IsExtra" xml:space="preserve">
<value>Is extra</value>
</data>
<data name="Destination" xml:space="preserve">
<value>Destination</value>
</data>
<data name="Source" xml:space="preserve">
<value>Source</value>
</data>
<data name="IsZipArchive" xml:space="preserve">
<value>Is Zip archive</value>
</data>
<data name="SourceOwner" xml:space="preserve">
<value>Source owner</value>
</data>
<data name="SourceName" xml:space="preserve">
<value>Source name</value>
</data>
<data name="SourceRegex" xml:space="preserve">
<value>Source RegEx</value>
</data>
<data name="SourceUrl" xml:space="preserve">
<value>Source URL</value>
</data>
<data name="ZipArchivePath" xml:space="preserve">
<value>ZIP archive path</value>
</data>
<data name="Metadata" xml:space="preserve">
<value>Metadata</value>
</data>
<data name="Website" xml:space="preserve">
<value>Website</value>
</data>
<data name="Select" xml:space="preserve">
<value>Select</value>
</data>
<data name="SelectRootFolder" xml:space="preserve">
<value>Select root folder</value>
</data>
</root> </root>

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class MsgBoxLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class MsgBoxLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal MsgBoxLangRes() { internal MsgBoxLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.MsgBoxLangRes", typeof(MsgBoxLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,76 +45,64 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string ChangelogCopiedToClipboard {
/// Sucht eine lokalisierte Zeichenfolge, die The changelog for the selected version has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard {
get { get {
return ResourceManager.GetString("ChangelogCopiedToClipboard", resourceCulture); return ResourceManager.GetString("ChangelogCopiedToClipboard", resourceCulture);
} }
} }
/// <summary> public static string ChangelogCopiedToClipboard_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Changelog generated successfully ähnelt.
/// </summary>
internal static string ChangelogCopiedToClipboard_Title {
get { get {
return ResourceManager.GetString("ChangelogCopiedToClipboard_Title", resourceCulture); return ResourceManager.GetString("ChangelogCopiedToClipboard_Title", resourceCulture);
} }
} }
/// <summary> public static string ModlistCopiedToClipboard {
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated and copied to the clipboard. ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard {
get { get {
return ResourceManager.GetString("ModlistCopiedToClipboard", resourceCulture); return ResourceManager.GetString("ModlistCopiedToClipboard", resourceCulture);
} }
} }
/// <summary> public static string ModlistCopiedToClipboard_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistCopiedToClipboard_Title {
get { get {
return ResourceManager.GetString("ModlistCopiedToClipboard_Title", resourceCulture); return ResourceManager.GetString("ModlistCopiedToClipboard_Title", resourceCulture);
} }
} }
/// <summary> public static string ModlistGenerated {
/// Sucht eine lokalisierte Zeichenfolge, die The modlist has been generated successfully and saved to the selected location. ähnelt.
/// </summary>
internal static string ModlistGenerated {
get { get {
return ResourceManager.GetString("ModlistGenerated", resourceCulture); return ResourceManager.GetString("ModlistGenerated", resourceCulture);
} }
} }
/// <summary> public static string ModlistGenerated_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Modlist generated successfully ähnelt.
/// </summary>
internal static string ModlistGenerated_Title {
get { get {
return ResourceManager.GetString("ModlistGenerated_Title", resourceCulture); return ResourceManager.GetString("ModlistGenerated_Title", resourceCulture);
} }
} }
/// <summary> public static string RemoveUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Are you sure that you want to delete this update? ähnelt.
/// </summary>
internal static string RemoveUpdate {
get { get {
return ResourceManager.GetString("RemoveUpdate", resourceCulture); return ResourceManager.GetString("RemoveUpdate", resourceCulture);
} }
} }
/// <summary> public static string RemoveUpdate_Title {
/// Sucht eine lokalisierte Zeichenfolge, die Remove update ähnelt.
/// </summary>
internal static string RemoveUpdate_Title {
get { get {
return ResourceManager.GetString("RemoveUpdate_Title", resourceCulture); return ResourceManager.GetString("RemoveUpdate_Title", resourceCulture);
} }
} }
public static string UpdateAvailable {
get {
return ResourceManager.GetString("UpdateAvailable", resourceCulture);
}
}
public static string UpdateAvailable_Title {
get {
return ResourceManager.GetString("UpdateAvailable_Title", resourceCulture);
}
}
} }
} }

View File

@@ -141,4 +141,11 @@
<data name="RemoveUpdate_Title" xml:space="preserve"> <data name="RemoveUpdate_Title" xml:space="preserve">
<value>Remove update</value> <value>Remove update</value>
</data> </data>
<data name="UpdateAvailable" xml:space="preserve">
<value>A new version of this program is available! Install now?
If you confirm, the update will be installed automatically within a few seconds.</value>
</data>
<data name="UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
</root> </root>

View File

@@ -0,0 +1,66 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SideLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal SideLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.SideLangRes", typeof(SideLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
internal static string Client {
get {
return ResourceManager.GetString("Client", resourceCulture);
}
}
internal static string Server {
get {
return ResourceManager.GetString("Server", resourceCulture);
}
}
internal static string Both {
get {
return ResourceManager.GetString("Both", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="Client" xml:space="preserve">
<value>Client</value>
</data>
<data name="Server" xml:space="preserve">
<value>Server</value>
</data>
<data name="Both" xml:space="preserve">
<value>Both</value>
</data>
</root>

View File

@@ -0,0 +1,78 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class SourceTypeLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal SourceTypeLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.SourceTypeLangRes", typeof(SourceTypeLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
internal static string DirectLink {
get {
return ResourceManager.GetString("DirectLink", resourceCulture);
}
}
internal static string GitHub {
get {
return ResourceManager.GetString("GitHub", resourceCulture);
}
}
internal static string GitLab {
get {
return ResourceManager.GetString("GitLab", resourceCulture);
}
}
internal static string CurseForge {
get {
return ResourceManager.GetString("CurseForge", resourceCulture);
}
}
internal static string Modrinth {
get {
return ResourceManager.GetString("Modrinth", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="DirectLink" xml:space="preserve">
<value>Direct link</value>
</data>
<data name="GitHub" xml:space="preserve">
<value>GitHub</value>
</data>
<data name="GitLab" xml:space="preserve">
<value>GitLab</value>
</data>
<data name="CurseForge" xml:space="preserve">
<value>CurseForge</value>
</data>
<data name="Modrinth" xml:space="preserve">
<value>Modrinth</value>
</data>
</root>

View File

@@ -1,10 +1,9 @@
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// <auto-generated> // <auto-generated>
// Dieser Code wurde von einem Tool generiert. // This code was generated by a tool.
// Laufzeitversion:4.0.30319.42000
// //
// Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn // Changes to this file may cause incorrect behavior and will be lost if
// der Code erneut generiert wird. // the code is regenerated.
// </auto-generated> // </auto-generated>
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@@ -12,46 +11,32 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
using System; using System;
/// <summary> [System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
/// Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw. [System.Diagnostics.DebuggerNonUserCodeAttribute()]
/// </summary> [System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
// Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert public class TitlesLangRes {
// -Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
// Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
// mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class TitlesLangRes {
private static global::System.Resources.ResourceManager resourceMan; private static System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture; private static System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal TitlesLangRes() { internal TitlesLangRes() {
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird. public static System.Resources.ResourceManager ResourceManager {
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get { get {
if (object.ReferenceEquals(resourceMan, null)) { if (object.Equals(null, resourceMan)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.TitlesLangRes", typeof(TitlesLangRes).Assembly); System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.TitlesLangRes", typeof(TitlesLangRes).Assembly);
resourceMan = temp; resourceMan = temp;
} }
return resourceMan; return resourceMan;
} }
} }
/// <summary> [System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
/// Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle public static System.Globalization.CultureInfo Culture {
/// Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get { get {
return resourceCulture; return resourceCulture;
} }
@@ -60,31 +45,28 @@ namespace ModpackUpdater.Apps.Manager.LangRes {
} }
} }
/// <summary> public static string CreateUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Create update ähnelt.
/// </summary>
internal static string CreateUpdate {
get { get {
return ResourceManager.GetString("CreateUpdate", resourceCulture); return ResourceManager.GetString("CreateUpdate", resourceCulture);
} }
} }
/// <summary> public static string EditUpdate {
/// Sucht eine lokalisierte Zeichenfolge, die Edit update ähnelt.
/// </summary>
internal static string EditUpdate {
get { get {
return ResourceManager.GetString("EditUpdate", resourceCulture); return ResourceManager.GetString("EditUpdate", resourceCulture);
} }
} }
/// <summary> public static string GitLabRepoWorkspaceEditor {
/// Sucht eine lokalisierte Zeichenfolge, die Setup GitLab workspace ähnelt.
/// </summary>
internal static string GitLabRepoWorkspaceEditor {
get { get {
return ResourceManager.GetString("GitLabRepoWorkspaceEditor", resourceCulture); return ResourceManager.GetString("GitLabRepoWorkspaceEditor", resourceCulture);
} }
} }
public static string LocalFolderWorkspaceEditor {
get {
return ResourceManager.GetString("LocalFolderWorkspaceEditor", resourceCulture);
}
}
} }
} }

View File

@@ -124,6 +124,9 @@
<value>Edit update</value> <value>Edit update</value>
</data> </data>
<data name="GitLabRepoWorkspaceEditor" xml:space="preserve"> <data name="GitLabRepoWorkspaceEditor" xml:space="preserve">
<value>Setup GitLab workspace</value> <value>Setup GitLab</value>
</data>
<data name="LocalFolderWorkspaceEditor" xml:space="preserve">
<value>Setup local folder</value>
</data> </data>
</root> </root>

View File

@@ -0,0 +1,78 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps.Manager.LangRes {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "4.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class UpdateActionTypeLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal UpdateActionTypeLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.Manager.LangRes.UpdateActionTypeLangRes", typeof(UpdateActionTypeLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
internal static string None {
get {
return ResourceManager.GetString("None", resourceCulture);
}
}
internal static string Update {
get {
return ResourceManager.GetString("Update", resourceCulture);
}
}
internal static string Delete {
get {
return ResourceManager.GetString("Delete", resourceCulture);
}
}
internal static string Move {
get {
return ResourceManager.GetString("Move", resourceCulture);
}
}
internal static string Copy {
get {
return ResourceManager.GetString("Copy", resourceCulture);
}
}
}
}

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:element name="root" msdata:IsDataSet="true">
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>1.3</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="None" xml:space="preserve">
<value>None</value>
</data>
<data name="Update" xml:space="preserve">
<value>Update</value>
</data>
<data name="Delete" xml:space="preserve">
<value>Delete</value>
</data>
<data name="Move" xml:space="preserve">
<value>Move</value>
</data>
<data name="Copy" xml:space="preserve">
<value>Copy</value>
</data>
</root>

View File

@@ -2,26 +2,63 @@
<PropertyGroup> <PropertyGroup>
<OutputType>WinExe</OutputType> <OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows</TargetFramework> <ApplicationIcon>Assets\app.ico</ApplicationIcon>
<Nullable>enable</Nullable> <AssemblyName>MinecraftModpackUpdateManager</AssemblyName>
<UseWindowsForms>true</UseWindowsForms> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<ImplicitUsings>enable</ImplicitUsings> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ApplicationIcon>icons8_Windows_Update.ico</ApplicationIcon> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
<AssemblyName>Minecraft Modpack Update Manager</AssemblyName>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="..\Version.cs" />
<Compile Update="LangRes\UpdateActionTypeLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>UpdateActionTypeLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\SideLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>SideLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\SourceTypeLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>SourceTypeLangRes.resx</DependentUpon>
</Compile>
<Compile Update="Features\Workspaces\LocalFolder\LocalFolderWorkspaceConfigEditorView.axaml.cs">
<DependentUpon>GitLabRepoWorkspaceConfigEditorView.axaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
</ItemGroup>
<ItemGroup>
<AvaloniaResource Include="Assets\**" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Avalonia.Controls.DataGrid" Version="11.3.8" />
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="EPPlus" Version="8.2.1" /> <PackageReference Include="EPPlus" Version="8.2.1" />
<PackageReference Include="NGitLab" Version="11.0.0" /> <PackageReference Include="NGitLab" Version="11.0.1" />
<PackageReference Include="Pilz" Version="2.6.1" />
<PackageReference Include="Pilz.Configuration" Version="3.2.7" /> <PackageReference Include="Pilz.Configuration" Version="3.2.7" />
<PackageReference Include="Pilz.UI" Version="3.1.1" /> <PackageReference Include="Pilz.Cryptography" Version="2.1.2" />
<PackageReference Include="Pilz.UI.WinForms" Version="2.7.0" /> <PackageReference Include="Pilz.Features" Version="2.13.0" />
<PackageReference Include="Pilz.UI.WinForms.Telerik" Version="2.14.3" /> <PackageReference Include="Pilz.UI" Version="3.1.4" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Features" Version="1.9.0" /> <PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.18" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <PackageReference Include="Pilz.UI.AvaloniaUI.Features" Version="1.0.1" />
<PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" /> <PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.GridView" Version="2025.3.812" /> <PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" /> <PackageReference Include="Avalonia.Svg" Version="11.3.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.8" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.8">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="PropertyChanged.Fody" Version="4.1.0" PrivateAssets='All' />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
@@ -60,25 +97,43 @@
<ItemGroup> <ItemGroup>
<EmbeddedResource Update="LangRes\ActionsListLangRes.resx"> <EmbeddedResource Update="LangRes\ActionsListLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>ActionsListLangRes.Designer.cs</LastGenOutput> <LastGenOutput>ActionsListLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\FeatureNamesLangRes.resx"> <EmbeddedResource Update="LangRes\FeatureNamesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>FeatureNamesLangRes.Designer.cs</LastGenOutput> <LastGenOutput>FeatureNamesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\GeneralLangRes.resx"> <EmbeddedResource Update="LangRes\GeneralLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput> <LastGenOutput>GeneralLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\MsgBoxLangRes.resx"> <EmbeddedResource Update="LangRes\MsgBoxLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput> <LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\TitlesLangRes.resx"> <EmbeddedResource Update="LangRes\TitlesLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>PublicResXFileCodeGenerator</Generator>
<LastGenOutput>TitlesLangRes.Designer.cs</LastGenOutput> <LastGenOutput>TitlesLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource> </EmbeddedResource>
<EmbeddedResource Update="LangRes\UpdateActionTypeLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>UpdateActionTypeLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\SideLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>SideLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
<EmbeddedResource Update="LangRes\SourceTypeLangRes.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>SourceTypeLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Reference Include="Pilz">
<HintPath>..\..\..\.nuget\packages\pilz\2.6.1\lib\net8.0\Pilz.dll</HintPath>
</Reference>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -1,12 +1,15 @@
using Avalonia;
using Castle.Core.Logging;
using OfficeOpenXml; using OfficeOpenXml;
using Pilz.Configuration; using Pilz.Configuration;
using Pilz.Features;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps.Manager;
public static class Program public static class Program
{ {
private static readonly SettingsManager settingsManager; public const string UpdateUrl = "https://git.pilzinsel64.de/litw-refined/minecraft-modpack-updater/-/snippets/3/raw/main/updates-manager.json";
internal static readonly SettingsManager settingsManager;
public static ISettings Settings => settingsManager.Instance; public static ISettings Settings => settingsManager.Instance;
@@ -14,30 +17,36 @@ public static class Program
{ {
ExcelPackage.License.SetNonCommercialPersonal("Pilzinsel64"); ExcelPackage.License.SetNonCommercialPersonal("Pilzinsel64");
settingsManager = new(GetSettingsPath(), true); settingsManager = new(GetSettingsPath(), true);
settingsManager.Instance.Logger = new ConsoleLogger("Settings");
} }
/// <summary> /// <summary>
/// The main entry point for the application. /// The main entry point for the application.
/// </summary> /// </summary>
[STAThread] [STAThread]
internal static void Main() internal static void Main(string[] args)
{ {
// To customize application configuration such as set high DPI settings or default font, // To customize application configuration such as set high DPI settings or default font,
// see https://aka.ms/applicationconfiguration. // see https://aka.ms/applicationconfiguration.
ApplicationConfiguration.Initialize(); BuildAvaloniaApp().StartWithClassicDesktopLifetime(args);
AppGlobals.Initialize(); }
PluginFeatureController.Instance.RegisterAllOwn();
Application.Run(new Ui.MainForm()); public static AppBuilder BuildAvaloniaApp()
{
return AppBuilder.Configure<App>()
.UsePlatformDetect()
.WithInterFont()
.LogToTrace();
} }
private static string GetSettingsPath() private static string GetSettingsPath()
{ {
const string AppDataDirectoryName = "MinecraftModpackUpdateManager"; const string AppDataDirectoryName = "MinecraftModpackUpdateManager";
var SettingsFileName = $"Settings.json"; const string settingsFileName = "Settings.json";
var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName); var settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), AppDataDirectoryName);
Directory.CreateDirectory(settingsPath); Directory.CreateDirectory(settingsPath);
settingsPath = Path.Combine(settingsPath, SettingsFileName); settingsPath = Path.Combine(settingsPath, settingsFileName);
return settingsPath; return settingsPath;
} }

View File

@@ -1,405 +0,0 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class MainForm
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
var tableViewDefinition2 = new Telerik.WinControls.UI.TableViewDefinition();
var resources = new System.ComponentModel.ComponentResourceManager(typeof(MainForm));
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel();
radTreeView_Sets = new Telerik.WinControls.UI.RadTreeView();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel_ActionSet = new TableLayoutPanel();
radGridView_Actions = new Telerik.WinControls.UI.RadGridView();
tableLayoutPanel_ActionSetInfo = new TableLayoutPanel();
radLabel1 = new Telerik.WinControls.UI.RadLabel();
radTextBoxControl_Version = new Telerik.WinControls.UI.RadTextBoxControl();
radCheckBox_IsPublic = new Telerik.WinControls.UI.RadCheckBox();
radMenuItem_Workspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_WorkspacePreferences = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_SaveWorkspace = new Telerik.WinControls.UI.RadMenuItem();
radMenuSeparatorItem1 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuHeaderItem_NewWorkspace = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuSeparatorItem3 = new Telerik.WinControls.UI.RadMenuSeparatorItem();
radMenuHeaderItem_RecentWorkspaces = new Telerik.WinControls.UI.RadMenuHeaderItem();
radMenuItem_Tools = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_Updates = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_CreateUpdate = new Telerik.WinControls.UI.RadMenuItem();
radMenuItem_RemoveUpdate = new Telerik.WinControls.UI.RadMenuItem();
radWaitingBar_Updates = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radWaitingBar_Actions = new Telerik.WinControls.UI.RadWaitingBar();
dotsRingWaitingBarIndicatorElement2 = new Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement();
radMenu1 = new Telerik.WinControls.UI.RadMenu();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radTreeView_Sets).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout();
tableLayoutPanel_ActionSet.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).BeginInit();
tableLayoutPanel_ActionSetInfo.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).BeginInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).BeginInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).BeginInit();
((System.ComponentModel.ISupportInitialize)radMenu1).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// radSplitContainer1
//
radSplitContainer1.Controls.Add(splitPanel1);
radSplitContainer1.Controls.Add(splitPanel2);
radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 28);
radSplitContainer1.Name = "radSplitContainer1";
radSplitContainer1.Size = new Size(800, 422);
radSplitContainer1.TabIndex = 0;
radSplitContainer1.TabStop = false;
//
// splitPanel1
//
splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1";
splitPanel1.Size = new Size(232, 422);
splitPanel1.SizeInfo.AbsoluteSize = new Size(232, 200);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(-0.190954775F, 0F);
splitPanel1.SizeInfo.SizeMode = Telerik.WinControls.UI.Docking.SplitPanelSizeMode.Absolute;
splitPanel1.SizeInfo.SplitterCorrection = new Size(-120, 0);
splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false;
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Controls.Add(radTreeView_Sets, 0, 0);
tableLayoutPanel2.Dock = DockStyle.Fill;
tableLayoutPanel2.Location = new Point(0, 0);
tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 50F));
tableLayoutPanel2.Size = new Size(232, 422);
tableLayoutPanel2.TabIndex = 1;
//
// radTreeView_Sets
//
radTreeView_Sets.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radTreeView_Sets.ItemHeight = 24;
radTreeView_Sets.LineColor = Color.FromArgb(152, 152, 152);
radTreeView_Sets.LineStyle = Telerik.WinControls.UI.TreeLineStyle.Solid;
radTreeView_Sets.Location = new Point(3, 3);
radTreeView_Sets.Name = "radTreeView_Sets";
radTreeView_Sets.Size = new Size(226, 416);
radTreeView_Sets.TabIndex = 0;
radTreeView_Sets.SelectedNodeChanged += RadTreeView_Sets_SelectedNodeChanged;
//
// splitPanel2
//
splitPanel2.Controls.Add(tableLayoutPanel_ActionSet);
splitPanel2.Location = new Point(236, 0);
splitPanel2.Name = "splitPanel2";
splitPanel2.Size = new Size(564, 422);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.0600000024F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(120, 0);
splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false;
//
// tableLayoutPanel_ActionSet
//
tableLayoutPanel_ActionSet.ColumnCount = 1;
tableLayoutPanel_ActionSet.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSet.Controls.Add(radGridView_Actions, 0, 1);
tableLayoutPanel_ActionSet.Controls.Add(tableLayoutPanel_ActionSetInfo, 0, 0);
tableLayoutPanel_ActionSet.Dock = DockStyle.Fill;
tableLayoutPanel_ActionSet.Location = new Point(0, 0);
tableLayoutPanel_ActionSet.Name = "tableLayoutPanel_ActionSet";
tableLayoutPanel_ActionSet.RowCount = 2;
tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle());
tableLayoutPanel_ActionSet.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSet.Size = new Size(564, 422);
tableLayoutPanel_ActionSet.TabIndex = 0;
//
// radGridView_Actions
//
radGridView_Actions.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radGridView_Actions.Location = new Point(3, 33);
//
//
//
radGridView_Actions.MasterTemplate.AddNewRowPosition = Telerik.WinControls.UI.SystemRowPosition.Bottom;
radGridView_Actions.MasterTemplate.AllowColumnChooser = false;
radGridView_Actions.MasterTemplate.AllowDragToGroup = false;
radGridView_Actions.MasterTemplate.AllowRowResize = false;
radGridView_Actions.MasterTemplate.AllowSearchRow = true;
radGridView_Actions.MasterTemplate.EnableGrouping = false;
radGridView_Actions.MasterTemplate.ViewDefinition = tableViewDefinition2;
radGridView_Actions.Name = "radGridView_Actions";
radGridView_Actions.Size = new Size(558, 386);
radGridView_Actions.TabIndex = 0;
radGridView_Actions.CellFormatting += RadGridView_Actions_CellFormatting;
radGridView_Actions.UserAddedRow += RadGridView_Actions_UserAddedRow;
radGridView_Actions.UserDeletingRow += RadGridView_Actions_UserDeletingRow;
radGridView_Actions.CellValueChanged += RadGridView_Actions_CellValueChanged;
radGridView_Actions.ContextMenuOpening += RadGridView_Actions_ContextMenuOpening;
//
// tableLayoutPanel_ActionSetInfo
//
tableLayoutPanel_ActionSetInfo.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right;
tableLayoutPanel_ActionSetInfo.AutoSize = true;
tableLayoutPanel_ActionSetInfo.ColumnCount = 3;
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel_ActionSetInfo.Controls.Add(radLabel1, 0, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radTextBoxControl_Version, 1, 0);
tableLayoutPanel_ActionSetInfo.Controls.Add(radCheckBox_IsPublic, 2, 0);
tableLayoutPanel_ActionSetInfo.Location = new Point(0, 0);
tableLayoutPanel_ActionSetInfo.Margin = new Padding(0);
tableLayoutPanel_ActionSetInfo.Name = "tableLayoutPanel_ActionSetInfo";
tableLayoutPanel_ActionSetInfo.RowCount = 1;
tableLayoutPanel_ActionSetInfo.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel_ActionSetInfo.Size = new Size(564, 30);
tableLayoutPanel_ActionSetInfo.TabIndex = 1;
//
// radLabel1
//
radLabel1.Anchor = AnchorStyles.Left;
radLabel1.Location = new Point(3, 4);
radLabel1.Name = "radLabel1";
radLabel1.Size = new Size(58, 22);
radLabel1.TabIndex = 0;
radLabel1.Text = "Version:";
//
// radTextBoxControl_Version
//
radTextBoxControl_Version.Anchor = AnchorStyles.Left;
radTextBoxControl_Version.AutoSize = true;
radTextBoxControl_Version.Location = new Point(67, 3);
radTextBoxControl_Version.Name = "radTextBoxControl_Version";
radTextBoxControl_Version.NullText = "e.g. 1.2.5.0";
radTextBoxControl_Version.Size = new Size(150, 24);
radTextBoxControl_Version.TabIndex = 1;
radTextBoxControl_Version.TextChanged += RadTextBoxControl1_TextChanged;
//
// radCheckBox_IsPublic
//
radCheckBox_IsPublic.Anchor = AnchorStyles.Left;
radCheckBox_IsPublic.Location = new Point(223, 5);
radCheckBox_IsPublic.Name = "radCheckBox_IsPublic";
radCheckBox_IsPublic.Size = new Size(76, 20);
radCheckBox_IsPublic.TabIndex = 2;
radCheckBox_IsPublic.Text = "Is public";
radCheckBox_IsPublic.ToggleStateChanged += RadCheckBox1_ToggleStateChanged;
//
// radMenuItem_Workspace
//
radMenuItem_Workspace.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_WorkspacePreferences, radMenuItem_SaveWorkspace, radMenuSeparatorItem1, radMenuHeaderItem_NewWorkspace, radMenuSeparatorItem3, radMenuHeaderItem_RecentWorkspaces });
radMenuItem_Workspace.Name = "radMenuItem_Workspace";
radMenuItem_Workspace.Text = "Workspace";
//
// radMenuItem_WorkspacePreferences
//
radMenuItem_WorkspacePreferences.Name = "radMenuItem_WorkspacePreferences";
radMenuItem_WorkspacePreferences.Text = "Preferences";
radMenuItem_WorkspacePreferences.Click += RadMenuItem_WorkspacePreferences_Click;
//
// radMenuItem_SaveWorkspace
//
radMenuItem_SaveWorkspace.Name = "radMenuItem_SaveWorkspace";
radMenuItem_SaveWorkspace.Text = "Save";
radMenuItem_SaveWorkspace.Click += RadMenuItem_SaveWorkspace_Click;
//
// radMenuSeparatorItem1
//
radMenuSeparatorItem1.Name = "radMenuSeparatorItem1";
radMenuSeparatorItem1.Text = "radMenuSeparatorItem1";
radMenuSeparatorItem1.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuHeaderItem_NewWorkspace
//
radMenuHeaderItem_NewWorkspace.Name = "radMenuHeaderItem_NewWorkspace";
radMenuHeaderItem_NewWorkspace.Text = "New workspace";
//
// radMenuSeparatorItem3
//
radMenuSeparatorItem3.Name = "radMenuSeparatorItem3";
radMenuSeparatorItem3.Text = "radMenuSeparatorItem3";
radMenuSeparatorItem3.TextAlignment = ContentAlignment.MiddleLeft;
//
// radMenuHeaderItem_RecentWorkspaces
//
radMenuHeaderItem_RecentWorkspaces.Name = "radMenuHeaderItem_RecentWorkspaces";
radMenuHeaderItem_RecentWorkspaces.Text = "Recent workspaces";
//
// radMenuItem_Tools
//
radMenuItem_Tools.Name = "radMenuItem_Tools";
radMenuItem_Tools.Text = "Tools";
//
// radMenuItem_Updates
//
radMenuItem_Updates.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_CreateUpdate, radMenuItem_RemoveUpdate });
radMenuItem_Updates.Name = "radMenuItem_Updates";
radMenuItem_Updates.Text = "Updates";
radMenuItem_Updates.DropDownOpening += RadMenuItem_Updates_DropDownOpening;
//
// radMenuItem_CreateUpdate
//
radMenuItem_CreateUpdate.Name = "radMenuItem_CreateUpdate";
radMenuItem_CreateUpdate.Text = "Create";
radMenuItem_CreateUpdate.Click += RadMenuItem_CreateUpdate_Click;
//
// radMenuItem_RemoveUpdate
//
radMenuItem_RemoveUpdate.Name = "radMenuItem_RemoveUpdate";
radMenuItem_RemoveUpdate.Text = "Remove";
radMenuItem_RemoveUpdate.Click += RadMenuItem_RemoveUpdate_Click;
//
// radWaitingBar_Updates
//
radWaitingBar_Updates.AssociatedControl = radTreeView_Sets;
radWaitingBar_Updates.Location = new Point(0, 78);
radWaitingBar_Updates.Name = "radWaitingBar_Updates";
radWaitingBar_Updates.Size = new Size(70, 70);
radWaitingBar_Updates.TabIndex = 2;
radWaitingBar_Updates.Text = "radWaitingBar1";
radWaitingBar_Updates.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement1);
radWaitingBar_Updates.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar_Updates.WaitingSpeed = 50;
radWaitingBar_Updates.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing;
//
// dotsRingWaitingBarIndicatorElement1
//
dotsRingWaitingBarIndicatorElement1.Name = "dotsRingWaitingBarIndicatorElement1";
//
// radWaitingBar_Actions
//
radWaitingBar_Actions.AssociatedControl = radGridView_Actions;
radWaitingBar_Actions.ForeColor = Color.Black;
radWaitingBar_Actions.Location = new Point(0, 145);
radWaitingBar_Actions.Name = "radWaitingBar_Actions";
radWaitingBar_Actions.Size = new Size(70, 70);
radWaitingBar_Actions.TabIndex = 3;
radWaitingBar_Actions.WaitingIndicators.Add(dotsRingWaitingBarIndicatorElement2);
radWaitingBar_Actions.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar_Actions.WaitingSpeed = 50;
radWaitingBar_Actions.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsRing;
//
// dotsRingWaitingBarIndicatorElement2
//
dotsRingWaitingBarIndicatorElement2.Name = "dotsRingWaitingBarIndicatorElement2";
//
// radMenu1
//
radMenu1.Items.AddRange(new Telerik.WinControls.RadItem[] { radMenuItem_Workspace, radMenuItem_Updates, radMenuItem_Tools });
radMenu1.Location = new Point(0, 0);
radMenu1.Name = "radMenu1";
radMenu1.Size = new Size(800, 28);
radMenu1.TabIndex = 1;
//
// MainForm
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 450);
Controls.Add(radWaitingBar_Actions);
Controls.Add(radWaitingBar_Updates);
Controls.Add(radSplitContainer1);
Controls.Add(radMenu1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "MainForm";
StartPosition = FormStartPosition.CenterScreen;
Text = "Minecraft Modpack Updates Manager";
WindowState = FormWindowState.Maximized;
Load += Form1_Load;
((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit();
radSplitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
splitPanel1.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radTreeView_Sets).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false);
tableLayoutPanel_ActionSet.ResumeLayout(false);
tableLayoutPanel_ActionSet.PerformLayout();
((System.ComponentModel.ISupportInitialize)radGridView_Actions.MasterTemplate).EndInit();
((System.ComponentModel.ISupportInitialize)radGridView_Actions).EndInit();
tableLayoutPanel_ActionSetInfo.ResumeLayout(false);
tableLayoutPanel_ActionSetInfo.PerformLayout();
((System.ComponentModel.ISupportInitialize)radLabel1).EndInit();
((System.ComponentModel.ISupportInitialize)radTextBoxControl_Version).EndInit();
((System.ComponentModel.ISupportInitialize)radCheckBox_IsPublic).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar_Actions).EndInit();
((System.ComponentModel.ISupportInitialize)radMenu1).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private Telerik.WinControls.UI.RadSplitContainer radSplitContainer1;
private Telerik.WinControls.UI.SplitPanel splitPanel1;
private Telerik.WinControls.UI.SplitPanel splitPanel2;
private Telerik.WinControls.UI.RadMenu radMenu1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Workspace;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_WorkspacePreferences;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Tools;
private TableLayoutPanel tableLayoutPanel2;
private TableLayoutPanel tableLayoutPanel_ActionSet;
private Telerik.WinControls.UI.RadGridView radGridView_Actions;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem1;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_SaveWorkspace;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Updates;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement1;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar_Actions;
private Telerik.WinControls.UI.DotsRingWaitingBarIndicatorElement dotsRingWaitingBarIndicatorElement2;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_Updates;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_CreateUpdate;
private Telerik.WinControls.UI.RadMenuItem radMenuItem_RemoveUpdate;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_NewWorkspace;
private Telerik.WinControls.UI.RadMenuSeparatorItem radMenuSeparatorItem3;
private Telerik.WinControls.UI.RadMenuHeaderItem radMenuHeaderItem_RecentWorkspaces;
private Telerik.WinControls.UI.RadTreeView radTreeView_Sets;
private TableLayoutPanel tableLayoutPanel_ActionSetInfo;
private Telerik.WinControls.UI.RadLabel radLabel1;
private Telerik.WinControls.UI.RadTextBoxControl radTextBoxControl_Version;
private Telerik.WinControls.UI.RadCheckBox radCheckBox_IsPublic;
}

View File

@@ -1,651 +0,0 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Settings;
using Pilz.Features;
using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Extensions;
using Pilz.UI.WinForms.Telerik.Features;
using Telerik.WinControls;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainForm : RadForm, IMainApi
{
private record RecentFilesItemTag(WorkspaceConfig Config, WorkspaceFeature Feature);
private record WorkspaceTag(IWorkspace Workspace, WorkspaceFeature Feature);
private bool loadingMainView;
private WorkspaceTag? wsInfo;
private InstallAction? tempAction;
Form IMainApi.MainWindow => this;
IWorkspace? IMainApi.CurWorkspace => wsInfo?.Workspace;
public IActionSetInfos? CurActionSet => radTreeView_Sets.SelectedNode?.Tag as IActionSetInfos;
public MainForm()
{
InitializeComponent();
radMenuItem_Workspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.workspace, SymbolSize.Small);
radMenuItem_WorkspacePreferences.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.settings, SymbolSize.Small);
radMenuItem_SaveWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.save, SymbolSize.Small);
//radMenuItem_OpenNewWorkspace.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.new_window, SymbolSize.Small);
//radMenuItem_RecentWorkspaces.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.time_machine, SymbolSize.Small);
radMenuItem_Updates.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small);
radMenuItem_CreateUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.add, SymbolSize.Small);
radMenuItem_RemoveUpdate.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.remove, SymbolSize.Small);
radMenuItem_Tools.SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.tools, SymbolSize.Small);
radMenuItem_SaveWorkspace.Shortcuts.Add(new(Keys.Control, Keys.S));
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).InsertItemsTo(radMenuItem_Workspace.Items,
customClickHandler: RadMenuItem_OpenNewWorkspace_Click,
insertPrioSplitters: true,
customDefault: radMenuItem_Workspace.Items.IndexOf(radMenuHeaderItem_NewWorkspace) + 1);
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(radMenuItem_Tools.Items,
customClickHandler: RadMenuItem_ToolsItem_Click,
insertPrioSplitters: true);
}
private void LoadRecentWorkspaces()
{
var settings = Program.Settings.Get<WorkspaceSettings>();
var startIndex = radMenuItem_Workspace.Items.IndexOf(radMenuHeaderItem_RecentWorkspaces) + 1;
foreach (var item in radMenuItem_Workspace.Items.Where(n => n.Tag is RecentFilesItemTag).ToArray())
radMenuItem_Workspace.Items.Remove(item);
foreach (var config in settings.Workspaces)
{
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
continue;
var item = new RadMenuItem
{
Text = config.DisplayText,
Tag = new RecentFilesItemTag(config, feature),
SvgImage = feature.Icon as RadSvgImage,
};
item.Click += RadMenuItem_OpenRecentWorkspace_Click;
radMenuItem_Workspace.Items.Insert(startIndex++, item);
}
}
private void AddToRecentFiles(IWorkspace workspace)
{
var settings = Program.Settings.Get<WorkspaceSettings>();
settings.Workspaces.Remove(workspace.Config);
settings.Workspaces.Insert(0, workspace.Config);
while (settings.Workspaces.Count > 20)
settings.Workspaces.RemoveAt(20);
}
private async Task LoadNewWorkspace(IWorkspace? workspace, WorkspaceFeature feature)
{
if (workspace is null)
return;
if (workspace != wsInfo?.Workspace)
wsInfo = new(workspace, feature);
AddToRecentFiles(workspace);
Invoke(LoadRecentWorkspaces);
radWaitingBar_Updates.StartWaiting();
if (!await workspace.Load())
{
radWaitingBar_Updates.StopWaiting();
return;
}
Invoke(LoadWorkspace);
}
private void LoadWorkspace()
{
if (wsInfo?.Workspace.Config is null || wsInfo.Workspace.InstallInfos is null || wsInfo.Workspace.UpdateInfos is null)
return;
radWaitingBar_Updates.StartWaiting();
Text = wsInfo.Workspace.Config.DisplayText;
radTreeView_Sets.BeginUpdate();
radTreeView_Sets.Nodes.Clear();
AddUpdateItem(wsInfo.Workspace.InstallInfos);
var nodeUpdates = new RadTreeNode
{
Text = "Updates",
Name = "updates",
SvgImage = AppGlobals.Symbols.GetSvgImage(AppSymbols.update_done, SymbolSize.Small),
};
wsInfo.Workspace.UpdateInfos.Updates.ForEach(n => AddUpdateItem(n, nodeUpdates.Nodes));
radTreeView_Sets.Nodes.Add(nodeUpdates);
radTreeView_Sets.EndUpdate();
radWaitingBar_Updates.StopWaiting();
}
private RadTreeNode AddUpdateItem(IActionSetInfos infos)
{
return AddUpdateItem(infos, radTreeView_Sets.Nodes);
}
private RadTreeNode AddUpdateItem(IActionSetInfos infos, RadTreeNodeCollection parent)
{
var item = CreateUpdateItem(infos);
parent.Add(item);
return item;
}
private RadTreeNode InsertUpdateItem(IActionSetInfos infos)
{
var item = CreateUpdateItem(infos);
var nodeUpdates = radTreeView_Sets.Nodes["updates"];
nodeUpdates.Nodes.Insert(Math.Min(1, nodeUpdates.Nodes.Count), item);
return item;
}
private RadTreeNode CreateUpdateItem(IActionSetInfos infos)
{
var item = new RadTreeNode();
UpdateUpdateItem(item, infos);
return item;
}
private void UpdateUpdateItem(RadTreeNode item)
{
if (item.Tag is IActionSetInfos infos)
UpdateUpdateItem(item, infos);
}
private void SaveActionsSet()
{
if (loadingMainView || CurActionSet is not IActionSetInfos infos)
return;
if (!Version.TryParse(radTextBoxControl_Version.Text.Trim(), out Version? version))
version = new Version("1.0.0.0");
infos.Version = version;
infos.IsPublic = radCheckBox_IsPublic.Checked;
UpdateUpdateItem(radTreeView_Sets.SelectedNode);
}
private void UpdateUpdateItem(RadTreeNode item, IActionSetInfos infos)
{
if (item.Tag != infos)
item.Tag = infos;
if (infos is UpdateInfo)
item.Text = string.Format(GeneralLangRes.Node_Update, infos.Version?.ToString() ?? "?");
else if (infos is InstallInfos)
item.Text = string.Format(GeneralLangRes.Node_Install, infos.Version?.ToString() ?? "?");
else
item.Text = infos.Version.ToString();
item.SvgImage = AppGlobals.Symbols.GetSvgImage(infos.IsPublic ? AppSymbols.eye : AppSymbols.invisible, SymbolSize.Small);
}
public void UpdateItem(IActionSetInfos actionSetInfos)
{
RadTreeNode? item = null;
var nodeUpdates = radTreeView_Sets.Nodes["updates"];
foreach (var iitem in nodeUpdates.Nodes)
{
if (item == null && iitem.Value == actionSetInfos)
item = iitem;
}
if (item == null)
InsertUpdateItem(actionSetInfos);
else if (wsInfo?.Workspace.UpdateInfos != null && !wsInfo.Workspace.UpdateInfos.Updates.Contains(actionSetInfos))
item.Remove();
else
UpdateUpdateItem(item);
}
public void UpdateItem(InstallAction action)
{
foreach (var row in radGridView_Actions.Rows)
{
if (row.Tag == action)
UpdateActionRow(row);
}
}
private void LoadMainView()
{
loadingMainView = true;
tableLayoutPanel_ActionSet.Visible = false;
tableLayoutPanel_ActionSetInfo.Visible = false;
if (CurActionSet is IActionSet set)
{
if (set is IActionSetInfos infos)
{
radTextBoxControl_Version.Text = infos.Version?.ToString();
radCheckBox_IsPublic.Checked = infos.IsPublic;
tableLayoutPanel_ActionSetInfo.Visible = true;
}
tableLayoutPanel_ActionSet.Visible = true;
LoadActionSet(set);
}
loadingMainView = false;
}
private void LoadActionSet(IActionSet infos)
{
radGridView_Actions.BeginUpdate();
radGridView_Actions.Rows.Clear();
radGridView_Actions.Columns.Clear();
// Add columns
radGridView_Actions.Columns.AddRange([
new GridViewTextBoxColumn
{
Name = "id",
HeaderText = ActionsListLangRes.Col_Id,
Width = 150,
IsVisible = infos is not UpdateInfo,
IsPinned = true,
},
new GridViewTextBoxColumn
{
Name = "name",
HeaderText = ActionsListLangRes.Col_Name,
Width = 150,
IsVisible = infos is not UpdateInfo,
},
new GridViewTextBoxColumn
{
Name = "inherit",
HeaderText = ActionsListLangRes.Col_InheritFrom,
Width = 150,
IsVisible = infos is UpdateInfo,
IsPinned = true,
},
new GridViewComboBoxColumn
{
Name = "utype",
HeaderText = ActionsListLangRes.Col_UpdateType,
Width = 150,
DataSource = Enum.GetValues<UpdateActionType>(),
IsVisible = infos is UpdateInfo,
},
new GridViewComboBoxColumn
{
Name = "side",
HeaderText = ActionsListLangRes.Col_Side,
Width = 100,
DataSource = Enum.GetValues<Side>(),
},
new GridViewCheckBoxColumn
{
Name = "isextra",
HeaderText = ActionsListLangRes.Col_IsExtra,
Width = 50,
},
new GridViewCheckBoxColumn
{
Name = "iszip",
HeaderText = ActionsListLangRes.Col_IsZip,
Width = 50,
},
new GridViewCheckBoxColumn
{
Name = "isdir",
HeaderText = ActionsListLangRes.Col_IsDir,
Width = 50,
IsVisible = infos is UpdateInfo,
},
new GridViewTextBoxColumn
{
Name = "destpath",
HeaderText = ActionsListLangRes.Col_DestPath,
Width = 250,
},
new GridViewComboBoxColumn
{
Name = "srctype",
HeaderText = ActionsListLangRes.Col_SrcType,
Width = 150,
DataSource = Enum.GetValues<SourceType>(),
},
new GridViewTextBoxColumn
{
Name = "srcowner",
HeaderText = ActionsListLangRes.Col_SrcOwner,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcname",
HeaderText = ActionsListLangRes.Col_SrcName,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcregex",
HeaderText = ActionsListLangRes.Col_SrcRegEx,
Width = 200,
},
new GridViewTextBoxColumn
{
Name = "srctag",
HeaderText = ActionsListLangRes.Col_SrcTag,
Width = 150,
},
new GridViewTextBoxColumn
{
Name = "srcurl",
HeaderText = ActionsListLangRes.Col_SrcUrl,
Width = 350,
},
new GridViewTextBoxColumn
{
Name = "zippath",
HeaderText = ActionsListLangRes.Col_ZipPath,
Width = 200,
},
new GridViewTextBoxColumn
{
Name = "srcpath",
HeaderText = ActionsListLangRes.Col_SrcPath,
Width = 250,
IsVisible = infos is UpdateInfo,
},
new GridViewTextBoxColumn
{
Name = "website",
HeaderText = ActionsListLangRes.Col_Website,
Width = 350,
},
]);
// Add rows
foreach (var action in infos.Actions)
{
var row = radGridView_Actions.Rows.AddNew();
row.Tag = action;
UpdateActionRow(row);
}
radGridView_Actions.EndUpdate();
}
private void UpdateActionRow(GridViewRowInfo row)
{
if (row.Tag is not InstallAction action)
return;
row.Cells["id"].Value = action.Id;
row.Cells["name"].Value = action.Name;
row.Cells["iszip"].Value = action.IsZip;
row.Cells["zippath"].Value = action.ZipPath;
row.Cells["destpath"].Value = action.DestPath;
row.Cells["srcurl"].Value = action.SourceUrl;
row.Cells["srctype"].Value = action.SourceType;
row.Cells["srcowner"].Value = action.SourceOwner;
row.Cells["srcname"].Value = action.SourceName;
row.Cells["srcregex"].Value = action.SourceRegex;
row.Cells["srctag"].Value = action.SourceTag;
row.Cells["side"].Value = action.Side;
row.Cells["isextra"].Value = action.IsExtra;
row.Cells["website"].Value = action.Website;
if (action is not UpdateAction uaction)
return;
row.Cells["inherit"].Value = uaction.InheritFrom; // TODO: Find inherit action and put it in here!
row.Cells["utype"].Value = uaction.Type;
row.Cells["srcpath"].Value = uaction.SrcPath;
row.Cells["isdir"].Value = uaction.IsDirectory;
}
private void Form1_Load(object sender, EventArgs e)
{
LoadRecentWorkspaces();
}
private async void RadMenuItem_OpenNewWorkspace_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is WorkspaceFeature feature)
{
var ws = wsInfo?.Workspace;
if (feature.Configure(ref ws))
await LoadNewWorkspace(ws, feature);
}
}
private async void RadMenuItem_OpenRecentWorkspace_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is RecentFilesItemTag tag && tag.Feature.CreateFromConfig(tag.Config) is IWorkspace workspace)
await LoadNewWorkspace(workspace, tag.Feature);
}
private async void RadMenuItem_WorkspacePreferences_Click(object sender, EventArgs e)
{
if (wsInfo != null)
{
var ws = wsInfo.Workspace;
if (wsInfo.Feature.Configure(ref ws))
await LoadNewWorkspace(ws, wsInfo.Feature);
}
}
private void RadMenuItem_SaveWorkspace_Click(object sender, EventArgs e)
{
wsInfo?.Workspace.Save();
}
private void RadMenuItem_ToolsItem_Click(object? sender, EventArgs e)
{
if (sender is RadMenuItem item && item.Tag is PluginFunction func)
func.Execute(new MainApiParameters(this));
}
private void RadTreeView_Sets_SelectedNodeChanged(object sender, RadTreeViewEventArgs e)
{
LoadMainView();
}
private void RadGridView_Actions_CellFormatting(object sender, CellFormattingEventArgs e)
{
//var cellElement = e.CellElement;
//var cellInfo = e.Row.Cells[e.Column.Name];
//if (e.Column.Name == "srctype" && cellInfo?.Value is string sourceTypeStr && Enum.Parse<SourceType>(sourceTypeStr) is SourceType sourceType)
//{
// cellElement.SvgImage = sourceType switch
// {
// SourceType.DirectLink => AppGlobals.Symbols.GetSvgImage(AppSymbols.link, SymbolSize.Small),
// SourceType.GitHub => AppGlobals.Symbols.GetSvgImage(AppSymbols.github, SymbolSize.Small),
// _ => null,
// };
// cellElement.DrawImage = cellElement.SvgImage != null;
// cellElement.TextImageRelation = TextImageRelation.ImageBeforeText;
// cellElement.ImageAlignment = ContentAlignment.MiddleLeft;
//}
//else
//{
// cellElement.ResetValue(LightVisualElement.SvgImageProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.DrawImageProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.TextImageRelationProperty, ValueResetFlags.Local);
// cellElement.ResetValue(LightVisualElement.ImageAlignmentProperty, ValueResetFlags.Local);
//}
}
private void RadGridView_Actions_CellValueChanged(object sender, GridViewCellEventArgs e)
{
if (e.Row is null)
return;
if (e.Row.Tag is not InstallAction action)
{
if (CurActionSet is UpdateInfo)
action = tempAction ??= new UpdateAction();
else if (CurActionSet is InstallInfos)
action = tempAction ??= new InstallAction();
else
return;
}
var uaction = action as UpdateAction;
var newValue = e.Row.Cells[e.Column.Name].Value;
var colName = e.Column.Name;
if (newValue is bool valueBool)
{
switch (colName)
{
case "iszip":
action.IsZip = valueBool;
break;
case "isextra":
action.IsExtra = valueBool;
break;
case "isdir":
if (uaction is not null)
uaction.IsDirectory = valueBool;
break;
}
}
else
{
var valueStr = newValue as string ?? string.Empty;
var valueNullStr = valueStr.Nullify();
switch (colName)
{
case "id":
action.Id = valueNullStr;
break;
case "name":
action.Name = valueNullStr;
break;
case "zippath":
action.ZipPath = valueNullStr;
break;
case "destpath":
action.DestPath = valueNullStr;
break;
case "srcurl":
action.SourceUrl = valueNullStr;
break;
case "srctype":
action.SourceType = Enum.Parse<SourceType>(valueStr);
break;
case "srcowner":
action.SourceOwner = valueNullStr;
break;
case "srcname":
action.SourceName = valueNullStr;
break;
case "srcregex":
action.SourceRegex = valueNullStr;
break;
case "srctag":
action.SourceTag = valueNullStr;
break;
case "website":
action.Website = valueNullStr;
break;
case "side":
action.Side = Enum.Parse<Side>(valueStr);
break;
case "inherit":
if (uaction is not null)
uaction.InheritFrom = valueNullStr;
break;
case "utype":
if (uaction is not null)
uaction.Type = Enum.Parse<UpdateActionType>(valueStr);
break;
case "srcpath":
if (uaction is not null)
uaction.SrcPath = valueNullStr;
break;
}
}
}
private void RadMenuItem_Updates_DropDownOpening(object sender, System.ComponentModel.CancelEventArgs e)
{
radMenuItem_RemoveUpdate.Enabled = radTreeView_Sets.SelectedNode?.Tag is UpdateInfo;
}
private void RadMenuItem_CreateUpdate_Click(object sender, EventArgs e)
{
if (wsInfo?.Workspace.UpdateInfos is null)
return;
var infos = new UpdateInfo
{
Version = wsInfo.Workspace.InstallInfos?.Version,
};
wsInfo.Workspace.UpdateInfos.Updates.Insert(0, infos);
InsertUpdateItem(infos);
}
private void RadMenuItem_RemoveUpdate_Click(object sender, EventArgs e)
{
if (radTreeView_Sets.SelectedNode?.Tag is UpdateInfo infos && wsInfo?.Workspace.UpdateInfos is not null
&& RadMessageBox.Show(MsgBoxLangRes.RemoveUpdate, MsgBoxLangRes.RemoveUpdate_Title, MessageBoxButtons.YesNo, RadMessageIcon.Exclamation).IsYes())
{
wsInfo.Workspace.UpdateInfos.Updates.Remove(infos);
radTreeView_Sets.SelectedNode.Remove();
}
}
private void RadGridView_Actions_UserAddedRow(object sender, GridViewRowEventArgs e)
{
if (tempAction is UpdateAction uaction && CurActionSet is UpdateInfo uinfo)
uinfo.Actions.Add(uaction);
else if (tempAction is InstallAction iaction && CurActionSet is InstallInfos iinfo)
iinfo.Actions.Add(iaction);
tempAction = null;
}
private void RadGridView_Actions_UserDeletingRow(object sender, GridViewRowCancelEventArgs e)
{
foreach (var row in e.Rows)
{
if (row.Tag is UpdateAction uaction && CurActionSet is UpdateInfo uinfo)
uinfo.Actions.Remove(uaction);
else if (row.Tag is InstallAction iaction && CurActionSet is InstallInfos iinfo)
iinfo.Actions.Remove(iaction);
}
}
private void RadGridView_Actions_ContextMenuOpening(object sender, ContextMenuOpeningEventArgs e)
{
if (e.ContextMenuProvider is GridDataCellElement)
{
e.ContextMenu.Items.Add(new RadMenuSeparatorItem());
PluginFeatureController.Instance.Functions.Get(FeatureTypes.ActionsContextMenu).InsertItemsTo(e.ContextMenu.Items, customClickHandler: RadMenuItem_ToolsItem_Click, insertPrioSplitters: true);
}
}
private void RadTextBoxControl1_TextChanged(object sender, EventArgs e)
{
SaveActionsSet();
}
private void RadCheckBox1_ToggleStateChanged(object sender, StateChangedEventArgs args)
{
SaveActionsSet();
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,456 @@
<Window
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ModpackUpdater.Apps.Manager.Ui"
xmlns:pilz="https://git.pilzinsel64.de/pilz-framework/pilz"
xmlns:symbols="clr-namespace:Pilz.UI.Symbols;assembly=Pilz.UI"
xmlns:mainWindow="clr-namespace:ModpackUpdater.Apps.Manager.Ui.Models.MainWindow"
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="ModpackUpdater.Apps.Manager.Ui.MainWindow"
Title="Minecraft Modpack Manager"
WindowState="Maximized"
Loaded="Window_OnLoaded"
Closed="Window_OnClosed"
KeyDown="Window_OnKeyDown">
<Grid
x:Name="GridMain"
x:DataType="mainWindow:MainWindowViewModel"
RowDefinitions="Auto,*"
ColumnDefinitions="Auto,*,500"
RowSpacing="6"
ColumnSpacing="6"
Margin="3">
<!-- StackPanel: Workspace -->
<StackPanel
Grid.Column="0"
Grid.Row="0"
Orientation="Horizontal">
<!-- Button: Workspace -->
<pilz:ImageButton
x:Name="ButtonWorkspace"
Text="{x:Static langRes:GeneralLangRes.Workspace}"
Background="Transparent">
<pilz:ImageButton.Flyout>
<MenuFlyout>
<MenuFlyout.Items>
<MenuItem x:Name="MenuItemWorkspacePreferences" Header="{x:Static langRes:GeneralLangRes.WorkspacePreferences}" Click="MenuItemWorkspacePreferences_OnClick"/>
<MenuItem x:Name="MenuItemSaveWorkspace" Header="{x:Static langRes:GeneralLangRes.SaveWorkspace}" HotKey="Ctrl+S" Click="MenuItemSaveWorkspace_OnClick"/>
<Separator/>
<MenuItem x:Name="MenuItemNewWorkspace" Header="{x:Static langRes:GeneralLangRes.NewWorkspace}"/>
<Separator/>
<MenuItem x:Name="MenuItemRecentWorkspaces" Header="{x:Static langRes:GeneralLangRes.RecentWorkspaces}"/>
</MenuFlyout.Items>
</MenuFlyout>
</pilz:ImageButton.Flyout>
</pilz:ImageButton>
<!-- Button: Update -->
<pilz:ImageButton
x:Name="ButtonUpdate"
Text="{x:Static langRes:GeneralLangRes.Update}"
Background="Transparent">
<pilz:ImageButton.Flyout>
<MenuFlyout>
<MenuFlyout.Items>
<MenuItem x:Name="MenuItemCreateUpdate" Header="{x:Static langRes:GeneralLangRes.CreateUpdate}" Click="MenuItemCreateUpdate_OnClick"/>
<MenuItem x:Name="MenuItemRemoveUpdate" Header="{x:Static langRes:GeneralLangRes.RemoveUpdate}" Click="MenuItemRemoveUpdate_OnClick"/>
</MenuFlyout.Items>
</MenuFlyout>
</pilz:ImageButton.Flyout>
</pilz:ImageButton>
<!-- Button: Tools -->
<pilz:ImageButton
x:Name="ButtonTools"
Text="{x:Static langRes:GeneralLangRes.Tools}"
Background="Transparent"/>
</StackPanel>
<!-- TreeView: Workspace -->
<ScrollViewer
Grid.Column="0"
Grid.Row="1"
VerticalScrollBarVisibility="Auto">
<StackPanel>
<TreeView
ItemsSource="{Binding CurrentTreeNodes}"
SelectedItem="{Binding SelectedTreeNode}">
<TreeView.ItemTemplate>
<TreeDataTemplate
ItemsSource="{Binding Nodes}">
<StackPanel Orientation="Horizontal" Spacing="6">
<Image
Source="{Binding Image}"
Width="{x:Static symbols:SymbolGlobals.DefaultImageSmallSize}"/>
<TextBlock Text="{Binding DisplayText}"/>
</StackPanel>
</TreeDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
</StackPanel>
</ScrollViewer>
<!-- Panel: List header -->
<StackPanel
Grid.Column="1"
Grid.Row="0"
Spacing="6"
Orientation="Horizontal"
VerticalAlignment="Center">
<!-- Panel: Menu -->
<ContentControl
Content="{Binding SelectedTreeNode}">
<ContentControl.DataTemplates>
<DataTemplate
DataType="mainWindow:ActionSetTreeNode">
<StackPanel
Orientation="Horizontal">
<!-- Button: Add action -->
<pilz:ImageButton
x:Name="ButtonAddAction"
Text="{x:Static langRes:GeneralLangRes.Add}"
ImageSource="{x:Static local:MainWindow.ButtonImageAddAction}"
Background="Transparent"
Click="ButtonAddAction_OnClick"/>
<!-- Button: Remove action -->
<pilz:ImageButton
x:Name="ButtonRemoveAction"
Text="{x:Static langRes:GeneralLangRes.Remove}"
ImageSource="{x:Static local:MainWindow.ButtonImageRemoveAction}"
Background="Transparent"
Click="ButtonRemoveAction_OnClick"/>
<!-- TextBox: Version -->
<TextBox
Margin="3, 0, 3, 0"
Width="100"
Text="{Binding Version}"/>
<!-- CheckBox: Is public -->
<CheckBox
Margin="3, 0, 3, 0"
Content="{x:Static langRes:GeneralLangRes.Public}"
IsChecked="{Binding IsPublic}"/>
</StackPanel>
</DataTemplate>
<DataTemplate
DataType="mainWindow:MainWindowTreeNode"/>
</ContentControl.DataTemplates>
</ContentControl>
<!-- ProgressBar: Status -->
<ProgressBar
HorizontalAlignment="Left"
VerticalAlignment="Stretch"
Maximum="{Binding Progress.MaxValue}"
Value="{Binding Progress.Value}"
ShowProgressText="{Binding Progress.ShowText}"
IsIndeterminate="{Binding Progress.IsGeneric}"
IsVisible="{Binding Progress.IsVisible}"/>
</StackPanel>
<!-- DataGrid -->
<DataGrid
Grid.Column="1"
Grid.Row="1"
x:Name="DataGridActions"
VerticalAlignment="Stretch"
ItemsSource="{Binding CurrentGridRows}"
SelectedItem="{Binding SelectedGridRow}">
<DataGrid.ContextMenu>
<ContextMenu x:Name="ContextMenuActions"/>
</DataGrid.ContextMenu>
<DataGrid.Columns>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.Id}"
Binding="{Binding InheritedId}"/>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.Side}"
Binding="{Binding InheritedSide}"/>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.UpdateType}"
Binding="{Binding InheritedUpdateType}"
IsVisible="{Binding IsUpdate}"/>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.SourceType}"
Binding="{Binding InheritedSourceType}"/>
<DataGridTextColumn
Header="{x:Static langRes:GeneralLangRes.DestinationPath}"
Binding="{Binding InheritedDestPath}"/>
<DataGridTemplateColumn
Header="{x:Static langRes:GeneralLangRes.State}">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Image
Width="{x:Static symbols:SymbolGlobals.DefaultImageSmallSize}"
Source="{Binding StateImage}"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<!-- Action editor -->
<ScrollViewer
x:Name="ScrollViewerInstallAction"
Grid.Column="2"
Grid.Row="1"
DataContext="{Binding SelectedGridRow}"
VerticalScrollBarVisibility="Auto">
<StackPanel
Spacing="6">
<!-- Update -->
<Grid
ColumnDefinitions="150,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto"
RowSpacing="6"
ColumnSpacing="6"
IsVisible="{Binding IsUpdate}">
<!-- Header -->
<StackPanel
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="6">
<Image x:Name="ImageUpdate" Width="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.Update}" FontSize="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
</StackPanel>
<!-- Inherit from -->
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.InheritFrom}" Target="TextBoxUpdateActionInheritFrom"/>
<TextBox
Grid.Row="1" Grid.Column="1"
x:Name="TextBoxUpdateActionInheritFrom"
Text="{Binding InheritFrom}"/>
<!-- Update type -->
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.UpdateType}" Target="ComboBoxUpdateActionSourceType"/>
<ComboBox
Grid.Row="2" Grid.Column="1"
x:Name="ComboBoxUpdateActionSourceType"
ItemsSource="{x:Static mainWindow:MainWindowGridRow.UpdateActionTypes}"
DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding UpdateType}"/>
<!-- Source path -->
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourcePath}" Target="TextBoxInstallActionSourcePath"/>
<TextBox
Grid.Row="3" Grid.Column="1"
x:Name="TextBoxInstallActionSourcePath"
Text="{Binding SrcPath}"/>
<!-- Is Directory -->
<CheckBox Grid.Row="4" Grid.Column="1"
x:Name="CheckBoxUpdateActionIsDir"
Content="{x:Static langRes:GeneralLangRes.IsDirectory}"
IsChecked="{Binding IsDirectory}"/>
</Grid>
<!-- General -->
<Grid
ColumnDefinitions="150,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto"
RowSpacing="6"
ColumnSpacing="6">
<!-- Header -->
<StackPanel
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="6">
<Image
x:Name="ImageGeneral"
Width="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.General}" FontSize="20"/>
</StackPanel>
<!-- Id -->
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.Id}" Target="TextBoxInstallActionId"/>
<TextBox
Grid.Row="1" Grid.Column="1"
x:Name="TextBoxInstallActionId"
Text="{Binding Id}"/>
<!-- Name -->
<Label Grid.Row="2" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.Name}" Target="TextBoxInstallActionName"/>
<TextBox
Grid.Row="2" Grid.Column="1"
x:Name="TextBoxInstallActionName"
Text="{Binding Name}"/>
<!-- Side -->
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.Side}" Target="ComboBoxInstallActionSide"/>
<ComboBox
Grid.Row="3" Grid.Column="1"
x:Name="ComboBoxInstallActionSide"
ItemsSource="{x:Static mainWindow:MainWindowGridRow.Sides}"
DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding Side}"/>
<!-- Is Extra -->
<CheckBox
Grid.Row="4" Grid.Column="1"
x:Name="CheckBoxInstallActionIsExtra"
Content="{x:Static langRes:GeneralLangRes.IsExtra}"
IsChecked="{Binding IsExtra}"/>
</Grid>
<!-- Destination -->
<Grid
ColumnDefinitions="150,*"
RowDefinitions="Auto,Auto"
RowSpacing="6"
ColumnSpacing="6">
<!-- Header -->
<StackPanel
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="6">
<Image
x:Name="ImageDestination"
Width="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.Destination}" FontSize="20"/>
</StackPanel>
<!-- Destination path -->
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.DestinationPath}" Target="TextBoxInstallDestPath"/>
<TextBox
Grid.Row="1" Grid.Column="1"
x:Name="TextBoxInstallDestPath"
Text="{Binding DestPath}"/>
</Grid>
<!-- Source -->
<Grid
ColumnDefinitions="150,*"
RowDefinitions="Auto,Auto,Auto,Auto,Auto,Auto,Auto,Auto"
RowSpacing="6"
ColumnSpacing="6">
<!-- Header -->
<StackPanel
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="6">
<Image
x:Name="ImageSource"
Width="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.Source}" FontSize="20"/>
</StackPanel>
<!-- Source types -->
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceType}" Target="CheckBoxInstallActionSourceType"/>
<ComboBox
Grid.Row="1" Grid.Column="1"
x:Name="CheckBoxInstallActionSourceType"
ItemsSource="{x:Static mainWindow:MainWindowGridRow.SourceTypes}"
DisplayMemberBinding="{Binding Value}"
SelectedValueBinding="{Binding Key}"
SelectedValue="{Binding SourceType}"/>
<!-- Is Zip -->
<CheckBox Grid.Row="2" Grid.Column="1"
x:Name="CheckBoxInstallActionIsZip"
Content="{x:Static langRes:GeneralLangRes.IsZipArchive}"
IsChecked="{Binding IsZip}"/>
<!-- Source owner -->
<Label Grid.Row="3" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceOwner}" Target="TextBoxInstallActionSourceOwner"/>
<TextBox
Grid.Row="3" Grid.Column="1"
x:Name="TextBoxInstallActionSourceOwner"
Text="{Binding SourceOwner}"/>
<!-- Source name -->
<Label Grid.Row="4" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceName}" Target="TextBoxInstallActionSourceName"/>
<TextBox
Grid.Row="4" Grid.Column="1"
x:Name="TextBoxInstallActionSourceName"
Text="{Binding SourceName}"/>
<!-- Source RegEx -->
<Label Grid.Row="5" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceRegex}" Target="TextBoxInstallActionSourceRegEx"/>
<TextBox
Grid.Row="5" Grid.Column="1"
x:Name="TextBoxInstallActionSourceRegEx"
Text="{Binding SourceRegex}"/>
<!-- Source url -->
<Label Grid.Row="6" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.SourceUrl}" Target="TextBoxInstallActionSourceUrl"/>
<TextBox
Grid.Row="6" Grid.Column="1"
x:Name="TextBoxInstallActionSourceUrl" Text="{Binding SourceUrl}"/>
<!-- Zip archive path -->
<Label Grid.Row="7" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.ZipArchivePath}" Target="TextBoxInstallActionZipArchivePath"/>
<TextBox
Grid.Row="7" Grid.Column="1"
x:Name="TextBoxInstallActionZipArchivePath"
Text="{Binding SourceUrl}"/>
</Grid>
<!-- Metadata -->
<Grid
ColumnDefinitions="150,*"
RowDefinitions="Auto,Auto"
RowSpacing="6"
ColumnSpacing="6"
VerticalAlignment="Center">
<!-- Header -->
<StackPanel
Grid.ColumnSpan="2"
Orientation="Horizontal"
Spacing="6">
<Image
x:Name="ImageMetadata"
Width="{x:Static symbols:SymbolGlobals.DefaultImageMediumSize}"/>
<TextBlock Text="{x:Static langRes:GeneralLangRes.Metadata}" FontSize="20"/>
</StackPanel>
<!-- Website -->
<Label Grid.Row="1" Grid.Column="0" Content="{x:Static langRes:GeneralLangRes.Website}" Target="TextBoxInstallActionWebsite"/>
<TextBox
Grid.Row="1" Grid.Column="1"
x:Name="TextBoxInstallActionWebsite"
Text="{Binding Website}"/>
</Grid>
</StackPanel>
</ScrollViewer>
</Grid>
</Window>

View File

@@ -0,0 +1,267 @@
using System.Reflection;
using Avalonia.Controls;
using Avalonia.Input;
using Avalonia.Interactivity;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.Api;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
using ModpackUpdater.Apps.Manager.Api.Plugins.Params;
using ModpackUpdater.Apps.Manager.Settings;
using ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
using Pilz.Extensions;
using Pilz.Features;
using Pilz.UI.AvaloniaUI.Features;
using Pilz.UI.Symbols;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class MainWindow : Window, IMainApi
{
public static IImage? ButtonImageAddAction => AppGlobals.Symbols.GetImageSource(AppSymbols.add);
public static IImage? ButtonImageRemoveAction => AppGlobals.Symbols.GetImageSource(AppSymbols.remove);
private WorkspaceFeature? curWs;
public MainWindowViewModel Model { get; } = new();
Window IMainApi.MainWindow => this;
public IMainApi MainApi => this;
public bool HasClosed { get; private set; }
public MainWindow()
{
InitializeComponent();
Title = $"{Title} (v{Assembly.GetExecutingAssembly().GetAppVersion().ToShortString()})";
GridMain.DataContext = Model;
ButtonWorkspace.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.workspace);
MenuItemWorkspacePreferences.Icon = AppGlobals.Symbols.GetImage(AppSymbols.settings, SymbolSize.Small);
MenuItemSaveWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.save, SymbolSize.Small);
MenuItemNewWorkspace.Icon = AppGlobals.Symbols.GetImage(AppSymbols.new_window, SymbolSize.Small);
MenuItemRecentWorkspaces.Icon = AppGlobals.Symbols.GetImage(AppSymbols.time_machine, SymbolSize.Small);
ButtonUpdate.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ButtonTools.ImageSource = AppGlobals.Symbols.GetImageSource(AppSymbols.tools);
MenuItemCreateUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.add, SymbolSize.Small);
MenuItemRemoveUpdate.Icon = AppGlobals.Symbols.GetImage(AppSymbols.remove, SymbolSize.Small);
ImageUpdate.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done);
ImageMetadata.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.show_property);
ImageGeneral.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.normal_screen);
ImageSource.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.input);
ImageDestination.Source = AppGlobals.Symbols.GetImageSource(AppSymbols.output);
PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).Ordered().InsertItemsTo(MenuItemNewWorkspace.Items,
customClickHandler: MenuItemNewWorkspaceItem_Click,
insertPrioSplitters: true);
PluginFeatureController.Instance.Features.Get(FeatureTypes.ActionsContextMenu).Ordered().InsertItemsTo(ContextMenuActions.Items,
customClickHandler: MenuItemActionItem_Click,
insertPrioSplitters: true);
var menuFlyoutTools = new MenuFlyout();
ButtonTools.Flyout = menuFlyoutTools;
PluginFeatureController.Instance.Functions.Get(FeatureTypes.Tools).InsertItemsTo(menuFlyoutTools.Items,
customClickHandler: MenuItemToolsItem_Click,
insertPrioSplitters: true);
}
private async Task LoadNewWorkspace(IWorkspace? workspace, WorkspaceFeature feature)
{
if (workspace is null)
return;
if (!await workspace.Load())
return;
if (workspace != Model.CurrentWorkspace)
{
Model.CurrentWorkspace = workspace;
curWs = feature;
}
AddToRecentFiles(workspace);
LoadRecentWorkspaces();
}
private async Task SaveWorkspace()
{
if (Model.CurrentWorkspace is not { } ws)
return;
Model.Progress.Start();
await ws.Save();
Model.Progress.Stop();
}
private void LoadRecentWorkspaces()
{
var settings = Program.Settings.Get<WorkspaceSettings>();
MenuItemRecentWorkspaces.Items.Clear();
settings.Workspaces.ForEach(config =>
{
if (PluginFeatureController.Instance.Features.Get(FeatureTypes.Workspace).OfType<WorkspaceFeature>().FirstOrDefault(n => n.Identifier == config.ProviderId) is not WorkspaceFeature feature)
return;
var item = new MenuItem
{
Header = config.DisplayText,
Icon = feature.Icon,
DataContext = new MainWindowRecentFilesItem(config, feature),
};
item.Click += MenuItemRecentWorkspaceItem_Click;
MenuItemRecentWorkspaces.Items.Add(item);
});
}
private static void AddToRecentFiles(IWorkspace workspace)
{
var settings = Program.Settings.Get<WorkspaceSettings>();
settings.Workspaces.Remove(workspace.Config);
settings.Workspaces.Insert(0, workspace.Config);
while (settings.Workspaces.Count > 20)
settings.Workspaces.RemoveAt(20);
}
private async void Window_OnLoaded(object? sender, RoutedEventArgs e)
{
var updater = new AppUpdates(Program.UpdateUrl, this);
updater.OnDownloadProgramUpdate += (o, args) => Model.Progress.Start();
await updater.UpdateApp();
Model.Progress.Stop();
LoadRecentWorkspaces();
}
private void Window_OnClosed(object? sender, EventArgs e)
{
HasClosed = true;
}
private async void Window_OnKeyDown(object? sender, KeyEventArgs e)
{
if (e.KeyModifiers == KeyModifiers.Control && e.Key == Key.Space)
await SaveWorkspace();
}
private async void MenuItemNewWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is not MenuItem item || item.Tag is not WorkspaceFeature feature)
return;
var context = new WorkspaceContext(MainApi, null);
await feature.Configure(context);
if (!context.Canceled)
await LoadNewWorkspace(context.Workspace, feature);
}
private async void MenuItemWorkspacePreferences_OnClick(object? sender, RoutedEventArgs e)
{
if (curWs is null || Model.CurrentWorkspace is null)
return;
var context = new WorkspaceContext(MainApi, Model.CurrentWorkspace);
await curWs.Configure(context);
if (!context.Canceled)
await LoadNewWorkspace(context.Workspace, curWs);
}
private async void MenuItemSaveWorkspace_OnClick(object? sender, RoutedEventArgs e)
{
await SaveWorkspace();
}
private async void MenuItemRecentWorkspaceItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.DataContext is MainWindowRecentFilesItem tag && tag.Feature.CreateFromConfig(tag.Config) is IWorkspace workspace)
await LoadNewWorkspace(workspace, tag.Feature);
}
private async void MenuItemToolsItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.Tag is PluginFunction func)
await func.ExecuteAsync(new MainApiParameters(this));
}
private async void MenuItemActionItem_Click(object? sender, RoutedEventArgs e)
{
if (sender is MenuItem item && item.Tag is PluginFunction func)
await func.ExecuteAsync(new MainApiParameters(this));
}
private void MenuItemCreateUpdate_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.UpdateInfos is null
|| Model.CurrentTreeNodes?.ElementAtOrDefault(1) is not { } nodeUpdates)
return;
var update = new UpdateInfo
{
Version = new(),
};
Model.CurrentWorkspace.UpdateInfos.Updates.Insert(0, update);
nodeUpdates.Nodes.Insert(0, new ActionSetTreeNode(update));
}
private void MenuItemRemoveUpdate_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.UpdateInfos is null
|| Model.CurrentTreeNodes?.ElementAtOrDefault(1) is not { } nodeUpdates
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| nodeUpdate.Infos is not UpdateInfo update)
return;
nodeUpdates.Nodes.Remove(nodeUpdate);
Model.CurrentWorkspace.UpdateInfos.Updates.Remove(update);
}
private void ButtonAddAction_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.CurrentWorkspace?.InstallInfos is not { } rootInfos
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| Model.CurrentGridRows is not { } rows)
return;
InstallAction action;
switch (nodeUpdate.Infos)
{
case UpdateInfo updateInfos:
updateInfos.Actions.Add((UpdateAction)(action = new UpdateAction()));
break;
case InstallInfos installInfos:
installInfos.Actions.Add(action = new InstallAction());
break;
default:
return;
}
rows.Add(new MainWindowGridRow(action, rootInfos));
}
private void ButtonRemoveAction_OnClick(object? sender, RoutedEventArgs e)
{
if (Model.SelectedGridRow is not { } row
|| Model.SelectedTreeNode is not ActionSetTreeNode nodeUpdate
|| Model.CurrentGridRows is not { } rows)
return;
switch (nodeUpdate.Infos)
{
case UpdateInfo updateInfos:
if (row.Action is UpdateAction action)
updateInfos.Actions.Remove(action);
break;
case InstallInfos installInfos:
installInfos.Actions.Remove(row.Action);
break;
default:
return;
}
rows.Remove(row);
}
}

View File

@@ -0,0 +1,158 @@
using System.ComponentModel;
using Avalonia.Media;
using ModpackUpdater.Apps.Manager.LangRes;
using ModpackUpdater.Apps.Manager.Utils;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
public class MainWindowGridRow(InstallAction action, IActionSet baseActions) : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public static Dictionary<SourceType, string> SourceTypes { get; } = Enum.GetValues<SourceType>().ToDictionary(n => n, n => SourceTypeLangRes.ResourceManager.GetString( Enum.GetName(n)!)!);
public static Dictionary<Side, string> Sides { get; } = Enum.GetValues<Side>().ToDictionary(n => n, n => SideLangRes.ResourceManager.GetString(Enum.GetName(n)!)!);
public static Dictionary<UpdateActionType, string> UpdateActionTypes { get; } = Enum.GetValues<UpdateActionType>().ToDictionary(n => n, n => UpdateActionTypeLangRes.ResourceManager.GetString(Enum.GetName(n)!)!);
public InstallAction Action => action;
private InstallAction? Base => action is UpdateAction ua ? baseActions.Actions.FirstOrDefault(n => n.Id == ua.InheritFrom) : null;
private InstallAction Inherited => Base ?? action;
public bool IsUpdate => action is UpdateAction;
public IImage? StateImage { get; set; }
[DependsOn(nameof(Id), nameof(InheritFrom))]
public string? InheritedId => action is UpdateAction ua && !string.IsNullOrWhiteSpace(ua.InheritFrom) ? ua.InheritFrom : action.Id;
[DependsOn(nameof(Side), nameof(InheritedId), nameof(Id))]
public string InheritedSide => Sides[Inherited.Side];
[DependsOn(nameof(UpdateType), nameof(InheritedId), nameof(Id))]
public string InheritedUpdateType => action is UpdateAction ua ? UpdateActionTypes[ua.Type] : string.Empty;
[DependsOn(nameof(SourceType), nameof(InheritedId), nameof(Id))]
public string InheritedSourceType => SourceTypes[Inherited.SourceType];
[DependsOn(nameof(DestPath), nameof(InheritedId), nameof(Id))]
public string? InheritedDestPath => Inherited.DestPath;
public string? Id
{
get => action.Id;
set => action.Id = value?.Trim().Nullify();
}
public string? Name
{
get => action.Name;
set => action.Name = value?.Trim().Nullify();
}
public string? Website
{
get => action.Website;
set => action.Website = value?.Trim().Nullify();
}
public bool IsZip
{
get => action.IsZip;
set => action.IsZip = value;
}
public string? ZipPath
{
get => action.ZipPath;
set => action.ZipPath = value?.Trim().Nullify();
}
public string? DestPath
{
get => action.DestPath;
set => action.DestPath = value?.Trim().Nullify();
}
public string? SourceUrl
{
get => action.SourceUrl;
set => action.SourceUrl = value?.Trim().Nullify();
}
public SourceType SourceType
{
get => action.SourceType;
set => action.SourceType = value;
}
public string? SourceOwner
{
get => action.SourceOwner;
set => action.SourceOwner = value?.Trim().Nullify();
}
public string? SourceName
{
get => action.SourceName;
set => action.SourceName = value?.Trim().Nullify();
}
public string? SourceRegex
{
get => action.SourceRegex;
set => action.SourceRegex = value?.Trim().Nullify();
}
public string? SourceTag
{
get => action.SourceTag;
set => action.SourceTag = value?.Trim().Nullify();
}
public Side Side
{
get => action.Side;
set => action.Side = value;
}
public bool IsExtra
{
get => action.IsExtra;
set => action.IsExtra = value;
}
public UpdateActionType UpdateType
{
get => action is UpdateAction ua ? ua.Type : default;
set
{
if (action is UpdateAction ua)
ua.Type = value;
}
}
public string? SrcPath
{
get => (action as UpdateAction)?.SrcPath;
set
{
if (action is UpdateAction ua)
ua.SrcPath = value?.Trim().Nullify();
}
}
public bool IsDirectory
{
get => action is UpdateAction ua && ua.IsDirectory;
set
{
if (action is UpdateAction ua)
ua.IsDirectory = value;
}
}
public string? InheritFrom
{
get => (action as UpdateAction)?.InheritFrom;
set
{
if (action is UpdateAction ua)
ua.InheritFrom = value?.Trim().Nullify();
}
}
}

View File

@@ -0,0 +1,6 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Api.Plugins.Features;
namespace ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
public record class MainWindowRecentFilesItem(WorkspaceConfig Config, WorkspaceFeature Feature);

View File

@@ -0,0 +1,61 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Runtime.CompilerServices;
using Avalonia.Media;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
public abstract class MainWindowTreeNode : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public abstract string DisplayText { get; }
public virtual IImage? Image { get; set; }
public ObservableCollection<MainWindowTreeNode> Nodes { get; init; } = [];
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
protected bool SetField<T>(ref T field, T value, [CallerMemberName] string? propertyName = null)
{
if (EqualityComparer<T>.Default.Equals(field, value)) return false;
field = value;
OnPropertyChanged(propertyName);
return true;
}
}
public class SimpleMainWindowTreeNode(string text) : MainWindowTreeNode
{
public override string DisplayText => text;
}
public class ActionSetTreeNode(IActionSetInfos infos) : MainWindowTreeNode
{
private string editVersion = infos.Version?.ToString() ?? string.Empty;
public override string DisplayText => infos.Version?.ToString() ?? string.Empty;
public IActionSetInfos Infos => infos;
public override IImage? Image => AppGlobals.Symbols.GetImageSource(infos.IsPublic ? AppSymbols.eye : AppSymbols.invisible);
[AlsoNotifyFor(nameof(DisplayText))]
public string Version
{
get => editVersion;
set
{
infos.Version = System.Version.TryParse(value, out var v) ? v : new();
editVersion = value;
}
}
[AlsoNotifyFor(nameof(Image))]
public bool IsPublic
{
get => infos.IsPublic;
set => infos.IsPublic = value;
}
}

View File

@@ -0,0 +1,71 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.LangRes;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models.MainWindow;
public class MainWindowViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
private ObservableCollection<MainWindowTreeNode>? currentTreeNodes;
private ObservableCollection<MainWindowGridRow>? currentGridRows;
private MainWindowTreeNode? selectedTreeNode;
private IWorkspace? currentWorkspace;
public bool IsUpdate => selectedTreeNode is ActionSetTreeNode node && node.Infos is UpdateInfo;
public ProgressInfos Progress { get; } = new();
public MainWindowGridRow? SelectedGridRow { get; set; }
[AlsoNotifyFor(nameof(CurrentTreeNodes))]
public IWorkspace? CurrentWorkspace
{
get => currentWorkspace;
set
{
currentTreeNodes = null;
currentWorkspace = value;
}
}
public ObservableCollection<MainWindowTreeNode>? CurrentTreeNodes
{
get
{
if (currentTreeNodes == null && currentWorkspace?.InstallInfos != null && currentWorkspace?.UpdateInfos != null)
currentTreeNodes =
[
new ActionSetTreeNode(currentWorkspace.InstallInfos),
new SimpleMainWindowTreeNode(GeneralLangRes.Updates)
{
Image = AppGlobals.Symbols.GetImageSource(AppSymbols.update_done),
Nodes = [.. currentWorkspace.UpdateInfos.Updates.Select(n => new ActionSetTreeNode(n))],
},
];
return currentTreeNodes;
}
}
[AlsoNotifyFor(nameof(CurrentGridRows))]
public MainWindowTreeNode? SelectedTreeNode
{
get => selectedTreeNode;
set
{
currentGridRows = null;
selectedTreeNode = value;
}
}
public ObservableCollection<MainWindowGridRow>? CurrentGridRows
{
get
{
if (currentGridRows == null && CurrentWorkspace?.InstallInfos != null && selectedTreeNode is ActionSetTreeNode node)
currentGridRows = [.. node.Infos.Actions.Select(n => new MainWindowGridRow(n, CurrentWorkspace.InstallInfos))];
return currentGridRows;
}
}
}

View File

@@ -0,0 +1,48 @@
using System.ComponentModel;
namespace ModpackUpdater.Apps.Manager.Ui.Models;
public class ProgressInfos : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public bool IsVisible { get; set; }
public bool IsGeneric { get; set; }
public bool ShowText { get; set; }
public double MaxValue { get; set; }
public double Value { get; set; }
public void Start(int maxValue)
{
IsGeneric = false;
Value = 0;
MaxValue = maxValue;
ShowText = true;
IsVisible = true;
}
public void Start()
{
ShowText = false;
IsGeneric = true;
IsVisible = true;
}
public void Set(int value)
{
if (!IsGeneric)
Value = value;
}
public void Increment()
{
if (!IsGeneric)
Value += 1;
}
public void Stop()
{
IsVisible = false;
IsGeneric = false;
}
}

View File

@@ -0,0 +1,18 @@
using System.ComponentModel;
namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
public record ModUpdateInfo(KeyValuePair<string, string>[] AvailableVersions, InstallAction Origin) : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public int NewVersion { get; set; }
public bool Visible { get; set; } = true;
public IEnumerable<string> DisplayVersions { get; } = AvailableVersions.Select(n =>
{
if (string.IsNullOrWhiteSpace(n.Value) || n.Value.Equals(n.Key, StringComparison.InvariantCulture))
return n.Key;
return $"{n.Value} ({n.Value})";
});
}

View File

@@ -0,0 +1,3 @@
namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
public record ModUpdates(IList<ModUpdateInfo> List);

View File

@@ -0,0 +1,14 @@
using System.Collections.ObjectModel;
using System.ComponentModel;
using PropertyChanged;
namespace ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
public class UpdatesCollectorViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler? PropertyChanged;
public ProgressInfos Progress { get; } = new();
public string? SearchText { get; set; }
public ObservableCollection<ModUpdateInfo> Updates { get; } = [];
}

View File

@@ -1,268 +0,0 @@
namespace ModpackUpdater.Apps.Manager.Ui;
partial class UpdatesCollectorUi
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
var listViewDetailColumn1 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 0", "Name");
var listViewDetailColumn2 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 1", "Current version");
var listViewDetailColumn3 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 2", "New version");
var listViewDetailColumn4 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 0", "Release");
var listViewDetailColumn5 = new Telerik.WinControls.UI.ListViewDetailColumn("Column 1", "Tag");
var resources = new System.ComponentModel.ComponentResourceManager(typeof(UpdatesCollectorUi));
tableLayoutPanel1 = new TableLayoutPanel();
radButton_Continue = new Telerik.WinControls.UI.RadButton();
radProgressBar1 = new Telerik.WinControls.UI.RadProgressBar();
radSplitContainer1 = new Telerik.WinControls.UI.RadSplitContainer();
splitPanel1 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel2 = new TableLayoutPanel();
radListView_Updates = new Telerik.WinControls.UI.RadListView();
splitPanel2 = new Telerik.WinControls.UI.SplitPanel();
tableLayoutPanel3 = new TableLayoutPanel();
radListView_VersionTags = new Telerik.WinControls.UI.RadListView();
radWaitingBar1 = new Telerik.WinControls.UI.RadWaitingBar();
dotsSpinnerWaitingBarIndicatorElement1 = new Telerik.WinControls.UI.DotsSpinnerWaitingBarIndicatorElement();
tableLayoutPanel1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radButton_Continue).BeginInit();
((System.ComponentModel.ISupportInitialize)radProgressBar1).BeginInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).BeginInit();
radSplitContainer1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)splitPanel1).BeginInit();
splitPanel1.SuspendLayout();
tableLayoutPanel2.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListView_Updates).BeginInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).BeginInit();
splitPanel2.SuspendLayout();
tableLayoutPanel3.SuspendLayout();
((System.ComponentModel.ISupportInitialize)radListView_VersionTags).BeginInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar1).BeginInit();
((System.ComponentModel.ISupportInitialize)this).BeginInit();
SuspendLayout();
//
// tableLayoutPanel1
//
tableLayoutPanel1.AutoSize = true;
tableLayoutPanel1.ColumnCount = 3;
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 200F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel1.ColumnStyles.Add(new ColumnStyle());
tableLayoutPanel1.Controls.Add(radButton_Continue, 2, 0);
tableLayoutPanel1.Controls.Add(radProgressBar1, 0, 0);
tableLayoutPanel1.Dock = DockStyle.Bottom;
tableLayoutPanel1.Location = new Point(0, 419);
tableLayoutPanel1.Name = "tableLayoutPanel1";
tableLayoutPanel1.RowCount = 1;
tableLayoutPanel1.RowStyles.Add(new RowStyle());
tableLayoutPanel1.Size = new Size(800, 30);
tableLayoutPanel1.TabIndex = 0;
//
// radButton_Continue
//
radButton_Continue.Anchor = AnchorStyles.Top | AnchorStyles.Right;
radButton_Continue.DialogResult = DialogResult.OK;
radButton_Continue.ImageAlignment = ContentAlignment.MiddleRight;
radButton_Continue.Location = new Point(647, 3);
radButton_Continue.Name = "radButton_Continue";
radButton_Continue.Size = new Size(150, 24);
radButton_Continue.TabIndex = 0;
radButton_Continue.Text = "Continue";
radButton_Continue.TextAlignment = ContentAlignment.MiddleLeft;
radButton_Continue.TextImageRelation = TextImageRelation.ImageBeforeText;
//
// radProgressBar1
//
radProgressBar1.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
radProgressBar1.Location = new Point(3, 3);
radProgressBar1.Name = "radProgressBar1";
radProgressBar1.Size = new Size(194, 24);
radProgressBar1.TabIndex = 2;
radProgressBar1.Visible = false;
//
// radSplitContainer1
//
radSplitContainer1.Controls.Add(splitPanel1);
radSplitContainer1.Controls.Add(splitPanel2);
radSplitContainer1.Dock = DockStyle.Fill;
radSplitContainer1.Location = new Point(0, 0);
radSplitContainer1.Name = "radSplitContainer1";
radSplitContainer1.Size = new Size(800, 419);
radSplitContainer1.TabIndex = 1;
radSplitContainer1.TabStop = false;
//
// splitPanel1
//
splitPanel1.Controls.Add(tableLayoutPanel2);
splitPanel1.Location = new Point(0, 0);
splitPanel1.Name = "splitPanel1";
splitPanel1.Size = new Size(516, 419);
splitPanel1.SizeInfo.AutoSizeScale = new SizeF(0.148241222F, 0F);
splitPanel1.SizeInfo.SplitterCorrection = new Size(118, 0);
splitPanel1.TabIndex = 0;
splitPanel1.TabStop = false;
splitPanel1.Text = "splitPanel1";
//
// tableLayoutPanel2
//
tableLayoutPanel2.ColumnCount = 1;
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel2.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tableLayoutPanel2.Controls.Add(radListView_Updates, 0, 0);
tableLayoutPanel2.Dock = DockStyle.Fill;
tableLayoutPanel2.Location = new Point(0, 0);
tableLayoutPanel2.Name = "tableLayoutPanel2";
tableLayoutPanel2.RowCount = 1;
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel2.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel2.Size = new Size(516, 419);
tableLayoutPanel2.TabIndex = 1;
//
// radListView_Updates
//
radListView_Updates.AllowEdit = false;
radListView_Updates.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
listViewDetailColumn1.HeaderText = "Name";
listViewDetailColumn2.HeaderText = "Current version";
listViewDetailColumn2.Width = 120F;
listViewDetailColumn3.HeaderText = "New version";
listViewDetailColumn3.Width = 120F;
radListView_Updates.Columns.AddRange(new Telerik.WinControls.UI.ListViewDetailColumn[] { listViewDetailColumn1, listViewDetailColumn2, listViewDetailColumn3 });
radListView_Updates.ItemSpacing = -1;
radListView_Updates.Location = new Point(3, 3);
radListView_Updates.Name = "radListView_Updates";
radListView_Updates.Size = new Size(510, 413);
radListView_Updates.TabIndex = 0;
radListView_Updates.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_Updates.SelectedItemChanged += RadListView_Updates_SelectedItemChanged;
radListView_Updates.ItemRemoved += RadListView_Updates_ItemRemoved;
//
// splitPanel2
//
splitPanel2.Controls.Add(tableLayoutPanel3);
splitPanel2.Location = new Point(520, 0);
splitPanel2.Name = "splitPanel2";
splitPanel2.Size = new Size(280, 419);
splitPanel2.SizeInfo.AutoSizeScale = new SizeF(-0.148241192F, 0F);
splitPanel2.SizeInfo.SplitterCorrection = new Size(-118, 0);
splitPanel2.TabIndex = 1;
splitPanel2.TabStop = false;
splitPanel2.Text = "splitPanel2";
//
// tableLayoutPanel3
//
tableLayoutPanel3.ColumnCount = 1;
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Percent, 100F));
tableLayoutPanel3.ColumnStyles.Add(new ColumnStyle(SizeType.Absolute, 20F));
tableLayoutPanel3.Controls.Add(radListView_VersionTags, 0, 0);
tableLayoutPanel3.Dock = DockStyle.Fill;
tableLayoutPanel3.Location = new Point(0, 0);
tableLayoutPanel3.Name = "tableLayoutPanel3";
tableLayoutPanel3.RowCount = 1;
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Percent, 100F));
tableLayoutPanel3.RowStyles.Add(new RowStyle(SizeType.Absolute, 20F));
tableLayoutPanel3.Size = new Size(280, 419);
tableLayoutPanel3.TabIndex = 0;
//
// radListView_VersionTags
//
radListView_VersionTags.AllowEdit = false;
radListView_VersionTags.AllowRemove = false;
radListView_VersionTags.Anchor = AnchorStyles.Top | AnchorStyles.Bottom | AnchorStyles.Left | AnchorStyles.Right;
listViewDetailColumn4.HeaderText = "Release";
listViewDetailColumn5.HeaderText = "Tag";
radListView_VersionTags.Columns.AddRange(new Telerik.WinControls.UI.ListViewDetailColumn[] { listViewDetailColumn4, listViewDetailColumn5 });
radListView_VersionTags.ItemSpacing = -1;
radListView_VersionTags.Location = new Point(3, 3);
radListView_VersionTags.Name = "radListView_VersionTags";
radListView_VersionTags.Size = new Size(274, 413);
radListView_VersionTags.TabIndex = 0;
radListView_VersionTags.ViewType = Telerik.WinControls.UI.ListViewType.DetailsView;
radListView_VersionTags.SelectedIndexChanged += RadListView_VersionTags_SelectedIndexChanged;
//
// radWaitingBar1
//
radWaitingBar1.AssociatedControl = radListView_Updates;
radWaitingBar1.Location = new Point(220, 171);
radWaitingBar1.Name = "radWaitingBar1";
radWaitingBar1.Size = new Size(70, 70);
radWaitingBar1.TabIndex = 2;
radWaitingBar1.Text = "radWaitingBar1";
radWaitingBar1.WaitingIndicators.Add(dotsSpinnerWaitingBarIndicatorElement1);
radWaitingBar1.WaitingIndicatorSize = new Size(100, 14);
radWaitingBar1.WaitingSpeed = 100;
radWaitingBar1.WaitingStyle = Telerik.WinControls.Enumerations.WaitingBarStyles.DotsSpinner;
//
// dotsSpinnerWaitingBarIndicatorElement1
//
dotsSpinnerWaitingBarIndicatorElement1.Name = "dotsSpinnerWaitingBarIndicatorElement1";
//
// UpdatesCollectorUi
//
AutoScaleBaseSize = new Size(7, 15);
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(800, 449);
Controls.Add(radSplitContainer1);
Controls.Add(tableLayoutPanel1);
Icon = (Icon)resources.GetObject("$this.Icon");
Name = "UpdatesCollectorUi";
StartPosition = FormStartPosition.CenterParent;
Text = "Find updates";
Shown += UpdatesCollectorUi_Shown;
tableLayoutPanel1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radButton_Continue).EndInit();
((System.ComponentModel.ISupportInitialize)radProgressBar1).EndInit();
((System.ComponentModel.ISupportInitialize)radSplitContainer1).EndInit();
radSplitContainer1.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)splitPanel1).EndInit();
splitPanel1.ResumeLayout(false);
tableLayoutPanel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radListView_Updates).EndInit();
((System.ComponentModel.ISupportInitialize)splitPanel2).EndInit();
splitPanel2.ResumeLayout(false);
tableLayoutPanel3.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)radListView_VersionTags).EndInit();
((System.ComponentModel.ISupportInitialize)radWaitingBar1).EndInit();
((System.ComponentModel.ISupportInitialize)this).EndInit();
ResumeLayout(false);
PerformLayout();
}
#endregion
private TableLayoutPanel tableLayoutPanel1;
private Telerik.WinControls.UI.RadButton radButton_Continue;
private Telerik.WinControls.UI.RadSplitContainer radSplitContainer1;
private Telerik.WinControls.UI.SplitPanel splitPanel1;
private TableLayoutPanel tableLayoutPanel2;
private Telerik.WinControls.UI.SplitPanel splitPanel2;
private TableLayoutPanel tableLayoutPanel3;
private Telerik.WinControls.UI.RadListView radListView_Updates;
private Telerik.WinControls.UI.RadWaitingBar radWaitingBar1;
private Telerik.WinControls.UI.RadListView radListView_VersionTags;
private Telerik.WinControls.UI.RadProgressBar radProgressBar1;
private Telerik.WinControls.UI.DotsSpinnerWaitingBarIndicatorElement dotsSpinnerWaitingBarIndicatorElement1;
}

View File

@@ -1,139 +0,0 @@
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Manager;
using Telerik.WinControls.UI;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatesCollectorUi : RadForm
{
public record ModUpdateInfo(KeyValuePair<string, string>[] AvailableVersions, InstallAction Origin)
{
public int NewVersion { get; set; } = 0;
}
public record ModUpdates(List<ModUpdateInfo> List);
private readonly IWorkspace workspace;
private readonly ModpackFactory factory = new();
private readonly InstallAction[] actions;
public ModUpdates? CurrentUpdates { get; private set; }
public ModUpdateInfo? SelectedUpdate => radListView_Updates.SelectedItem?.Value as ModUpdateInfo;
public int SelectedVersion => radListView_VersionTags.SelectedIndex;
public UpdatesCollectorUi(IWorkspace workspace, params InstallAction[] actions)
{
this.workspace = workspace;
this.actions = actions;
InitializeComponent();
radListView_Updates.AutoSizeColumnsMode = ListViewAutoSizeColumnsMode.Fill;
radListView_VersionTags.AutoSizeColumnsMode = ListViewAutoSizeColumnsMode.Fill;
}
private async Task<ModUpdates> FindUpdates()
{
var list = new List<ModUpdateInfo>();
foreach (var action in actions)
{
var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any);
BeginInvoke(() =>
{
radProgressBar1.Value1 += 1;
radProgressBar1.Text = $"{radProgressBar1.Value1} / {radProgressBar1.Maximum}";
});
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
continue;
list.Add(new(updates, action));
}
return new ModUpdates(list);
}
private void LoadUpdates(ModUpdates updates)
{
radListView_Updates.BeginUpdate();
radListView_Updates.Items.Clear();
foreach (var update in updates.List)
{
var item = new ListViewDataItem(update);
UpdateUpdatesItem(item);
radListView_Updates.Items.Add(item);
}
radListView_Updates.EndUpdate();
}
private static void UpdateUpdatesItem(ListViewDataItem? item)
{
if (item?.Value is not ModUpdateInfo updates)
return;
item[0] = updates.Origin.Name;
item[1] = updates.Origin.SourceTag;
item[2] = updates.AvailableVersions[updates.NewVersion].Value;
}
private void LoadVersions(ModUpdateInfo updates)
{
radListView_VersionTags.BeginUpdate();
radListView_VersionTags.Items.Clear();
foreach (var kvp in updates.AvailableVersions)
{
var item = new ListViewDataItem();
item[0] = kvp.Key;
item[1] = kvp.Value;
radListView_VersionTags.Items.Add(item);
}
radListView_VersionTags.SelectedIndex = updates.NewVersion;
radListView_VersionTags.EndUpdate();
}
private async void UpdatesCollectorUi_Shown(object sender, EventArgs e)
{
radWaitingBar1.StartWaiting();
radProgressBar1.Value1 = 0;
radProgressBar1.Maximum = actions.Length;
radProgressBar1.Text = null;
radProgressBar1.Visible = true;
CurrentUpdates = await FindUpdates();
LoadUpdates(CurrentUpdates);
radProgressBar1.Visible = false;
radWaitingBar1.StopWaiting();
}
private void RadListView_Updates_SelectedItemChanged(object sender, EventArgs e)
{
if (SelectedUpdate is ModUpdateInfo updates)
LoadVersions(updates);
}
private void RadListView_VersionTags_SelectedIndexChanged(object sender, EventArgs e)
{
var newIndex = SelectedVersion;
if (newIndex != -1 && SelectedUpdate is ModUpdateInfo updates)
{
updates.NewVersion = newIndex;
UpdateUpdatesItem(radListView_Updates.SelectedItem);
}
}
private void RadListView_Updates_ItemRemoved(object sender, ListViewItemEventArgs e)
{
if (e.Item?.Value is ModUpdateInfo update && CurrentUpdates is not null && CurrentUpdates.List.Contains(update))
CurrentUpdates.List.Remove(update);
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,96 @@
<dialogs:AvaloniaFlyoutBase
xmlns="https://github.com/avaloniaui"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dialogs="https://git.pilzinsel64.de/pilz-framework/pilz"
xmlns:updatesCollectorViewMode="clr-namespace:ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode"
xmlns:langRes="clr-namespace:ModpackUpdater.Apps.Manager.LangRes"
mc:Ignorable="d"
d:DesignWidth="600"
d:DesignHeight="450"
Width="800"
Height="600"
x:Class="ModpackUpdater.Apps.Manager.Ui.UpdatesCollectorView"
x:DataType="updatesCollectorViewMode:UpdatesCollectorViewModel"
Loaded="Me_OnLoaded">
<!-- Main -->
<dialogs:AvaloniaFlyoutBase.MainContent>
<Grid
RowDefinitions="Auto,*"
RowSpacing="6"
VerticalAlignment="Stretch">
<!-- TextBox: Search -->
<TextBox
Grid.Row="0"
Watermark="Search"
Text="{Binding SearchText}"
TextChanged="TextBoxSearch_OnTextChanged"/>
<!-- ScrollViewer: Updates -->
<ScrollViewer
Grid.Row="1">
<ItemsControl
ItemsSource="{Binding Updates}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid
ColumnDefinitions="20*,20*,20*,Auto"
ColumnSpacing="6"
RowSpacing="6"
Margin="3"
IsVisible="{Binding Visible}">
<!-- Label: Name -->
<TextBlock
Grid.Column="0"
VerticalAlignment="Center"
Text="{Binding Origin.Name}"/>
<!-- Label: Version (old) -->
<TextBlock
Grid.Column="1"
VerticalAlignment="Center"
Text="{Binding Origin.SourceTag}"/>
<!-- ComboBox: Version (new) -->
<ComboBox
HorizontalAlignment="Stretch"
Grid.Column="2"
ItemsSource="{Binding DisplayVersions}"
SelectedIndex="{Binding NewVersion}"/>
<!-- Button: RemoveUpdate -->
<dialogs:ImageButton
Grid.Column="3"
VerticalAlignment="Center"
HorizontalAlignment="Center"
Content="{x:Static langRes:GeneralLangRes.Remove}"
Click="ButtonRemoveUpdate_Click"/>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>
</dialogs:AvaloniaFlyoutBase.MainContent>
<!-- Footer -->
<dialogs:AvaloniaFlyoutBase.FooterContent>
<!-- ProgressBar: Status -->
<ProgressBar
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Maximum="{Binding Progress.MaxValue}"
Value="{Binding Progress.Value}"
ShowProgressText="{Binding Progress.ShowText}"
IsIndeterminate="{Binding Progress.IsGeneric}"
IsVisible="{Binding Progress.IsVisible}"/>
</dialogs:AvaloniaFlyoutBase.FooterContent>
</dialogs:AvaloniaFlyoutBase>

View File

@@ -0,0 +1,72 @@
using Avalonia.Controls;
using Avalonia.Interactivity;
using ModpackUpdater.Apps.Manager.Api.Model;
using ModpackUpdater.Apps.Manager.Ui.Models.UpdatesCollectorViewMode;
using ModpackUpdater.Manager;
using Pilz.UI.AvaloniaUI.Dialogs;
namespace ModpackUpdater.Apps.Manager.Ui;
public partial class UpdatesCollectorView : AvaloniaFlyoutBase
{
private readonly IWorkspace workspace;
private readonly ModpackFactory factory = new();
private readonly InstallAction[] actions;
public UpdatesCollectorViewModel Model { get; } = new();
public UpdatesCollectorView(IWorkspace workspace, params InstallAction[] actions)
{
this.workspace = workspace;
this.actions = actions;
DataContext = Model;
InitializeComponent();
}
private async Task FindUpdates()
{
Model.Progress.Start(actions.Length);
foreach (var action in actions)
{
var updates = await factory.FindUpdates(action, workspace.ModpackConfig?.MinecraftVersion, workspace.ModpackConfig?.ModLoader ?? ModLoader.Any);
Model.Progress.Increment();
if (updates == null || updates.Length == 0 || updates[0].Value == action.SourceTag)
continue;
Model.Updates.Add(new(updates, action));
if (IsClosed)
break;
}
Model.Progress.Stop();
}
protected override object GetResult()
{
return new ModUpdates(Model.Updates);
}
private async void Me_OnLoaded(object? sender, RoutedEventArgs e)
{
await FindUpdates();
}
private void TextBoxSearch_OnTextChanged(object? sender, TextChangedEventArgs e)
{
var searchString = Model.SearchText?.Trim().ToLowerInvariant();
var hasNoSearch = string.IsNullOrWhiteSpace(searchString);
foreach (var item in Model.Updates)
item.Visible = hasNoSearch || (item.Origin.Name != null && item.Origin.Name.Contains(searchString!, StringComparison.InvariantCultureIgnoreCase));
}
private void ButtonRemoveUpdate_Click(object? sender, RoutedEventArgs e)
{
if (sender is Button button && button.DataContext is ModUpdateInfo update)
Model.Updates.Remove(update);
}
}

View File

@@ -0,0 +1,20 @@
using System.Collections;
using System.Globalization;
using Avalonia.Data.Converters;
namespace ModpackUpdater.Apps.Manager.Utils;
public class DictionaryValueConverter : IValueConverter
{
public object? Convert(object? value, Type targetType, object? parameter, CultureInfo culture)
{
if (parameter is IDictionary dict && value != null && dict.Contains(value))
return dict[value];
return value?.ToString() ?? string.Empty;
}
public object ConvertBack(object? value, Type targetType, object? parameter, CultureInfo culture)
{
throw new NotSupportedException();
}
}

View File

@@ -0,0 +1,9 @@
namespace ModpackUpdater.Apps.Manager.Utils;
internal static class Extensions
{
public static string? Nullify(this string? @this)
{
return string.IsNullOrEmpty(@this) ? null : @this;
}
}

View File

@@ -0,0 +1,12 @@
using Avalonia.Platform.Storage;
namespace ModpackUpdater.Apps.Manager.Utils;
public class MyFilePickerFileTypes
{
public static FilePickerFileType Excel { get; } = new("Excel")
{
Patterns = ["*.xlsx"],
MimeTypes = ["application/vnd.ms-excel"]
};
}

View File

@@ -1,6 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<appSettings>
<add key="TelerikWinFormsThemeName" value="Windows11CompactDark" />
</appSettings>
</configuration>

View File

@@ -0,0 +1,92 @@
# PUPNET DEPLOY: 1.9.1
# Use: 'pupnet --help conf' for information.
# APP PREAMBLE
AppBaseName = MinecraftModpackUpdateManager
AppFriendlyName = Minecraft Modpack Update Manager
AppId = de.pilzinsel64.minecraft-modpack-update-manager
AppVersionRelease = 1.0.0[1]
AppShortSummary = Administrate updates for your modpack easily.
AppDescription = """
Minecraft Modpack Update Manager is an administrative tool to manage updates for your Minecraft modpack. It is used to distribute updates to the Minecraft Modpack Updater (the client).
"""
AppLicenseId = MIT
AppLicenseFile = ../LICENSE
AppChangeFile =
# PUBLISHER
PublisherName = Pilzinsel64
PublisherId = de.pilzinsel64
PublisherCopyright = Copyright (C) Pilzinsel64 2025
PublisherLinkName = Pilzinsel64 Homepage
PublisherLinkUrl = https://pilzinsel64.de
PublisherEmail =
# DESKTOP INTEGRATION
DesktopNoDisplay = false
DesktopTerminal = false
DesktopFile =
StartCommand =
PrimeCategory =
MetaFile =
IconFiles = """
Assets/app.ico
Assets/app.svg
"""
# DOTNET PUBLISH
DotnetProjectPath = ModpackUpdater.Apps.Manager.csproj
DotnetPublishArgs = -p:Version=${APP_VERSION} --self-contained true -p:DebugType=None -p:DebugSymbols=false -p:PublishSingleFile=true -p:PublishTrimmed=false
DotnetPostPublish =
DotnetPostPublishOnWindows =
# PACKAGE OUTPUT
PackageName = minecraft-modpack-update-manager
OutputDirectory = ../publish/manager
# APPIMAGE OPTIONS
AppImageArgs =
AppImageRuntimePath =
AppImageVersionOutput = false
# FLATPAK OPTIONS
FlatpakPlatformRuntime = org.freedesktop.Platform
FlatpakPlatformSdk = org.freedesktop.Sdk
FlatpakPlatformVersion = 25.08
FlatpakFinishArgs = """
--socket=wayland
--socket=fallback-x11
--filesystem=home
--share=network
"""
FlatpakBuilderArgs =
# RPM OPTIONS
RpmAutoReq = false
RpmAutoProv = true
RpmRequires = """
krb5-libs
libicu
openssl-libs
"""
# DEBIAN OPTIONS
DebianRecommends = """
libc6
libgcc1
libgssapi-krb5-2
libicu70
libssl3
libstdc++6
zlib1g
"""
# WINDOWS SETUP OPTIONS
SetupGroupName =
SetupAdminInstall = false
SetupCommandPrompt =
SetupMinWindowsVersion = 10
SetupSignTool =
SetupSuffixOutput =
SetupVersionOutput = false
SetupUninstallScript =

View File

@@ -0,0 +1,12 @@
pupnet -y -v "$1[1]" -r linux-x64 -k appimage
#pupnet -y -v "$1[1]" -r linux-x64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-x64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-x64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -v "$1[1]" -r linux-arm64 -k appimage
#pupnet -y -v "$1[1]" -r linux-arm64 -k flatpak -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-arm64 -k deb -p DefineConstants=DISABLE_UPDATE
#pupnet -y -v "$1[1]"-r linux-arm64 -k rpm -p DefineConstants=DISABLE_UPDATE
pupnet -y -v "$1[1]" -r win-x64 -k zip
pupnet -y -v "$1[1]" -r win-arm64 -k zip
pupnet -y -v "$1[1]" -r osx-x64 -k zip
pupnet -y -v "$1[1]" -r osx-arm64 -k zip

View File

@@ -1,24 +1,17 @@
using ModpackUpdater.Apps.Manager; using Pilz.UI.AvaloniaUI.Dialogs;
using Pilz.UI.WinForms.Telerik.Dialogs; using Pilz.UI.AvaloniaUI.Symbols;
using Pilz.UI.WinForms.Telerik.Symbols; using Pilz.UI.Symbols;
using Pilz.UI.WinForms.Telerik.Theming;
using Telerik.WinControls.Themes;
namespace ModpackUpdater.Apps; namespace ModpackUpdater.Apps;
public static class AppGlobals public static class AppGlobals
{ {
public static IRadSymbolFactory<AppSymbols> Symbols { get; } = new AppSymbolFactory(); public static ISymbolFactory<AppSymbols> Symbols { get; } = new AppSymbolFactory();
public static void Initialize() public static void Initialize()
{ {
ThemeHelper.ApplyApplicationTheme(new ThemeDefinition(ApplicationTheme.Auto, HighContrastMode.Auto), n => n.Theme switch SymbolGlobals.DefaultImageSmallSize = 17;
{ AvaloniaFlyoutBase.DefaultConfirmImage = Symbols.GetImageSource(AppSymbols.checkmark);
ApplicationTheme.Light => new Windows11CompactTheme(), AvaloniaFlyoutBase.DefaultCancelImage = Symbols.GetImageSource(AppSymbols.cancel);
ApplicationTheme.Gray or ApplicationTheme.Dark => new Windows11CompactDarkTheme(),
_ => throw new NotImplementedException(),
});
RadFlyoutBase.ConfirmSvg = Symbols.GetSvgImage(AppSymbols.checkmark, Pilz.UI.Symbols.SymbolSize.Small);
RadFlyoutBase.CancelSvg = Symbols.GetSvgImage(AppSymbols.cancel, Pilz.UI.Symbols.SymbolSize.Small);
} }
} }

View File

@@ -1,9 +1,9 @@
using Pilz.UI.WinForms.Telerik.Symbols; using System.Reflection;
using System.Reflection; using Pilz.UI.AvaloniaUI.Symbols;
namespace ModpackUpdater.Apps.Manager; namespace ModpackUpdater.Apps;
internal class AppSymbolFactory : RadSymbolFactory<AppSymbols> internal class AppSymbolFactory : SymbolFactory<AppSymbols>
{ {
public override Assembly GetImageResourceAssembly() public override Assembly GetImageResourceAssembly()
{ {

View File

@@ -36,4 +36,10 @@ public enum AppSymbols
broom, broom,
renew, renew,
list_view, list_view,
show_property,
normal_screen,
input,
output,
git,
hourglass,
} }

View File

@@ -0,0 +1,59 @@
using System.Diagnostics;
using System.Reflection;
using Avalonia.Controls;
using MsBox.Avalonia;
using MsBox.Avalonia.Enums;
using Pilz;
using Pilz.Extensions;
using Pilz.Runtime;
using Pilz.Updating.Client;
namespace ModpackUpdater.Apps;
public class AppUpdates(string updateUrl, Window mainWindow)
{
public event EventHandler? OnDownloadProgramUpdate;
public async Task UpdateApp()
{
#if !DISABLE_UPDATE
try
{
await UpdateAppCore();
}
catch (Exception ex)
{
await MessageBoxManager.GetMessageBoxStandard(GeneralMsgBoxLangRes.UpdateAvailable_Title, string.Format(GeneralMsgBoxLangRes.UpdateAvailable, ex.Message), ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowAsync();
mainWindow.IsEnabled = true;
}
#endif
}
private async Task UpdateAppCore()
{
if (Debugger.IsAttached)
return;
var myAppPath = EnvironmentEx.ProcessPath!;
var updater = new UpdateClient(updateUrl, Assembly.GetEntryAssembly()!.GetAppVersion(), AppChannel.Stable)
{
Distro = RuntimeInformationsEx.GetRuntimeIdentifier(),
};
if (await updater.CheckForUpdate() is {} packageToInstall
&& await MessageBoxManager.GetMessageBoxStandard(GeneralMsgBoxLangRes.UpdateAvailable_Title, GeneralMsgBoxLangRes.UpdateAvailable, ButtonEnum.YesNo, MsBox.Avalonia.Enums.Icon.Info).ShowWindowDialogAsync(mainWindow) == ButtonResult.Yes)
{
OnDownloadProgramUpdate?.Invoke(this, EventArgs.Empty);
mainWindow.IsEnabled = false;
if (await updater.DownloadPackageAsync(packageToInstall)
&& await updater.InstallPackageAsync(packageToInstall, myAppPath))
{
mainWindow.IsVisible = false;
await Process.Start(myAppPath).WaitForExitAsync();
Environment.Exit(0);
return;
}
mainWindow.IsEnabled = true;
}
}
}

View File

@@ -0,0 +1,72 @@
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace ModpackUpdater.Apps {
using System;
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")]
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class GeneralMsgBoxLangRes {
private static System.Resources.ResourceManager resourceMan;
private static System.Globalization.CultureInfo resourceCulture;
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal GeneralMsgBoxLangRes() {
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Resources.ResourceManager ResourceManager {
get {
if (object.Equals(null, resourceMan)) {
System.Resources.ResourceManager temp = new System.Resources.ResourceManager("ModpackUpdater.Apps.LangRes.GeneralMsgBoxLangRes", typeof(GeneralMsgBoxLangRes).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
internal static System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
internal static string UpdateAvailable {
get {
return ResourceManager.GetString("UpdateAvailable", resourceCulture);
}
}
internal static string UpdateAvailable_Title {
get {
return ResourceManager.GetString("UpdateAvailable_Title", resourceCulture);
}
}
internal static string ErrorWhileUpdate_Title {
get {
return ResourceManager.GetString("ErrorWhileUpdate_Title", resourceCulture);
}
}
internal static string ErrorWhileUpdate {
get {
return ResourceManager.GetString("ErrorWhileUpdate", resourceCulture);
}
}
}
}

View File

@@ -117,4 +117,17 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<data name="UpdateAvailable" xml:space="preserve">
<value>A new version of this program is available! Install now?
If you confirm, the update will be installed automatically within a few seconds.</value>
</data>
<data name="UpdateAvailable_Title" xml:space="preserve">
<value>New program version available</value>
</data>
<data name="ErrorWhileUpdate_Title" xml:space="preserve">
<value>Error while updating</value>
</data>
<data name="ErrorWhileUpdate" xml:space="preserve">
<value>An error happened while updating the program. Error message:\n{0}</value>
</data>
</root> </root>

View File

@@ -1,20 +1,58 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup> <PropertyGroup>
<TargetFramework>net8.0-windows</TargetFramework> <IncludeAllContentForSelfExtract>true</IncludeAllContentForSelfExtract>
<Nullable>enable</Nullable> <BuiltInComInteropSupport>true</BuiltInComInteropSupport>
<ImplicitUsings>enable</ImplicitUsings> <AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<EmbeddedResource Include="Symbols\*.svg" /> <AvaloniaResource Include="Assets\**" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<PackageReference Include="Pilz.UI" Version="3.1.1" /> <EmbeddedResource Include="Symbols\*.svg" />
<PackageReference Include="Pilz.UI.WinForms.Telerik.Symbols" Version="1.2.1" /> <EmbeddedResource Update="LangRes\GeneralMsgBoxLangRes.resx">
<PackageReference Include="UI.for.WinForms.Common" Version="2025.3.812" /> <Generator>ResXFileCodeGenerator</Generator>
<PackageReference Include="UI.for.WinForms.Themes" Version="2025.3.812" /> <LastGenOutput>MsgBoxLangRes.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<PackageReference Include="Pilz" Version="2.6.1" />
<PackageReference Include="Pilz.UI" Version="3.1.4" />
<PackageReference Include="Pilz.UI.AvaloniaUI" Version="1.2.18" />
<PackageReference Include="MessageBox.Avalonia" Version="3.3.0" />
<PackageReference Include="Avalonia" Version="11.3.8" />
<PackageReference Include="Avalonia.Desktop" Version="11.3.8" />
<PackageReference Include="Avalonia.Svg" Version="11.3.0" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.3.8" />
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.3.8" />
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
<PackageReference Include="Avalonia.Diagnostics" Version="11.3.8">
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
</PackageReference>
<PackageReference Include="Pilz.Updating" Version="4.3.5" />
<PackageReference Include="Pilz.Updating.Client" Version="4.4.6" />
</ItemGroup>
<ItemGroup>
<Compile Update="LangRes\GeneralLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>GeneralLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\GeneralMsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>GeneralMsgBoxLangRes.resx</DependentUpon>
</Compile>
<Compile Update="LangRes\MsgBoxLangRes.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>MsgBoxLangRes.resx</DependentUpon>
</Compile>
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="480" height="480">
<path fill="#F4511E" d="M42.2,22.1L25.9,5.8C25.4,5.3,24.7,5,24,5c0,0,0,0,0,0c-0.7,0-1.4,0.3-1.9,0.8l-3.5,3.5l4.1,4.1c0.4-0.2,0.8-0.3,1.3-0.3c1.7,0,3,1.3,3,3c0,0.5-0.1,0.9-0.3,1.3l4,4c0.4-0.2,0.8-0.3,1.3-0.3c1.7,0,3,1.3,3,3s-1.3,3-3,3c-1.7,0-3-1.3-3-3c0-0.5,0.1-0.9,0.3-1.3l-4-4c-0.1,0-0.2,0.1-0.3,0.1v10.4c1.2,0.4,2,1.5,2,2.8c0,1.7-1.3,3-3,3s-3-1.3-3-3c0-1.3,0.8-2.4,2-2.8V18.8c-1.2-0.4-2-1.5-2-2.8c0-0.5,0.1-0.9,0.3-1.3l-4.1-4.1L5.8,22.1C5.3,22.6,5,23.3,5,24c0,0.7,0.3,1.4,0.8,1.9l16.3,16.3c0,0,0,0,0,0c0.5,0.5,1.2,0.8,1.9,0.8s1.4-0.3,1.9-0.8l16.3-16.3c0.5-0.5,0.8-1.2,0.8-1.9C43,23.3,42.7,22.6,42.2,22.1z" />
</svg>

View File

@@ -0,0 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="480" height="480">
<path fill="#6ad7fc" d="M36,14.217V8H12v6.217c0,4.574,3.113,8.562,7.551,9.671L20,24l-0.449,0.112C15.113,25.222,12,29.209,12,33.783V40h24v-6.217c0-4.574-3.113-8.562-7.551-9.671L28,24l0.449-0.112C32.887,22.778,36,18.791,36,14.217z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWa" x1="11" x2="37" y1="9.5" y2="9.5" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3079d6" />
<stop offset="1" stop-color="#297cd2" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWa)" d="M36,11H12c-0.552,0-1-0.448-1-1V8h26v2C37,10.552,36.552,11,36,11z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWb" x1="9" x2="39" y1="6.5" y2="6.5" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#42a3f2" />
<stop offset="1" stop-color="#42a4eb" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWb)" d="M38,8H10C9.448,8,9,7.552,9,7V6c0-0.552,0.448-1,1-1h28c0.552,0,1,0.448,1,1v1C39,7.552,38.552,8,38,8z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWc" x1="24" x2="24" y1="16.715" y2="23.806" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eba84b" />
<stop offset="1" stop-color="#d97218" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWc)" d="M15,18c0,3,8,6,9,6s9-3,9-6H15z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWd" x1="24" x2="24" y1="21.788" y2="39.515" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#eba84b" />
<stop offset="1" stop-color="#d97218" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWd)" d="M24.965,32.175C24.976,32.116,25,32.062,25,32c0-0.552-0.448-1-1-1s-1,0.448-1,1 c0,0.062,0.024,0.116,0.035,0.175C20.621,32.877,16,35.714,16,40h16C32,35.714,27.379,32.877,24.965,32.175z M24,30 c0.552,0,1-0.448,1-1c0-0.552-0.448-1-1-1s-1,0.448-1,1C23,29.552,23.448,30,24,30z M24,27c0.552,0,1-0.448,1-1 c0-0.552-0.448-1-1-1s-1,0.448-1,1C23,26.552,23.448,27,24,27z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWe" x1="11" x2="37" y1="-22.5" y2="-22.5" gradientTransform="rotate(180 24 8)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#3079d6" />
<stop offset="1" stop-color="#297cd2" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWe)" d="M12,37h24c0.552,0,1,0.448,1,1v2H11v-2C11,37.448,11.448,37,12,37z" />
<linearGradient id="1Qkvnwv_~bZVAEIrNtREWf" x1="9" x2="39" y1="-25.5" y2="-25.5" gradientTransform="rotate(180 24 8)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#42a3f2" />
<stop offset="1" stop-color="#42a4eb" />
</linearGradient>
<path fill="url(#1Qkvnwv_~bZVAEIrNtREWf)" d="M10,40h28c0.552,0,1,0.448,1,1v1c0,0.552-0.448,1-1,1H10c-0.552,0-1-0.448-1-1v-1C9,40.448,9.448,40,10,40z" />
</svg>

View File

@@ -0,0 +1,38 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="480" height="480">
<linearGradient id="tF5jXHsBSdYe~15_6tmTFa" x1="24" x2="24" y1="7.958" y2="32.803" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#32bdef" />
<stop offset="1" stop-color="#1ea2e4" />
</linearGradient>
<path fill="url(#tF5jXHsBSdYe~15_6tmTFa)" d="M29.19,25H26V9c0-0.552-0.448-1-1-1h-2c-0.552,0-1,0.448-1,1v16h-3.19c-0.72,0-1.08,0.87-0.571,1.379l4.701,4.701c0.586,0.586,1.536,0.586,2.121,0l4.701-4.701C30.271,25.87,29.91,25,29.19,25z" />
<linearGradient id="tF5jXHsBSdYe~15_6tmTFb" x1="37" x2="37" y1="5.113" y2="25.441" gradientTransform="matrix(-1 0 0 1 48 0)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#32bdef" />
<stop offset="1" stop-color="#1ea2e4" />
</linearGradient>
<path fill="url(#tF5jXHsBSdYe~15_6tmTFb)" d="M5.81,19H9v-7.172L5.293,8.121c-0.391-0.391-0.391-1.024,0-1.414l1.414-1.414c0.391-0.391,1.024-0.391,1.414,0l4,4C12.684,9.856,13,10.619,13,11.414V19h3.19c0.72,0,1.08,0.87,0.571,1.379L12.06,25.08c-0.586,0.586-1.536,0.586-2.121,0l-4.701-4.701C4.729,19.87,5.09,19,5.81,19z" />
<linearGradient id="tF5jXHsBSdYe~15_6tmTFc" x1="37" x2="37" y1="5.113" y2="25.441" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#32bdef" />
<stop offset="1" stop-color="#1ea2e4" />
</linearGradient>
<path fill="url(#tF5jXHsBSdYe~15_6tmTFc)" d="M42.19,19H39v-7.172l3.707-3.707c0.391-0.391,0.391-1.024,0-1.414l-1.414-1.414c-0.391-0.391-1.024-0.391-1.414,0l-4,4C35.316,9.856,35,10.619,35,11.414V19h-3.19c-0.72,0-1.08,0.87-0.571,1.379l4.701,4.701c0.586,0.586,1.536,0.586,2.121,0l4.701-4.701C43.271,19.87,42.91,19,42.19,19z" />
<linearGradient id="tF5jXHsBSdYe~15_6tmTFd" x1="39.25" x2="44.171" y1="-590.623" y2="-604.567" gradientTransform="matrix(1 0 0 -1 0 -562)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#32bdef" />
<stop offset="1" stop-color="#1ea2e4" />
</linearGradient>
<path fill="url(#tF5jXHsBSdYe~15_6tmTFd)" d="M39,30v13l4.828-4.828c0.75-0.75,1.172-1.768,1.172-2.828V30c0-0.552-0.448-1-1-1h-4C39.448,29,39,29.448,39,30z" />
<linearGradient id="tF5jXHsBSdYe~15_6tmTFe" x1="9" x2="39" y1="-602" y2="-602" gradientTransform="matrix(1 0 0 -1 0 -562)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#0362b0" />
<stop offset=".112" stop-color="#036abd" />
<stop offset=".258" stop-color="#036fc5" />
<stop offset=".5" stop-color="#0370c8" />
<stop offset=".742" stop-color="#036fc5" />
<stop offset=".888" stop-color="#036abd" />
<stop offset="1" stop-color="#0362b0" />
</linearGradient>
<rect width="30" height="6" x="9" y="37" fill="url(#tF5jXHsBSdYe~15_6tmTFe)" />
<linearGradient id="tF5jXHsBSdYe~15_6tmTFf" x1="-549.75" x2="-544.829" y1="-590.623" y2="-604.567" gradientTransform="rotate(180 -270.5 -281)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#32bdef" />
<stop offset="1" stop-color="#1ea2e4" />
</linearGradient>
<path fill="url(#tF5jXHsBSdYe~15_6tmTFf)" d="M9,30v13l-4.828-4.828C3.421,37.421,3,36.404,3,35.343V30c0-0.552,0.448-1,1-1h4C8.552,29,9,29.448,9,30z" />
</svg>

View File

@@ -0,0 +1,55 @@
<?xml version="1.0" encoding="utf-8"?>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 48 48" width="480" height="480">
<linearGradient id="zQnX_u5TVUyKpnweuzAEVa" x1="-381.96" x2="-371.96" y1="-1380.109" y2="-1380.109" gradientTransform="matrix(1 0 0 -1 389.237 -1361.109)" gradientUnits="userSpaceOnUse">
<stop offset=".273" stop-color="#912fbd" />
<stop offset=".588" stop-color="#8f2ebb" />
<stop offset=".758" stop-color="#892bb3" />
<stop offset=".894" stop-color="#7e26a5" />
<stop offset="1" stop-color="#701f94" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVa)" d="M16.996,17l-8.997,0.007c-0.552,0.001-1,0.449-0.999,1.001L7.003,21L17,20.992L16.996,17z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVb" x1="16.525" x2="21.446" y1="-1637.127" y2="-1651.07" gradientTransform="matrix(1 0 0 -1 -.022 -1630.206)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ae4cd5" />
<stop offset="1" stop-color="#ac4ad5" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVb)" d="M17,8.004l0.011,13l3.405-3.416c0.374-0.376,0.584-0.885,0.584-1.415L20.993,7l-2.994,0.003 C17.447,7.004,16.999,7.452,17,8.004z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVc" x1="-1604.119" x2="-1594.119" y1="638.46" y2="638.46" gradientTransform="matrix(-1 0 0 1 -1562.594 -609.46)" gradientUnits="userSpaceOnUse">
<stop offset=".273" stop-color="#912fbd" />
<stop offset=".588" stop-color="#8f2ebb" />
<stop offset=".758" stop-color="#892bb3" />
<stop offset=".894" stop-color="#7e26a5" />
<stop offset="1" stop-color="#701f94" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVc)" d="M31.004,31l8.997-0.007c0.552-0.001,1-0.449,0.999-1.001L40.997,27L31,27.008L31.004,31z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVd" x1="-1205.055" x2="-1200.136" y1="381.523" y2="367.584" gradientTransform="matrix(-1 0 0 1 -1173.464 -340.176)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ae4cd5" />
<stop offset="1" stop-color="#ac4ad5" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVd)" d="M31,39.996L30.989,27l-3.406,3.417C27.209,30.792,26.999,31.3,27,31.829L27.007,41 l2.994-0.003C30.553,40.996,31.001,40.548,31,39.996z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVe" x1="-1626.498" x2="-1616.498" y1="-1380.299" y2="-1380.299" gradientTransform="rotate(180 -793.086 -680.252)" gradientUnits="userSpaceOnUse">
<stop offset=".273" stop-color="#912fbd" />
<stop offset=".588" stop-color="#8f2ebb" />
<stop offset=".758" stop-color="#892bb3" />
<stop offset=".894" stop-color="#7e26a5" />
<stop offset="1" stop-color="#701f94" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVe)" d="M30.996,17.007l9-0.007c0.552-0.001,1,0.445,1.001,0.995L41,20.992L31,21L30.996,17.007z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVf" x1="-1228.014" x2="-1223.093" y1="-1637.658" y2="-1651.601" gradientTransform="rotate(180 -598.651 -815.082)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ae4cd5" />
<stop offset="1" stop-color="#ac4ad5" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVf)" d="M30.989,7.999L31,20.997l-3.408-3.41c-0.374-0.375-0.585-0.883-0.585-1.414L27,7.003 L29.993,7C30.542,6.999,30.988,7.447,30.989,7.999z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVg" x1="-359.508" x2="-349.508" y1="639.223" y2="639.223" gradientTransform="translate(365.896 -610.563)" gradientUnits="userSpaceOnUse">
<stop offset=".273" stop-color="#912fbd" />
<stop offset=".588" stop-color="#8f2ebb" />
<stop offset=".758" stop-color="#892bb3" />
<stop offset=".894" stop-color="#7e26a5" />
<stop offset="1" stop-color="#701f94" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVg)" d="M17.004,30.993l-9,0.007c-0.552,0.001-1-0.445-1.001-0.995L7,27.008L17,27L17.004,30.993z" />
<linearGradient id="zQnX_u5TVUyKpnweuzAEVh" x1="38.977" x2="43.897" y1="381.863" y2="367.921" gradientTransform="translate(-22.845 -340.716)" gradientUnits="userSpaceOnUse">
<stop offset="0" stop-color="#ae4cd5" />
<stop offset="1" stop-color="#ac4ad5" />
</linearGradient>
<path fill="url(#zQnX_u5TVUyKpnweuzAEVh)" d="M17.011,40L17,27.003l3.407,3.41c0.374,0.375,0.585,0.884,0.586,1.414L21,40.997L18.008,41 C17.458,41.001,17.012,40.553,17.011,40z" />
</svg>

Some files were not shown because too many files have changed in this diff Show More