added preliminary archive creation support.

This commit is contained in:
morkt 2014-07-24 05:43:20 +04:00
parent 56012447d8
commit 0a1f14e051
29 changed files with 568 additions and 58 deletions

View File

@ -68,6 +68,9 @@
<setting name="appLastDirectory" serializeAs="String">
<value />
</setting>
<setting name="appArchiveFormat" serializeAs="String">
<value />
</setting>
</GARbro.GUI.Properties.Settings>
</userSettings>
</configuration>

View File

@ -39,8 +39,9 @@ namespace GameRes.Formats
public class AmiOpener : ArchiveFormat
{
public override string Tag { get { return "AMI"; } }
public override string Description { get { return "Amaterasu Translations Muv-Luv archive"; } }
public override string Description { get { return Strings.arcStrings.AMIDescription; } }
public override uint Signature { get { return 0x00494d41; } }
public override bool IsHierarchic { get { return false; } }
public AmiOpener ()
{
@ -109,7 +110,7 @@ namespace GameRes.Formats
public class GrpFormat : ImageFormat
{
public override string Tag { get { return "GRP"; } }
public override string Description { get { return "âge proprietary image format"; } }
public override string Description { get { return Strings.arcStrings.GRPDescription; } }
public override uint Signature { get { return 0x00505247; } }
public override ImageMetaData ReadMetaData (Stream stream)
@ -191,7 +192,7 @@ namespace GameRes.Formats
public class ScrFormat : ScriptFormat
{
public override string Tag { get { return "SCR"; } }
public override string Description { get { return "Amaterasu Translations Muv-Luv script file"; } }
public override string Description { get { return Strings.arcStrings.SCRDescription; } }
public override uint Signature { get { return 0x00524353; } }
public override ScriptData Read (string name, Stream stream)

View File

@ -41,8 +41,9 @@ namespace GameRes.Formats
public class IntOpener : ArchiveFormat
{
public override string Tag { get { return "INT"; } }
public override string Description { get { return "FrontWing game resource archive"; } }
public override string Description { get { return arcStrings.INTDescription; } }
public override uint Signature { get { return 0x0046494b; } }
public override bool IsHierarchic { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
@ -267,11 +268,9 @@ namespace GameRes.Formats
{ "Sengoku Tenshi Djibril (trial)", new KeyData { Key=0xef870610, Passphrase="FW-8O9B6WDS" }},
};
IntEncryptionInfo m_info = Settings.Default.INTEncryption ?? new IntEncryptionInfo();
uint? QueryEncryptionInfo ()
{
var widget = new GUI.WidgetINT (m_info);
var widget = new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo());
var args = new ParametersRequestEventArgs
{
Notice = arcStrings.INTNotice,
@ -284,5 +283,12 @@ namespace GameRes.Formats
Settings.Default.INTEncryption = widget.Info;
return widget.GetKey();
}
public override ResourceOptions GetOptions ()
{
return new ResourceOptions {
Widget = new GUI.WidgetINT (Settings.Default.INTEncryption ?? new IntEncryptionInfo())
};
}
}
}

View File

@ -49,8 +49,9 @@ namespace GameRes.Formats
public class NpaOpener : ArchiveFormat
{
public override string Tag { get { return "NPA"; } }
public override string Description { get { return "Nitro+ resource archive"; } }
public override string Description { get { return arcStrings.NPADescription; } }
public override uint Signature { get { return 0x0141504e; } } // NPA\x01
public override bool IsHierarchic { get { return true; } }
/// <summary>Known encryption schemes.</summary>
public static readonly string[] KnownSchemes = new string[] {

View File

@ -16,8 +16,9 @@ namespace GameRes.Formats
public class XflOpener : ArchiveFormat
{
public override string Tag { get { return "XFL"; } }
public override string Description { get { return "Liar-soft game resource archive"; } }
public override string Description { get { return Strings.arcStrings.XFLDescription; } }
public override uint Signature { get { return 0x0001424c; } }
public override bool IsHierarchic { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
@ -62,8 +63,9 @@ namespace GameRes.Formats
public class LwgOpener : ArchiveFormat
{
public override string Tag { get { return "LWG"; } }
public override string Description { get { return "Liar-soft image archive"; } }
public override string Description { get { return Strings.arcStrings.LWGDescription; } }
public override uint Signature { get { return 0x0001474c; } }
public override bool IsHierarchic { get { return false; } }
public override ArcFile TryOpen (ArcView file)
{
@ -112,7 +114,7 @@ namespace GameRes.Formats
public class GscFormat : ScriptFormat
{
public override string Tag { get { return "GSC"; } }
public override string Description { get { return "Liar-soft proprietary script format"; } }
public override string Description { get { return Strings.arcStrings.GSCDescription; } }
public override uint Signature { get { return 0; } }
public override ScriptData Read (string name, Stream stream)

View File

@ -45,8 +45,9 @@ namespace GameRes.Formats.KiriKiri
public class Xp3Opener : ArchiveFormat
{
public override string Tag { get { return "XP3"; } }
public override string Description { get { return "KiriKiri game engine resource archive"; } }
public override string Description { get { return arcStrings.XP3Description; } }
public override uint Signature { get { return 0x0d335058; } }
public override bool IsHierarchic { get { return false; } }
private static readonly ICrypt NoCryptAlgorithm = new NoCrypt();

View File

@ -20,8 +20,9 @@ namespace GameRes.Formats
public class YpfOpener : ArchiveFormat
{
public override string Tag { get { return "YPF"; } }
public override string Description { get { return "Yu-Ris game engine resource archive"; } }
public override string Description { get { return arcStrings.YPFDescription; } }
public override uint Signature { get { return 0x00465059; } }
public override bool IsHierarchic { get { return true; } }
private const uint DefaultKey = 0xffffffff;

View File

@ -60,6 +60,15 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Amaterasu Translations Muv-Luv archive.
/// </summary>
public static string AMIDescription {
get {
return ResourceManager.GetString("AMIDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Archive content is encrypted.
///Choose appropriate encryption scheme..
@ -79,6 +88,42 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to âge proprietary image format.
/// </summary>
public static string GRPDescription {
get {
return ResourceManager.GetString("GRPDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Liar-soft proprietary script format.
/// </summary>
public static string GSCDescription {
get {
return ResourceManager.GetString("GSCDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to FrontWing game resource archive.
/// </summary>
public static string INTDescription {
get {
return ResourceManager.GetString("INTDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Numeric key should be a 32-bit hexadecimal integer.
/// </summary>
public static string INTKeyRequirement {
get {
return ResourceManager.GetString("INTKeyRequirement", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Numeric key.
/// </summary>
@ -117,6 +162,60 @@ namespace GameRes.Formats.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Liar-soft image archive.
/// </summary>
public static string LWGDescription {
get {
return ResourceManager.GetString("LWGDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Nitro+ resource archive.
/// </summary>
public static string NPADescription {
get {
return ResourceManager.GetString("NPADescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Amaterasu Translations Muv-Luv script file.
/// </summary>
public static string SCRDescription {
get {
return ResourceManager.GetString("SCRDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Liar-soft game resource archive.
/// </summary>
public static string XFLDescription {
get {
return ResourceManager.GetString("XFLDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to KiriKiri game engine resource archive.
/// </summary>
public static string XP3Description {
get {
return ResourceManager.GetString("XP3Description", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Yu-Ris game engine resource archive.
/// </summary>
public static string YPFDescription {
get {
return ResourceManager.GetString("YPFDescription", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to 8-bit encryption key.
/// </summary>

View File

@ -117,6 +117,9 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="AMIDescription" xml:space="preserve">
<value>Amaterasu Translations Muv-Luv archive</value>
</data>
<data name="ArcEncryptedNotice" xml:space="preserve">
<value>Archive content is encrypted.
Choose appropriate encryption scheme.</value>
@ -124,6 +127,18 @@ Choose appropriate encryption scheme.</value>
<data name="ArcNoEncryption" xml:space="preserve">
<value>no encryption</value>
</data>
<data name="GRPDescription" xml:space="preserve">
<value>âge proprietary image format</value>
</data>
<data name="GSCDescription" xml:space="preserve">
<value>Liar-soft proprietary script format</value>
</data>
<data name="INTDescription" xml:space="preserve">
<value>FrontWing game resource archive</value>
</data>
<data name="INTKeyRequirement" xml:space="preserve">
<value>Numeric key should be a 32-bit hexadecimal integer</value>
</data>
<data name="INTLabelNumericKey" xml:space="preserve">
<value>Numeric key</value>
</data>
@ -138,6 +153,24 @@ Choose appropriate encryption scheme.</value>
Enter archive encryption key or choose
predefined encryption scheme.</value>
</data>
<data name="LWGDescription" xml:space="preserve">
<value>Liar-soft image archive</value>
</data>
<data name="NPADescription" xml:space="preserve">
<value>Nitro+ resource archive</value>
</data>
<data name="SCRDescription" xml:space="preserve">
<value>Amaterasu Translations Muv-Luv script file</value>
</data>
<data name="XFLDescription" xml:space="preserve">
<value>Liar-soft game resource archive</value>
</data>
<data name="XP3Description" xml:space="preserve">
<value>KiriKiri game engine resource archive</value>
</data>
<data name="YPFDescription" xml:space="preserve">
<value>Yu-Ris game engine resource archive</value>
</data>
<data name="YPFLabelKey" xml:space="preserve">
<value>8-bit encryption key</value>
</data>

View File

@ -124,6 +124,9 @@
<data name="ArcNoEncryption" xml:space="preserve">
<value>без шифрования</value>
</data>
<data name="INTKeyRequirement" xml:space="preserve">
<value>Цифровой ключ должен быть 32-битным шестнадцатиричным числом</value>
</data>
<data name="INTLabelNumericKey" xml:space="preserve">
<value>Цифровой ключ</value>
</data>

View File

@ -3,7 +3,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:GameRes.Formats.Strings"
xmlns:local="clr-namespace:GameRes.Formats.GUI"
MaxWidth="250">
MaxWidth="260">
<Grid.Resources>
<local:KeyConverter x:Key="keyConverter"/>
<Style TargetType="{x:Type TextBox}">
@ -17,7 +17,7 @@
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition MinWidth="100" Width="*"/>
<ColumnDefinition MinWidth="130" Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>

View File

@ -118,7 +118,7 @@ namespace GameRes.Formats.GUI
}
catch
{
return new ValidationResult (false, "Numeric key should be a 32-bit hexadecimal integer");
return new ValidationResult (false, Strings.arcStrings.INTKeyRequirement);
}
return new ValidationResult (true, null);
}

50
CreateArchive.xaml Normal file
View File

@ -0,0 +1,50 @@
<Window x:Class="GARbro.GUI.CreateArchiveDialog"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:GARbro.GUI.Strings"
xmlns:p="clr-namespace:GARbro.GUI.Properties"
xmlns:local="clr-namespace:GARbro.GUI"
Title="{x:Static s:guiStrings.TextCreateArchive}" SizeToContent="WidthAndHeight"
UseLayoutRounding="True" Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
ShowInTaskbar="False" WindowStartupLocation="CenterOwner" ResizeMode="NoResize"
MinWidth="300">
<DockPanel VerticalAlignment="Top" Margin="10">
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Target="{Binding ElementName=ArchiveName}" Content="{x:Static s:guiStrings.LabelArchiveName}" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2"/>
<local:ExtAutoCompleteBox x:Name="ArchiveName" HorizontalContentAlignment="Stretch" Grid.Column="0" Grid.Row="1"/>
<Button Margin="10,0,0,0" VerticalAlignment="Center" Grid.Column="1" Grid.Row="1"
Command="{x:Static local:Commands.Browse}">
<Image Source="{StaticResource IconSearch}" Stretch="Uniform" UseLayoutRounding="True" SnapsToDevicePixels="True" Width="16" Height="16" HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Button>
</Grid>
<Grid DockPanel.Dock="Top" Margin="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Vertical" Grid.Column="0" VerticalAlignment="Top" Margin="0,0,10,0">
<Label Content="{x:Static s:guiStrings.LabelArchiveFormat}" Target="{Binding ElementName=ArchiveFormat}" HorizontalAlignment="Left"
Padding="5,0,5,5"/>
<ComboBox Name="ArchiveFormat" SelectedValuePath="Tag" SelectedValue="{Binding Source={x:Static p:Settings.Default}, Path=appArchiveFormat, Mode=TwoWay}"
SelectionChanged="OnFormatSelect" DisplayMemberPath="Tag"/>
</StackPanel>
<GroupBox Name="OptionsWidget" Grid.Column="1" Header="{x:Static s:guiStrings.LabelArchiveOptions}"
VerticalAlignment="Stretch" VerticalContentAlignment="Stretch" Padding="5" Visibility="Hidden"/>
</Grid>
<StackPanel DockPanel.Dock="Bottom" HorizontalAlignment="Right" Orientation="Horizontal" Margin="20,20,0,0">
<Button Content="Ok" Click="Button_Click" IsDefault="True" Width="70" Margin="0,0,10,0"/>
<Button Content="Cancel" IsCancel="True" Width="70" Margin="10,0,0,0"/>
</StackPanel>
</DockPanel>
<Window.CommandBindings>
<CommandBinding Command="{x:Static local:Commands.Browse}" Executed="BrowseExec" CanExecute="CanExecuteAlways"/>
</Window.CommandBindings>
</Window>

102
CreateArchive.xaml.cs Normal file
View File

@ -0,0 +1,102 @@
using System.IO;
using System.Windows;
using System.Windows.Input;
using System.Text;
using System.Linq;
using Microsoft.Win32;
using GARbro.GUI.Strings;
using GameRes;
using System.Windows.Controls;
namespace GARbro.GUI
{
/// <summary>
/// Interaction logic for CreateArchive.xaml
/// </summary>
public partial class CreateArchiveDialog : Window
{
public CreateArchiveDialog ()
{
InitializeComponent ();
this.ArchiveFormat.ItemsSource = FormatCatalog.Instance.ArcFormats;
}
public ResourceOptions ArchiveOptions { get; private set; }
void Button_Click (object sender, RoutedEventArgs e)
{
DialogResult = true;
}
void BrowseExec (object sender, ExecutedRoutedEventArgs e)
{
string file = ChooseFile (guiStrings.TextChooseArchive, ArchiveName.Text);
if (!string.IsNullOrEmpty (file))
ArchiveName.Text = file;
}
string GetFilters ()
{
var filters = new StringBuilder();
var format = this.ArchiveFormat.SelectedItem as ArchiveFormat;
if (null != format)
{
var patterns = format.Extensions.Select (ext => "*."+ext);
filters.Append (format.Description);
filters.Append (" (");
filters.Append (string.Join (", ", patterns));
filters.Append (")|");
filters.Append (string.Join (";", patterns));
}
if (filters.Length > 0)
filters.Append ('|');
filters.Append (string.Format ("{0} (*.*)|*.*", guiStrings.TextAllFiles));
return filters.ToString();
}
public string ChooseFile (string title, string initial)
{
string dir = ".";
if (!string.IsNullOrEmpty (initial))
{
var parent = Directory.GetParent (initial);
if (null != parent)
dir = parent.FullName;
}
dir = Path.GetFullPath (dir);
var dlg = new OpenFileDialog {
InitialDirectory = dir,
Multiselect = false,
Filter = GetFilters(),
};
return dlg.ShowDialog (this).Value ? dlg.FileName : null;
}
void OnFormatSelect (object sender, SelectionChangedEventArgs e)
{
var format = this.ArchiveFormat.SelectedItem as ArchiveFormat;
UIElement widget = null;
if (null != format)
{
var options = format.GetOptions();
ArchiveOptions = options;
if (null != options)
widget = options.Widget as UIElement;
}
else
{
ArchiveOptions = null;
}
OptionsWidget.Content = widget;
OptionsWidget.Visibility = null != widget ? Visibility.Visible : Visibility.Hidden;
}
void CanExecuteAlways (object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = true;
}
}
}

View File

@ -12,7 +12,7 @@
<RowDefinition Height="70*"/>
<RowDefinition Height="41*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="ExtractLabel" Text="{x:Static s:guiStrings.TextExtractAllTo}" Margin="10,10,10,0" VerticalAlignment="Top" Height="15"/>
<TextBlock x:Name="ExtractLabel" Text="{x:Static s:guiStrings.LabelExtractAllTo}" Margin="10,10,10,0" VerticalAlignment="Top" Height="15"/>
<local:ExtAutoCompleteBox x:Name="DestinationDir" Margin="10,0,41,9" VerticalAlignment="Bottom"/>
<Button Margin="0,0,10,9" VerticalAlignment="Bottom" HorizontalAlignment="Right"
Command="{x:Static local:Commands.Browse}">

View File

@ -45,7 +45,7 @@ namespace GARbro.GUI
public ExtractArchiveDialog (string filename, string destination)
{
InitializeComponent();
ExtractLabel.Text = string.Format (guiStrings.TextExtractAllTo, filename);
ExtractLabel.Text = string.Format (guiStrings.LabelExtractAllTo, filename);
DestinationDir.Text = destination;
ExtractImages.IsChecked = Settings.Default.appExtractImages;

View File

@ -10,7 +10,7 @@
<Grid.RowDefinitions>
<RowDefinition/>
</Grid.RowDefinitions>
<TextBlock x:Name="ExtractLabel" Text="{x:Static s:guiStrings.TextExtractFileTo}" Margin="10,10,9.157,0" VerticalAlignment="Top" Height="15"/>
<TextBlock x:Name="ExtractLabel" Text="{x:Static s:guiStrings.LabelExtractFileTo}" Margin="10,10,9.157,0" VerticalAlignment="Top" Height="15"/>
<local:ExtAutoCompleteBox x:Name="DestinationDir" Margin="10,28,0,0"
VerticalAlignment="Top" HorizontalAlignment="Left" Width="337"/>
<Button Margin="0,28,10,0" VerticalAlignment="Top" HorizontalAlignment="Right"

View File

@ -43,7 +43,7 @@ namespace GARbro.GUI
public ExtractFile (EntryViewModel entry, string destination)
{
InitializeComponent();
ExtractLabel.Text = string.Format (guiStrings.TextExtractFileTo, entry.Name);
ExtractLabel.Text = string.Format (guiStrings.LabelExtractFileTo, entry.Name);
DestinationDir.Text = destination;
if ("image" == entry.Type)
{

View File

@ -119,6 +119,9 @@
<Compile Include="ArcParameters.xaml.cs">
<DependentUpon>ArcParameters.xaml</DependentUpon>
</Compile>
<Compile Include="CreateArchive.xaml.cs">
<DependentUpon>CreateArchive.xaml</DependentUpon>
</Compile>
<Compile Include="DragScroll.cs" />
<Compile Include="ExtractArchive.xaml.cs">
<DependentUpon>ExtractArchive.xaml</DependentUpon>
@ -129,6 +132,7 @@
</Compile>
<Compile Include="HistoryStack.cs" />
<Compile Include="ImagePreview.cs" />
<Compile Include="ListBoxEx.cs" />
<Compile Include="ModalWindow.cs" />
<Compile Include="Settings.cs" />
<Compile Include="Strings\guiStrings.Designer.cs">
@ -146,6 +150,10 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="CreateArchive.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ExtractArchive.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>

View File

@ -103,6 +103,8 @@ namespace GameRes
{
public override string Type { get { return "archive"; } }
public abstract bool IsHierarchic { get; }
public abstract ArcFile TryOpen (ArcView view);
/// <summary>
@ -141,7 +143,7 @@ namespace GameRes
return File.Create (entry.Name);
}
/// /// <summary>
/// <summary>
/// Create resource archive named <paramref name="filename"/> containing entries from the
/// supplied <paramref name="list"/> and applying necessary <paramref name="options"/>.
/// </summary>

View File

@ -19,6 +19,7 @@
<BitmapImage x:Key="Icon32x32Forward" UriSource="Images/32x32/forward button.png"/>
<BitmapImage x:Key="Icon32x32Help" UriSource="Images/32x32/help.png"/>
<CollectionViewSource x:Key="ListViewSource" Source="{Binding}"/>
<local:BooleanToCollapsedVisibilityConverter x:Key="booleanToCollapsedVisibilityConverter" />
<Style x:Key="HeaderLeftAlign" TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="HorizontalContentAlignment" Value="Left"></Setter>
</Style>
@ -106,7 +107,7 @@
<ColumnDefinition Width="1"/>
<ColumnDefinition Width="*" MinWidth="100"/>
</Grid.ColumnDefinitions>
<ListView Name="CurrentDirectory" Grid.Column="0"
<ListView x:Name="CurrentDirectory" Grid.Column="0"
ItemsSource="{Binding Source={StaticResource ListViewSource}}"
VerticalAlignment="Stretch" HorizontalAlignment="Stretch"
BorderBrush="Transparent" SelectedValuePath="Name"
@ -122,12 +123,16 @@
<MenuItem Header="{x:Static s:guiStrings.CtxMenuOpen}" InputGestureText="Enter"
Style="{StaticResource DefaultMenuItemStyle}"
Command="{x:Static local:Commands.OpenItem}" />
<MenuItem Header="{x:Static s:guiStrings.CtxMenuCreate}" InputGestureText="F3"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToCollapsedVisibilityConverter}}"
Command="{x:Static local:Commands.CreateArchive}" />
<MenuItem Header="{x:Static s:guiStrings.CtxMenuExtract}" InputGestureText="F4"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToCollapsedVisibilityConverter}}"
Command="{x:Static local:Commands.ExtractItem}" />
<MenuItem Header="{x:Static s:guiStrings.CtxMenuExplorer}" InputGestureText="Ctrl+E"
Command="{x:Static local:Commands.ExploreItem}"/>
<Separator/>
<MenuItem Header="{x:Static s:guiStrings.CtxMenuDelete}" InputGestureText="Del"
Visibility="{Binding Path=IsEnabled, RelativeSource={RelativeSource Self}, Mode=OneWay, Converter={StaticResource booleanToCollapsedVisibilityConverter}}"
Command="{x:Static local:Commands.DeleteItem}"/>
<Separator/>
<!--
@ -246,6 +251,7 @@
<Window.CommandBindings>
<CommandBinding Command="{x:Static local:Commands.OpenItem}" Executed="OpenItemExec" CanExecute="CanExecuteOnSelected"/>
<CommandBinding Command="{x:Static local:Commands.ExtractItem}" Executed="ExtractItemExec" CanExecute="CanExecuteOnSelected"/>
<CommandBinding Command="{x:Static local:Commands.CreateArchive}" Executed="CreateArchiveExec" CanExecute="CanExecuteCreateArchive"/>
<CommandBinding Command="{x:Static local:Commands.DeleteItem}" Executed="DeleteItemExec" CanExecute="CanExecuteDelete" />
<CommandBinding Command="{x:Static local:Commands.RenameItem}" Executed="RenameItemExec" CanExecute="CanExecuteInDirectory" />
<CommandBinding Command="{x:Static local:Commands.ExploreItem}" Executed="ExploreItemExec" CanExecute="CanExecuteInDirectory" />

View File

@ -158,12 +158,16 @@ namespace GARbro.GUI
DirectoryViewModel GetNewViewModel (string path)
{
SetBusyState();
path = Path.GetFullPath (path);
if (Directory.Exists (path))
{
return new DirectoryViewModel (path, m_app.GetDirectoryList (path));
}
else
{
SetBusyState();
return new ArchiveViewModel (path, m_app.GetArchive (path));
}
}
public void SetBusyState()
@ -918,7 +922,7 @@ namespace GARbro.GUI
Description = "",
MinimizeBox = true,
};
if (1 == file_list.Count())
if (!file_list.Skip (1).Any()) // 1 == file_list.Count()
{
extractProgressDialog.Description = file_list.First().Name;
extractProgressDialog.ProgressBarStyle = ProgressBarStyle.MarqueeProgressBar;
@ -960,6 +964,28 @@ namespace GARbro.GUI
extractProgressDialog.ShowDialog (this);
}
private void CreateArchiveExec (object sender, ExecutedRoutedEventArgs e)
{
try
{
var dialog = new CreateArchiveDialog();
dialog.Owner = this;
if (!dialog.ShowDialog().Value || string.IsNullOrEmpty (dialog.ArchiveName.Text))
return;
var format = dialog.ArchiveFormat.SelectedItem as ArchiveFormat;
if (null == format)
return;
string arc_name = Path.GetFullPath (dialog.ArchiveName.Text);
var items = CurrentDirectory.SelectedItems.Cast<EntryViewModel>();
format.Create (arc_name, items.Select (entry => entry.Source), dialog.ArchiveOptions);
}
catch (Exception X)
{
PopupError (X.Message, guiStrings.TextCreateArchiveError);
}
}
/// <summary>
/// Handle "Exit" command.
/// </summary>
@ -996,6 +1022,11 @@ namespace GARbro.GUI
e.CanExecute = ViewModel.IsArchive && CurrentDirectory.SelectedIndex != -1;
}
private void CanExecuteCreateArchive (object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = !ViewModel.IsArchive && CurrentDirectory.SelectedItems.Count > 0;
}
private void CanExecuteInDirectory (object sender, CanExecuteRoutedEventArgs e)
{
e.CanExecute = !ViewModel.IsArchive;
@ -1077,10 +1108,30 @@ namespace GARbro.GUI
}
}
public class BooleanToCollapsedVisibilityConverter : IValueConverter
{
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
//reverse conversion (false=>Visible, true=>collapsed) on any given parameter
bool input = (null == parameter) ? (bool)value : !((bool)value);
return (input) ? Visibility.Visible : Visibility.Collapsed;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
public static class Commands
{
public static readonly RoutedCommand OpenItem = new RoutedCommand();
public static readonly RoutedCommand ExtractItem = new RoutedCommand();
public static readonly RoutedCommand CreateArchive = new RoutedCommand();
public static readonly RoutedCommand SortBy = new RoutedCommand();
public static readonly RoutedCommand Exit = new RoutedCommand();
public static readonly RoutedCommand GoBack = new RoutedCommand();

View File

@ -1,8 +1,10 @@
MSCS = D:/WINDOWS/Microsoft.NET/Framework/v4.0.30319/csc //nologo
MSNETDIR = D:/WINDOWS/Microsoft.NET/Framework/v4.0.30319
MSCS = $(MSNETDIR)/csc //nologo
MSBUILD = $(MSNETDIR)/MSBuild.exe //nologo
.SUFFIXES: .cs .exe
all: GARbro
all: GARbro.GUI
adler32: adler32.cs
$(MSCS) $(MSCSFLAGS) //out:$@.exe $^
@ -13,6 +15,9 @@ inflate: inflate.cs
deflate: deflate.cs
$(MSCS) $(MSCSFLAGS) //out:$@.exe $^ //r:zlib\\zlibnet.dll
GARbro.GUI:
$(MSBUILD) //p:Configuration=Debug //v:m GARbro.GUI.csproj
GARbro: Program.cs GameRes.cs ArcXFL.cs
$(MSCS) $(MSCSFLAGS) //out:$@.exe $^ //r:System.ComponentModel.Composition.dll //r:System.ComponentModel.DataAnnotations.dll

View File

@ -226,5 +226,17 @@ namespace GARbro.GUI.Properties {
this["appLastDirectory"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string appArchiveFormat {
get {
return ((string)(this["appArchiveFormat"]));
}
set {
this["appArchiveFormat"] = value;
}
}
}
}

View File

@ -53,5 +53,8 @@
<Setting Name="appLastDirectory" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="appArchiveFormat" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
</Settings>
</SettingsFile>

View File

@ -105,6 +105,15 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Create archive....
/// </summary>
public static string CtxMenuCreate {
get {
return ResourceManager.GetString("CtxMenuCreate", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Cut.
/// </summary>
@ -249,6 +258,51 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Archive format.
/// </summary>
public static string LabelArchiveFormat {
get {
return ResourceManager.GetString("LabelArchiveFormat", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Archive name.
/// </summary>
public static string LabelArchiveName {
get {
return ResourceManager.GetString("LabelArchiveName", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Archive options.
/// </summary>
public static string LabelArchiveOptions {
get {
return ResourceManager.GetString("LabelArchiveOptions", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extract all files from {0} to.
/// </summary>
public static string LabelExtractAllTo {
get {
return ResourceManager.GetString("LabelExtractAllTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extract {0} to.
/// </summary>
public static string LabelExtractFileTo {
get {
return ResourceManager.GetString("LabelExtractFileTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to file.
/// </summary>
@ -456,6 +510,15 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to All Files.
/// </summary>
public static string TextAllFiles {
get {
return ResourceManager.GetString("TextAllFiles", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to as is.
/// </summary>
@ -465,6 +528,15 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Choose archive location.
/// </summary>
public static string TextChooseArchive {
get {
return ResourceManager.GetString("TextChooseArchive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Choose destination directory.
/// </summary>
@ -474,6 +546,24 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Create archive.
/// </summary>
public static string TextCreateArchive {
get {
return ResourceManager.GetString("TextCreateArchive", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Archive creation error.
/// </summary>
public static string TextCreateArchiveError {
get {
return ResourceManager.GetString("TextCreateArchiveError", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to &lt;DIR&gt;.
/// </summary>
@ -492,24 +582,6 @@ namespace GARbro.GUI.Strings {
}
}
/// <summary>
/// Looks up a localized string similar to Extract all files from {0} to.
/// </summary>
public static string TextExtractAllTo {
get {
return ResourceManager.GetString("TextExtractAllTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extract {0} to.
/// </summary>
public static string TextExtractFileTo {
get {
return ResourceManager.GetString("TextExtractFileTo", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Extract images.
/// </summary>

View File

@ -132,6 +132,9 @@
<data name="CtxMenuCopy" xml:space="preserve">
<value>Copy</value>
</data>
<data name="CtxMenuCreate" xml:space="preserve">
<value>Create archive...</value>
</data>
<data name="CtxMenuCut" xml:space="preserve">
<value>Cut</value>
</data>
@ -180,6 +183,21 @@
<data name="HeaderType" xml:space="preserve">
<value>Type</value>
</data>
<data name="LabelArchiveFormat" xml:space="preserve">
<value>Archive format</value>
</data>
<data name="LabelArchiveName" xml:space="preserve">
<value>Archive name</value>
</data>
<data name="LabelArchiveOptions" xml:space="preserve">
<value>Archive options</value>
</data>
<data name="LabelExtractAllTo" xml:space="preserve">
<value>Extract all files from {0} to</value>
</data>
<data name="LabelExtractFileTo" xml:space="preserve">
<value>Extract {0} to</value>
</data>
<data name="LPfile1" xml:space="preserve">
<value>file</value>
</data>
@ -249,24 +267,30 @@
<data name="TextAboutTitle" xml:space="preserve">
<value>About Game Resource browser</value>
</data>
<data name="TextAllFiles" xml:space="preserve">
<value>All Files</value>
</data>
<data name="TextAsIs" xml:space="preserve">
<value>as is</value>
</data>
<data name="TextChooseArchive" xml:space="preserve">
<value>Choose archive location</value>
</data>
<data name="TextChooseDestDir" xml:space="preserve">
<value>Choose destination directory</value>
</data>
<data name="TextCreateArchive" xml:space="preserve">
<value>Create archive</value>
</data>
<data name="TextCreateArchiveError" xml:space="preserve">
<value>Archive creation error</value>
</data>
<data name="TextDirType" xml:space="preserve">
<value>&lt;DIR&gt;</value>
</data>
<data name="TextEncoding" xml:space="preserve">
<value>Text encoding</value>
</data>
<data name="TextExtractAllTo" xml:space="preserve">
<value>Extract all files from {0} to</value>
</data>
<data name="TextExtractFileTo" xml:space="preserve">
<value>Extract {0} to</value>
</data>
<data name="TextExtractImages" xml:space="preserve">
<value>Extract images</value>
</data>

View File

@ -129,6 +129,9 @@
<data name="CtxMenuCopy" xml:space="preserve">
<value>Копировать</value>
</data>
<data name="CtxMenuCreate" xml:space="preserve">
<value>Создать архив...</value>
</data>
<data name="CtxMenuCut" xml:space="preserve">
<value>Вырезать</value>
</data>
@ -177,6 +180,21 @@
<data name="HeaderType" xml:space="preserve">
<value>Тип</value>
</data>
<data name="LabelArchiveFormat" xml:space="preserve">
<value>Формат архива</value>
</data>
<data name="LabelArchiveName" xml:space="preserve">
<value>Имя архива</value>
</data>
<data name="LabelArchiveOptions" xml:space="preserve">
<value>Настройки архивирования</value>
</data>
<data name="LabelExtractAllTo" xml:space="preserve">
<value>Извлечь все файлы из {0} в</value>
</data>
<data name="LabelExtractFileTo" xml:space="preserve">
<value>Извлечь {0} в</value>
</data>
<data name="LPfile1" xml:space="preserve">
<value>файл</value>
</data>
@ -249,24 +267,30 @@
<data name="TextAboutTitle" xml:space="preserve">
<value>Об обозревателе игровых ресурсов</value>
</data>
<data name="TextAllFiles" xml:space="preserve">
<value>Все файлы</value>
</data>
<data name="TextAsIs" xml:space="preserve">
<value>исходном</value>
</data>
<data name="TextChooseArchive" xml:space="preserve">
<value>Выберите месторасположение архива</value>
</data>
<data name="TextChooseDestDir" xml:space="preserve">
<value>Выберите место извлечения</value>
</data>
<data name="TextCreateArchive" xml:space="preserve">
<value>Создать архив</value>
</data>
<data name="TextCreateArchiveError" xml:space="preserve">
<value>Ошибка при создании архива</value>
</data>
<data name="TextDirType" xml:space="preserve">
<value>&lt;DIR&gt;</value>
</data>
<data name="TextEncoding" xml:space="preserve">
<value>Кодировка текста</value>
</data>
<data name="TextExtractAllTo" xml:space="preserve">
<value>Извлечь все файлы из {0} в</value>
</data>
<data name="TextExtractFileTo" xml:space="preserve">
<value>Извлечь {0} в</value>
</data>
<data name="TextExtractImages" xml:space="preserve">
<value>Извлекать изображения</value>
</data>

View File

@ -2,4 +2,5 @@
<repositories>
<repository path="..\..\GARbro.GUI\packages.config" />
<repository path="..\ArcFormats\packages.config" />
<repository path="..\packages.config" />
</repositories>