mirror of
https://github.com/LostArtefacts/TRX.git
synced 2025-04-28 20:58:07 +03:00
tools/installer: move language to external file
This moves all language used in the installer to an embedded JSON file to allow for customisation per game.
This commit is contained in:
parent
e16fcda94b
commit
365cff79c1
23 changed files with 170 additions and 97 deletions
|
@ -6,7 +6,7 @@
|
|||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:models="clr-namespace:TRX_InstallerLib.Models"
|
||||
d:DataContext="{d:DesignInstance Type=models:FinishStep}"
|
||||
mc:Ignorable="d"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
|
||||
<UserControl.Resources>
|
||||
|
@ -14,19 +14,17 @@
|
|||
</UserControl.Resources>
|
||||
|
||||
<StackPanel Orientation="Vertical">
|
||||
<TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Margin="0,0,0,12" Style="{StaticResource heading}">
|
||||
Step 4: Done
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Style="{StaticResource heading}"
|
||||
Text="{Binding ViewText[step_finish_heading]}"/>
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="0,0,0,12" TextWrapping="Wrap">
|
||||
Installation complete. To configure more advanced features, you can edit the JSON files in the cfg/ directory with a text editor.
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,24"
|
||||
TextWrapping="Wrap"
|
||||
Text="{Binding ViewText[step_finish_content]}"/>
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="0,0,0,12">
|
||||
Happy raiding :)
|
||||
</TextBlock>
|
||||
|
||||
<CheckBox IsChecked="{Binding FinishSettings.OpenGameDirectory}" Content="Open game directory after closing this window" Margin="0,0,0,12" />
|
||||
<CheckBox IsChecked="{Binding FinishSettings.LaunchGame}" Content="Launch the game after closing this window" Margin="0,0,0,12" />
|
||||
<CheckBox IsChecked="{Binding FinishSettings.OpenGameDirectory}" Content="{Binding ViewText[step_finish_open_directory]}" Margin="0,0,0,12" />
|
||||
<CheckBox IsChecked="{Binding FinishSettings.LaunchGame}" Content="{Binding ViewText[step_finish_open_game]}" Margin="0,0,0,12" />
|
||||
</StackPanel>
|
||||
</UserControl>
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
xmlns:models="clr-namespace:TRX_InstallerLib.Models"
|
||||
xmlns:utils="clr-namespace:TRX_InstallerLib.Utils"
|
||||
d:DataContext="{d:DesignInstance Type=models:InstallSettingsStep}"
|
||||
mc:Ignorable="d"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
|
||||
<UserControl.Resources>
|
||||
|
@ -20,9 +20,9 @@
|
|||
<RowDefinition Height="*" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" TextWrapping="Wrap" VerticalAlignment="Center" Margin="0,0,0,12" Style="{StaticResource heading}">
|
||||
Step 2: Installation options
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Style="{StaticResource heading}"
|
||||
Text="{Binding ViewText[step_settings_heading]}"/>
|
||||
|
||||
<ScrollViewer Grid.Row="1" ScrollViewer.VerticalScrollBarVisibility="Auto">
|
||||
<ScrollViewer.Template>
|
||||
|
@ -82,15 +82,10 @@
|
|||
<StackPanel Orientation="Vertical">
|
||||
<CheckBox VerticalAlignment="Center" Margin="0,0,0,12" IsChecked="{Binding InstallSettings.DownloadMusic}" IsEnabled="{Binding InstallSettings.IsDownloadingMusicNeeded}">
|
||||
<TextBlock TextWrapping="Wrap">
|
||||
Download music tracks
|
||||
<Run Foreground="ForestGreen" Text="{Binding InstallSettings.IsDownloadingMusicNeeded, Converter={utils:ConditionalMarkupConverter TrueValue='', FalseValue='(already found)'}, Mode=OneWay}" />
|
||||
<Run Text="{Binding ViewText[step_settings_music_heading]}"/>
|
||||
<Run Foreground="ForestGreen" Text="{Binding InstallSettings.IsDownloadingMusicNeeded, Converter={utils:ConditionalViewTextConverter TrueValue='', FalseValue='label_already_found'}, Mode=OneWay}" />
|
||||
<LineBreak />
|
||||
<Run Style="{StaticResource small}">
|
||||
This option lets you download compatible music files for the game
|
||||
automatically (60 MB). The legality of these files is disputable;
|
||||
the most legal way to import the music to PC is to obtain them from
|
||||
your own source - TR2 supports FLAC, OOG, MP3 and WAV files.
|
||||
</Run>
|
||||
<Run Style="{StaticResource small}" Text="{Binding ViewText[step_settings_music_content]}"/>
|
||||
</TextBlock>
|
||||
</CheckBox>
|
||||
|
||||
|
@ -100,33 +95,31 @@
|
|||
<utils:ComparisonConverter x:Key="ComparisonConverter" />
|
||||
</StackPanel.Resources>
|
||||
<TextBlock TextWrapping="Wrap" Margin="0,0,0,6">
|
||||
Download Unfinished Business expansion pack
|
||||
<Run Foreground="ForestGreen" Text="{Binding InstallSettings.IsDownloadingExpansionNeeded, Converter={utils:ConditionalMarkupConverter TrueValue='', FalseValue='(already found)'}, Mode=OneWay}" />
|
||||
<Run Text="{Binding ViewText[step_settings_expansion_heading]}"/>
|
||||
<Run Foreground="ForestGreen" Text="{Binding InstallSettings.IsDownloadingExpansionNeeded, Converter={utils:ConditionalViewTextConverter TrueValue='', FalseValue='label_already_found'}, Mode=OneWay}" />
|
||||
<LineBreak />
|
||||
<Run Style="{StaticResource small}">
|
||||
The Unfinished Business expansion pack was made freeware. However, the Steam and GOG versions do not ship it. This option lets you download the expansion files automatically (6 MB).
|
||||
</Run>
|
||||
<Run Style="{StaticResource small}" Text="{Binding ViewText[step_settings_expansion_content]}"/>
|
||||
</TextBlock>
|
||||
<RadioButton IsEnabled="{Binding InstallSettings.DownloadExpansionPack}" Style="{StaticResource small}" Margin="0,0,0,6" Content="Fan-made edition (includes music triggers)"
|
||||
<RadioButton IsEnabled="{Binding InstallSettings.DownloadExpansionPack}" Style="{StaticResource small}" Margin="0,0,0,6" Content="{Binding ViewText[step_settings_expansion_music]}"
|
||||
IsChecked="{Binding Path=InstallSettings.ExpansionPackType, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static models:ExpansionPackType.Music}}"/>
|
||||
<RadioButton IsEnabled="{Binding InstallSettings.DownloadExpansionPack}" Style="{StaticResource small}" Margin="0,0,0,6" Content="Original edition (does not include music triggers)"
|
||||
<RadioButton IsEnabled="{Binding InstallSettings.DownloadExpansionPack}" Style="{StaticResource small}" Margin="0,0,0,6" Content="{Binding ViewText[step_settings_expansion_vanilla]}"
|
||||
IsChecked="{Binding Path=InstallSettings.ExpansionPackType, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static models:ExpansionPackType.Vanilla}}"/>
|
||||
</StackPanel>
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Margin="0,0,0,12" IsChecked="{Binding InstallSettings.ImportSaves}" IsEnabled="{Binding InstallSettings.InstallSource.IsImportingSavesSupported}">
|
||||
<TextBlock TextWrapping="Wrap">
|
||||
Import saves
|
||||
<Run Text="{Binding ViewText[step_settings_saves_header]}"/>
|
||||
<LineBreak />
|
||||
<Run Style="{StaticResource small}">
|
||||
Imports existing savegame files. Only TombATI and TR1X savegame format is supported at this time.
|
||||
</Run>
|
||||
<Run Style="{StaticResource small}" Text="{Binding ViewText[step_settings_saves_content]}"/>
|
||||
</TextBlock>
|
||||
</CheckBox>
|
||||
|
||||
<CheckBox VerticalAlignment="Center" Margin="0,0,0,12" IsChecked="{Binding InstallSettings.CreateDesktopShortcut}">
|
||||
Create desktop shortcut
|
||||
</CheckBox>
|
||||
<CheckBox
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,12"
|
||||
IsChecked="{Binding InstallSettings.CreateDesktopShortcut}"
|
||||
Content="{Binding ViewText[step_settings_shortcut_heading]}"/>
|
||||
|
||||
<Separator />
|
||||
|
||||
|
@ -136,9 +129,9 @@
|
|||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Label Grid.Column="0" VerticalAlignment="Center" Margin="0,0,12,0" Padding="0" Content="Destination folder:" />
|
||||
<Label Grid.Column="0" VerticalAlignment="Center" Margin="0,0,12,0" Padding="0" Content="{Binding ViewText[label_destination_folder]}" />
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Text="{Binding InstallSettings.TargetDirectory}" TextTrimming="CharacterEllipsis" />
|
||||
<Button Grid.Column="2" VerticalAlignment="Center" Margin="12,0,0,0" Command="{Binding ChooseLocationCommand}" Content="Change..." />
|
||||
<Button Grid.Column="2" VerticalAlignment="Center" Margin="12,0,0,0" Command="{Binding ChooseLocationCommand}" Content="{Binding ViewText[command_change]}" />
|
||||
</Grid>
|
||||
</StackPanel>
|
||||
</ScrollViewer>
|
||||
|
|
|
@ -50,8 +50,8 @@
|
|||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" Padding="0" Margin="0,-3,12,3" VerticalAlignment="Top" Style="{StaticResource subHeading}" Text="{Binding InstallSource.SourceName}" Height="16" />
|
||||
<TextBlock Grid.Column="1" Padding="0" Margin="0,-3,0,3" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{StaticResource subHeadingFound}" Visibility="{Binding IsAvailable, Converter={StaticResource BoolToVisibleConverter}}" Text="Found" />
|
||||
<TextBlock Grid.Column="1" Padding="0" Margin="0,-3,0,3" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{StaticResource subHeadingNotFound}" Visibility="{Binding IsAvailable, Converter={StaticResource BoolToHiddenConverter}}" Text="Not found" />
|
||||
<TextBlock Grid.Column="1" Padding="0" Margin="0,-3,0,3" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{StaticResource subHeadingFound}" Visibility="{Binding IsAvailable, Converter={StaticResource BoolToVisibleConverter}}" Text="{Binding ViewText[label_found]}" />
|
||||
<TextBlock Grid.Column="1" Padding="0" Margin="0,-3,0,3" HorizontalAlignment="Right" VerticalAlignment="Top" Style="{StaticResource subHeadingNotFound}" Visibility="{Binding IsAvailable, Converter={StaticResource BoolToHiddenConverter}}" Text="{Binding ViewText[label_not_found]}" />
|
||||
</Grid>
|
||||
|
||||
<Grid Grid.Row="1" Grid.Column="1">
|
||||
|
@ -59,9 +59,12 @@
|
|||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Grid.Column="0" VerticalAlignment="Center" Text="{Binding SourceDirectory, TargetNullValue='(no folder selected)'}" TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Grid.Column="0" VerticalAlignment="Center" Text="{Binding ViewText[label_folder_not_selected]}" Visibility="{Binding IsSourceDirectoryDefined, Converter={StaticResource BoolToHiddenConverter}}" />
|
||||
<TextBlock Grid.Column="0" VerticalAlignment="Center" Text="{Binding SourceDirectory}" TextTrimming="CharacterEllipsis" />
|
||||
<TextBlock Grid.Column="1" VerticalAlignment="Center" Margin="6,0,0,0">
|
||||
<Hyperlink Command="{Binding ChooseLocationCommand}" >(change)</Hyperlink>
|
||||
<Hyperlink Command="{Binding ChooseLocationCommand}">
|
||||
<Run Text="{Binding ViewText[command_change_link]}"/>
|
||||
</Hyperlink>
|
||||
</TextBlock>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
@ -24,9 +24,9 @@
|
|||
</Grid.RowDefinitions>
|
||||
|
||||
<StackPanel Grid.Row="0" Orientation="Vertical">
|
||||
<TextBlock TextWrapping="Wrap" VerticalAlignment="Center" Margin="0,0,0,12" Style="{StaticResource heading}">
|
||||
Step 3: Installing
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Style="{StaticResource heading}"
|
||||
Text="{Binding ViewText[step_install_heading]}"/>
|
||||
|
||||
<TextBlock VerticalAlignment="Center" Margin="0,0,0,12" Text="{Binding Description}" />
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@
|
|||
xmlns:controls="clr-namespace:TRX_InstallerLib.Controls"
|
||||
xmlns:models="clr-namespace:TRX_InstallerLib.Models"
|
||||
xmlns:utils="clr-namespace:TRX_InstallerLib.Utils"
|
||||
d:DataContext="{d:DesignInstance Type=models:MainWindowViewModel}"
|
||||
mc:Ignorable="d"
|
||||
d:DataContext="{d:DesignInstance Type=models:SourceStep}"
|
||||
mc:Ignorable="d"
|
||||
d:DesignHeight="450" d:DesignWidth="800">
|
||||
|
||||
<UserControl.Resources>
|
||||
|
@ -18,7 +18,7 @@
|
|||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
|
||||
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" MinHeight="30" />
|
||||
|
@ -29,17 +29,16 @@
|
|||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<TextBlock Grid.Row="0" Grid.Column="0" TextWrapping="Wrap" VerticalAlignment="Center" Margin="0,0,0,12" Style="{StaticResource heading}">
|
||||
Step 1: Choose installation source
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Style="{StaticResource heading}"
|
||||
Text="{Binding ViewText[step_source_heading]}"/>
|
||||
|
||||
<TextBlock Grid.Row="1" Grid.Column="0" TextWrapping="Wrap" VerticalAlignment="Center" Margin="0,0,0,10">
|
||||
TR1X requires original game files to run.
|
||||
<LineBreak />
|
||||
Please choose the source location where to install the data files from.
|
||||
<LineBreak />
|
||||
If you're upgrading an existing installation, please choose TR1X.
|
||||
</TextBlock>
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
TextWrapping="Wrap"
|
||||
VerticalAlignment="Center"
|
||||
Margin="0,0,0,10"
|
||||
Text="{Binding ViewText[step_source_content]}"/>
|
||||
|
||||
<ListView
|
||||
BorderThickness="0"
|
||||
|
|
|
@ -90,17 +90,17 @@
|
|||
<Button
|
||||
Command="{Binding GoToPreviousStepCommand}"
|
||||
Visibility="{Binding IsFinalStep, Converter={StaticResource BoolToHiddenConverter}}"
|
||||
Content="_Back" />
|
||||
Content="{Binding ViewText[command_back]}" />
|
||||
<Button
|
||||
Grid.Column="1"
|
||||
Command="{Binding GoToNextStepCommand}"
|
||||
Visibility="{Binding IsFinalStep, Converter={StaticResource BoolToHiddenConverter}}"
|
||||
Content="_Next" />
|
||||
Content="{Binding ViewText[command_next]}" />
|
||||
<Button
|
||||
Grid.Column="2"
|
||||
Command="{Binding CloseWindowCommand}"
|
||||
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType=Window}}"
|
||||
Content="{Binding IsFinalStep, Converter={utils:ConditionalMarkupConverter TrueValue='_Close', FalseValue='_Cancel'}}" />
|
||||
Content="{Binding IsFinalStep, Converter={utils:ConditionalViewTextConverter TrueValue='command_close', FalseValue='command_cancel'}}" />
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
|
|
@ -52,7 +52,7 @@ public class InstallExecutor
|
|||
CreateDesktopShortcut(_settings.TargetDirectory);
|
||||
}
|
||||
|
||||
progress.Report(new InstallProgress { Description = "Finished", Finished = true });
|
||||
progress.Report(new InstallProgress { Description = Language.Instance.Controls!["progress_finished"], Finished = true });
|
||||
}
|
||||
|
||||
protected async Task CopyOriginalGameFiles(string sourceDirectory, string targetDirectory, IProgress<InstallProgress> progress)
|
||||
|
@ -72,11 +72,11 @@ public class InstallExecutor
|
|||
{
|
||||
CurrentValue = 0,
|
||||
MaximumValue = 1,
|
||||
Description = "Opening embedded ZIP",
|
||||
Description = Language.Instance.Controls!["progress_opening_zip"],
|
||||
});
|
||||
|
||||
using var stream = AssemblyUtils.GetResourceStream("Resources.release.zip", false)
|
||||
?? throw new ApplicationException($"Could not open embedded ZIP.");
|
||||
?? throw new ApplicationException(Language.Instance.Controls!["progress_zip_failure"]);
|
||||
await InstallUtils.ExtractZip(stream, targetDirectory, progress, overwrite: true);
|
||||
}
|
||||
|
||||
|
|
|
@ -26,7 +26,7 @@ public static class InstallUtils
|
|||
{
|
||||
try
|
||||
{
|
||||
progress.Report(new InstallProgress { Description = "Scanning directory" });
|
||||
progress.Report(new InstallProgress { Description = Language.Instance.Controls!["progress_scanning"] });
|
||||
var files = Directory.GetFiles(sourceDirectory, "*", SearchOption.AllDirectories);
|
||||
var currentProgress = 0;
|
||||
var maximumProgress = files.Length;
|
||||
|
@ -45,7 +45,7 @@ public static class InstallUtils
|
|||
{
|
||||
CurrentValue = currentProgress,
|
||||
MaximumValue = maximumProgress,
|
||||
Description = $"Copying {relPath}",
|
||||
Description = string.Format(Language.Instance.Controls!["progress_copying"], relPath),
|
||||
});
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
|
||||
await Task.Run(() => File.Copy(sourcePath, targetPath, true));
|
||||
|
@ -56,7 +56,7 @@ public static class InstallUtils
|
|||
{
|
||||
CurrentValue = currentProgress,
|
||||
MaximumValue = maximumProgress,
|
||||
Description = $"Copying {relPath} - skipped",
|
||||
Description = string.Format(Language.Instance.Controls!["progress_skipped"], relPath),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@ public static class InstallUtils
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException($"Could not extract ZIP:\n{e.Message}");
|
||||
throw new ApplicationException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -79,14 +79,14 @@ public static class InstallUtils
|
|||
public static async Task<byte[]> DownloadFile(string url, IProgress<InstallProgress> progress)
|
||||
{
|
||||
HttpProgressClient wc = new();
|
||||
progress.Report(new InstallProgress { Description = $"Initializing download of {url}" });
|
||||
progress.Report(new InstallProgress { Description = string.Format(Language.Instance.Controls!["progress_init_download"], url) });
|
||||
wc.DownloadProgressChanged += (totalBytesToReceive, bytesReceived) =>
|
||||
{
|
||||
progress.Report(new InstallProgress
|
||||
{
|
||||
CurrentValue = (int)bytesReceived,
|
||||
MaximumValue = (int)totalBytesToReceive,
|
||||
Description = $"Downloading {url}",
|
||||
Description = string.Format(Language.Instance.Controls!["progress_downloading"], url),
|
||||
});
|
||||
};
|
||||
return await wc.DownloadDataTaskAsync(new Uri(url));
|
||||
|
@ -116,7 +116,7 @@ public static class InstallUtils
|
|||
using var zip = new ZipArchive(stream);
|
||||
progress.Report(new InstallProgress
|
||||
{
|
||||
Description = "Scanning ZIP",
|
||||
Description = Language.Instance.Controls!["progress_scanning_zip"],
|
||||
});
|
||||
var currentProgress = 0;
|
||||
var maximumProgress = zip.Entries.Count;
|
||||
|
@ -140,7 +140,7 @@ public static class InstallUtils
|
|||
{
|
||||
CurrentValue = currentProgress,
|
||||
MaximumValue = maximumProgress,
|
||||
Description = $"Extracting {entry.FullName}",
|
||||
Description = string.Format(Language.Instance.Controls!["progress_extracting"], entry.FullName),
|
||||
});
|
||||
|
||||
Directory.CreateDirectory(Path.GetDirectoryName(targetPath)!);
|
||||
|
@ -152,7 +152,7 @@ public static class InstallUtils
|
|||
{
|
||||
CurrentValue = currentProgress,
|
||||
MaximumValue = maximumProgress,
|
||||
Description = $"Extracting {entry.FullName} - skipped",
|
||||
Description = string.Format(Language.Instance.Controls!["progress_extracting_skipped"], entry.FullName),
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -161,7 +161,7 @@ public static class InstallUtils
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException($"Could not extract ZIP:\n{e.Message}");
|
||||
throw new ApplicationException(e.Message);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,7 +2,7 @@ using TRX_InstallerLib.Utils;
|
|||
|
||||
namespace TRX_InstallerLib.Models;
|
||||
|
||||
public class FinishStep : BaseNotifyPropertyChanged, IStep
|
||||
public class FinishStep : BaseLanguageViewModel, IStep
|
||||
{
|
||||
public FinishStep(FinishSettings finishSettings)
|
||||
{
|
||||
|
|
|
@ -3,7 +3,7 @@ using TRX_InstallerLib.Utils;
|
|||
|
||||
namespace TRX_InstallerLib.Models;
|
||||
|
||||
public class InstallSettingsStep : BaseNotifyPropertyChanged, IStep
|
||||
public class InstallSettingsStep : BaseLanguageViewModel, IStep
|
||||
{
|
||||
public InstallSettingsStep(InstallSettings installSettings)
|
||||
{
|
||||
|
@ -24,7 +24,7 @@ public class InstallSettingsStep : BaseNotifyPropertyChanged, IStep
|
|||
public ICommand ChooseLocationCommand
|
||||
{
|
||||
get => _chooseLocationCommand ??= new RelayCommand(ChooseLocation);
|
||||
}
|
||||
}
|
||||
|
||||
private void ChooseLocation()
|
||||
{
|
||||
|
|
|
@ -4,7 +4,7 @@ using TRX_InstallerLib.Utils;
|
|||
|
||||
namespace TRX_InstallerLib.Models;
|
||||
|
||||
public class InstallSourceViewModel : BaseNotifyPropertyChanged
|
||||
public class InstallSourceViewModel : BaseLanguageViewModel
|
||||
{
|
||||
public InstallSourceViewModel(IInstallSource source)
|
||||
{
|
||||
|
@ -38,6 +38,11 @@ public class InstallSourceViewModel : BaseNotifyPropertyChanged
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsSourceDirectoryDefined
|
||||
{
|
||||
get => SourceDirectory != null;
|
||||
}
|
||||
|
||||
public string? SourceDirectory
|
||||
{
|
||||
get => _sourceDirectory;
|
||||
|
@ -48,6 +53,7 @@ public class InstallSourceViewModel : BaseNotifyPropertyChanged
|
|||
_sourceDirectory = value;
|
||||
NotifyPropertyChanged();
|
||||
NotifyPropertyChanged(nameof(IsAvailable));
|
||||
NotifyPropertyChanged(nameof(IsSourceDirectoryDefined));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@ using TRX_InstallerLib.Utils;
|
|||
|
||||
namespace TRX_InstallerLib.Models;
|
||||
|
||||
public class InstallStep : BaseNotifyPropertyChanged, IStep
|
||||
public class InstallStep : BaseLanguageViewModel, IStep
|
||||
{
|
||||
public InstallStep(InstallSettings installSettings)
|
||||
{
|
||||
|
|
|
@ -13,7 +13,7 @@ public class Language
|
|||
public static Language Instance { get; private set; }
|
||||
|
||||
public Dictionary<string, string>? Controls { get; set; }
|
||||
|
||||
|
||||
static Language()
|
||||
{
|
||||
CultureInfo defaultCulture = CultureInfo.GetCultureInfo(_defaultCulture);
|
||||
|
|
|
@ -4,7 +4,7 @@ using TRX_InstallerLib.Utils;
|
|||
|
||||
namespace TRX_InstallerLib.Models;
|
||||
|
||||
public class SourceStep : BaseNotifyPropertyChanged, IStep
|
||||
public class SourceStep : BaseLanguageViewModel, IStep
|
||||
{
|
||||
public SourceStep(IEnumerable<IInstallSource> installSources)
|
||||
{
|
||||
|
|
|
@ -1,5 +1,56 @@
|
|||
{
|
||||
"Controls": {
|
||||
|
||||
"command_back": "_Back",
|
||||
"command_next": "_Next",
|
||||
"command_close": "_Close",
|
||||
"command_cancel": "_Cancel",
|
||||
"command_change": "C_hange...",
|
||||
"command_change_link": "(change)",
|
||||
"label_found": "Found",
|
||||
"label_not_found": "Not found",
|
||||
"label_already_found": "(already found)",
|
||||
"label_folder_not_selected": "(no folder selected)",
|
||||
"label_destination_folder": "Destination folder:",
|
||||
"label_select_folder": "Choose directory",
|
||||
"step_source_heading": "Step 1: Choose installation source",
|
||||
"step_source_content": "Placeholder",
|
||||
"step_settings_heading": "Step 2: Installation options",
|
||||
"step_settings_music_heading": "Download music tracks",
|
||||
"step_settings_music_content": "Placeholder",
|
||||
"step_settings_expansion_heading": "Placeholder",
|
||||
"step_settings_expansion_content": "Placeholder",
|
||||
"step_settings_expansion_music": "Placeholder",
|
||||
"step_settings_expansion_vanilla": "Placeholder",
|
||||
"step_settings_saves_header": "Import saves",
|
||||
"step_settings_saves_content": "Placeholder",
|
||||
"step_settings_shortcut_heading": "Create desktop shortcut",
|
||||
"step_install_heading": "Step 3: Installing",
|
||||
"step_finish_heading": "Step 4: Done",
|
||||
"step_finish_content": "Installation complete. To configure more advanced features, you can edit the JSON files in the cfg/ directory with a text editor.\n\nHappy raiding :)",
|
||||
"step_finish_open_directory": "Open game directory after closing this window",
|
||||
"step_finish_open_game": "Launch the game after closing this window",
|
||||
"progress_scanning": "Scanning directory",
|
||||
"progress_scanning_source": "Scanning the source directory",
|
||||
"progress_preparing_extract": "Preparing to extract the ISO",
|
||||
"progress_copying": "Copying {0}",
|
||||
"progress_skipped": "Copying {0} - skipped",
|
||||
"progress_init_download": "Initializing download of {0}",
|
||||
"progress_downloading": "Downloading {0}",
|
||||
"progress_opening_zip": "Opening embedded ZIP",
|
||||
"progress_zip_failure": "Could not open embedded ZIP.",
|
||||
"progress_scanning_zip": "Scanning ZIP",
|
||||
"progress_extracting": "Extracting {0}",
|
||||
"progress_extracting_skipped": "Extracting {0} - skipped",
|
||||
"progress_converting_bin": "Converting BIN to ISO",
|
||||
"progress_converting_bin_failure": "Could not convert BIN to ISO: {0}",
|
||||
"progress_converting_iso_failure": "Could not open converted ISO: {0}",
|
||||
"progress_track_write_failure": "Could not write to track file {0}: {1}",
|
||||
"progress_track_seek_failure": "Could not seek to track location: {0}",
|
||||
"progress_bin_failure": "Could not open BIN {0}: {1}",
|
||||
"progress_cue_failure": "Could not read CUE {0}: {1}",
|
||||
"progress_cue_empty": "Could not parse {0}: no tracks were found",
|
||||
"progress_finished": "Finished",
|
||||
"shortcut_signature_failure": "Invalid LNK signature",
|
||||
"shortcut_target_failure": "Unable to determine link target path"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyle}" />
|
||||
<Style x:Key="heading" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="20" />
|
||||
<Setter Property="TextWrapping" Value="Wrap" />
|
||||
<Setter Property="VerticalAlignment" Value="Center" />
|
||||
<Setter Property="Margin" Value="0,0,0,12" />
|
||||
</Style>
|
||||
<Style x:Key="subHeading" TargetType="TextBlock">
|
||||
<Setter Property="FontSize" Value="15" />
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Remove="Resources\const.json" />
|
||||
<None Remove="Resources\Lang\en.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="Resources\const.json" />
|
||||
<EmbeddedResource Include="Resources\Lang\en.json" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
|
|
|
@ -4,12 +4,12 @@ using System.Windows.Markup;
|
|||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
public sealed class ConditionalMarkupConverter : MarkupExtension, IValueConverter
|
||||
public class ConditionalMarkupConverter : MarkupExtension, IValueConverter
|
||||
{
|
||||
public object FalseValue { get; set; } = new();
|
||||
public object TrueValue { get; set; } = new();
|
||||
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value is true ? TrueValue : FalseValue;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
using System.Globalization;
|
||||
using TRX_InstallerLib.Models;
|
||||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
public class ConditionalViewTextConverter : ConditionalMarkupConverter
|
||||
{
|
||||
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
string result = base.Convert(value, targetType, parameter, culture).ToString()!;
|
||||
return result.Length == 0 ? string.Empty : Language.Instance.Controls![result];
|
||||
}
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using TRX_InstallerLib.Models;
|
||||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
|
@ -19,7 +20,7 @@ public class CueFile
|
|||
MatchCollection fileMatches = _fileGroupRegex.Matches(cueFileContent);
|
||||
if (fileMatches.Count == 0)
|
||||
{
|
||||
throw new ApplicationException($"Could not parse {cueFilePath}: no tracks were found");
|
||||
throw new ApplicationException(string.Format(Language.Instance.Controls!["progress_cue_empty"], cueFilePath));
|
||||
}
|
||||
|
||||
foreach (Match fileMatch in fileMatches.Cast<Match>())
|
||||
|
@ -29,7 +30,7 @@ public class CueFile
|
|||
|
||||
if (matches.Count == 0)
|
||||
{
|
||||
throw new ApplicationException($"Could not parse {cueFilePath}: no tracks were found");
|
||||
throw new ApplicationException(string.Format(Language.Instance.Controls!["progress_cue_empty"], cueFilePath));
|
||||
}
|
||||
|
||||
CueTrack? track = null;
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
using System.IO;
|
||||
using TRX_InstallerLib.Models;
|
||||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
|
@ -78,7 +79,7 @@ public class CueTrack
|
|||
{
|
||||
MaximumValue = (int)TotalBytes,
|
||||
CurrentValue = (int)convertedBytes,
|
||||
Description = "Converting BIN to ISO"
|
||||
Description = Language.Instance.Controls!["progress_converting_bin"],
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -87,14 +88,14 @@ public class CueTrack
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException(string.Format(" Could not write to track file {0}: {1}", targetPath, e.Message));
|
||||
throw new ApplicationException(string.Format(Language.Instance.Controls!["progress_track_write_failure"], targetPath, e.Message));
|
||||
}
|
||||
|
||||
progress.Report(new InstallProgress
|
||||
{
|
||||
MaximumValue = (int)TotalBytes,
|
||||
CurrentValue = (int)TotalBytes,
|
||||
Description = "Converting BIN to ISO",
|
||||
Description = Language.Instance.Controls!["progress_converting_bin"],
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,7 @@ public class CueTrack
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException($"Could not open BIN {BinFilePath}: {e.Message}");
|
||||
throw new ApplicationException(string.Format(Language.Instance.Controls!["progress_bin_failure"], BinFilePath, e.Message));
|
||||
}
|
||||
try
|
||||
{
|
||||
|
@ -177,7 +178,7 @@ public class CueTrack
|
|||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
throw new ApplicationException(string.Format("Could not seek to track location: {0}", e.Message));
|
||||
throw new ApplicationException(string.Format(Language.Instance.Controls!["progress_track_seek_failure"], e.Message));
|
||||
}
|
||||
return fileStream;
|
||||
}
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
using TRX_InstallerLib.Models;
|
||||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
public class FileBrowser
|
||||
|
@ -6,7 +8,7 @@ public class FileBrowser
|
|||
{
|
||||
using var dlg = new FolderBrowserDialog()
|
||||
{
|
||||
Description = "Choose directory",
|
||||
Description = Language.Instance.Controls!["label_select_folder"],
|
||||
SelectedPath = initialDirectory,
|
||||
ShowNewFolderButton = true,
|
||||
};
|
||||
|
|
|
@ -2,6 +2,7 @@ using System.IO;
|
|||
using System.Text;
|
||||
|
||||
using System.Text.RegularExpressions;
|
||||
using TRX_InstallerLib.Models;
|
||||
|
||||
namespace TRX_InstallerLib.Utils;
|
||||
|
||||
|
@ -146,7 +147,7 @@ public static class ShortcutUtils
|
|||
var headerSize = br.ReadUInt32();
|
||||
if (headerSize != 0x4C)
|
||||
{
|
||||
throw new ApplicationException("Invalid LNK signature");
|
||||
throw new ApplicationException(Language.Instance.Controls!["shortcut_signature_failure"]);
|
||||
}
|
||||
|
||||
br.ReadBytes(0x10); // skip LinkCLSID
|
||||
|
@ -230,6 +231,6 @@ public static class ShortcutUtils
|
|||
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), relativePath);
|
||||
}
|
||||
|
||||
throw new ApplicationException("Unable to determine link target path");
|
||||
throw new ApplicationException(Language.Instance.Controls!["shortcut_target_failure"]);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue