mirror of
https://github.com/crskycode/GARbro.git
synced 2026-07-08 01:30:18 +08:00
implemented archive creation frontend.
This commit is contained in:
@@ -1,12 +1,12 @@
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using GARbro.GUI.Strings;
|
using GARbro.GUI.Strings;
|
||||||
using GameRes;
|
using GameRes;
|
||||||
using System.Windows.Controls;
|
|
||||||
|
|
||||||
namespace GARbro.GUI
|
namespace GARbro.GUI
|
||||||
{
|
{
|
||||||
@@ -15,17 +15,31 @@ namespace GARbro.GUI
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class CreateArchiveDialog : Window
|
public partial class CreateArchiveDialog : Window
|
||||||
{
|
{
|
||||||
public CreateArchiveDialog ()
|
public CreateArchiveDialog (string initial_name = "")
|
||||||
{
|
{
|
||||||
InitializeComponent ();
|
InitializeComponent ();
|
||||||
|
|
||||||
this.ArchiveFormat.ItemsSource = FormatCatalog.Instance.ArcFormats;
|
if (!string.IsNullOrEmpty (initial_name))
|
||||||
|
{
|
||||||
|
var format = this.ArchiveFormat.SelectedItem as ArchiveFormat;
|
||||||
|
if (null != format)
|
||||||
|
ArchiveName.Text = Path.ChangeExtension (initial_name, format.Extensions.First());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ResourceOptions ArchiveOptions { get; private set; }
|
public ResourceOptions ArchiveOptions { get; private set; }
|
||||||
|
|
||||||
void Button_Click (object sender, RoutedEventArgs e)
|
void Button_Click (object sender, RoutedEventArgs e)
|
||||||
{
|
{
|
||||||
|
string arc_name = Path.GetFullPath (ArchiveName.Text);
|
||||||
|
if (File.Exists (arc_name))
|
||||||
|
{
|
||||||
|
string text = string.Format (guiStrings.MsgOverwrite, arc_name);
|
||||||
|
var rc = MessageBox.Show (this, text, guiStrings.TextConfirmOverwrite, MessageBoxButton.YesNo,
|
||||||
|
MessageBoxImage.Question);
|
||||||
|
if (MessageBoxResult.Yes != rc)
|
||||||
|
return;
|
||||||
|
}
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -92,11 +106,21 @@ namespace GARbro.GUI
|
|||||||
}
|
}
|
||||||
OptionsWidget.Content = widget;
|
OptionsWidget.Content = widget;
|
||||||
OptionsWidget.Visibility = null != widget ? Visibility.Visible : Visibility.Hidden;
|
OptionsWidget.Visibility = null != widget ? Visibility.Visible : Visibility.Hidden;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty (ArchiveName.Text))
|
||||||
|
{
|
||||||
|
ArchiveName.Text = Path.ChangeExtension (ArchiveName.Text, format.Extensions.First());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void CanExecuteAlways (object sender, CanExecuteRoutedEventArgs e)
|
void CanExecuteAlways (object sender, CanExecuteRoutedEventArgs e)
|
||||||
{
|
{
|
||||||
e.CanExecute = true;
|
e.CanExecute = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void ArchiveName_TextChanged (object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.ButtonOk.IsEnabled = ArchiveName.Text.Length > 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@
|
|||||||
<TargetZone>LocalIntranet</TargetZone>
|
<TargetZone>LocalIntranet</TargetZone>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<ApplicationManifest>Properties\app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<SignManifests>true</SignManifests>
|
<SignManifests>true</SignManifests>
|
||||||
@@ -130,11 +130,14 @@
|
|||||||
<Compile Include="ExtractFile.xaml.cs">
|
<Compile Include="ExtractFile.xaml.cs">
|
||||||
<DependentUpon>ExtractFile.xaml</DependentUpon>
|
<DependentUpon>ExtractFile.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="GarCreate.cs" />
|
||||||
|
<Compile Include="GarExtract.cs" />
|
||||||
<Compile Include="HistoryStack.cs" />
|
<Compile Include="HistoryStack.cs" />
|
||||||
<Compile Include="ImagePreview.cs" />
|
<Compile Include="ImagePreview.cs" />
|
||||||
<Compile Include="ListBoxEx.cs" />
|
<Compile Include="ListViewEx.cs" />
|
||||||
<Compile Include="ModalWindow.cs" />
|
<Compile Include="ModalWindow.cs" />
|
||||||
<Compile Include="Settings.cs" />
|
<Compile Include="Settings.cs" />
|
||||||
|
<Compile Include="Shell.cs" />
|
||||||
<Compile Include="Strings\guiStrings.Designer.cs">
|
<Compile Include="Strings\guiStrings.Designer.cs">
|
||||||
<AutoGen>True</AutoGen>
|
<AutoGen>True</AutoGen>
|
||||||
<DesignTime>True</DesignTime>
|
<DesignTime>True</DesignTime>
|
||||||
@@ -198,6 +201,7 @@
|
|||||||
<LastGenOutput>guiStrings.Designer.cs</LastGenOutput>
|
<LastGenOutput>guiStrings.Designer.cs</LastGenOutput>
|
||||||
</EmbeddedResource>
|
</EmbeddedResource>
|
||||||
<EmbeddedResource Include="Strings\guiStrings.ru-RU.resx" />
|
<EmbeddedResource Include="Strings\guiStrings.ru-RU.resx" />
|
||||||
|
<None Include="app.manifest" />
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
<None Include="Properties\app.manifest" />
|
<None Include="Properties\app.manifest" />
|
||||||
<None Include="Properties\Settings.settings">
|
<None Include="Properties\Settings.settings">
|
||||||
|
|||||||
@@ -144,10 +144,10 @@ namespace GameRes
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Create resource archive named <paramref name="filename"/> containing entries from the
|
/// Create resource wihin stream <paramref name="file"/> containing entries from the
|
||||||
/// supplied <paramref name="list"/> and applying necessary <paramref name="options"/>.
|
/// supplied <paramref name="list"/> and applying necessary <paramref name="options"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Create (string filename, IEnumerable<Entry> list, ResourceOptions options = null)
|
public virtual void Create (Stream file, IEnumerable<Entry> list, ResourceOptions options = null)
|
||||||
{
|
{
|
||||||
throw new NotImplementedException ("ArchiveFormat.Create is not implemented");
|
throw new NotImplementedException ("ArchiveFormat.Create is not implemented");
|
||||||
}
|
}
|
||||||
@@ -329,7 +329,7 @@ namespace GameRes
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class InvalidFormatException : Exception
|
public class InvalidFormatException : FileFormatException
|
||||||
{
|
{
|
||||||
public InvalidFormatException() : base(garStrings.MsgInvalidFormat) { }
|
public InvalidFormatException() : base(garStrings.MsgInvalidFormat) { }
|
||||||
public InvalidFormatException (string msg) : base (msg) { }
|
public InvalidFormatException (string msg) : base (msg) { }
|
||||||
@@ -346,4 +346,37 @@ namespace GameRes
|
|||||||
public InvalidEncryptionScheme() : base(garStrings.MsgInvalidEncryption) { }
|
public InvalidEncryptionScheme() : base(garStrings.MsgInvalidEncryption) { }
|
||||||
public InvalidEncryptionScheme (string msg) : base (msg) { }
|
public InvalidEncryptionScheme (string msg) : base (msg) { }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class FileSizeException : Exception
|
||||||
|
{
|
||||||
|
public FileSizeException () : base (garStrings.MsgFileTooLarge) { }
|
||||||
|
public FileSizeException (string msg) : base (msg) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public class InvalidFileName : Exception
|
||||||
|
{
|
||||||
|
public string FileName { get; set; }
|
||||||
|
|
||||||
|
public InvalidFileName (string filename)
|
||||||
|
: this (filename, garStrings.MsgInvalidFileName)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFileName (string filename, string message)
|
||||||
|
: base (message)
|
||||||
|
{
|
||||||
|
FileName = filename;
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFileName (string filename, Exception X)
|
||||||
|
: this (filename, garStrings.MsgInvalidFileName, X)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public InvalidFileName (string filename, string message, Exception X)
|
||||||
|
: base (message, X)
|
||||||
|
{
|
||||||
|
FileName = filename;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
18
GameRes/Strings/garStrings.Designer.cs
generated
18
GameRes/Strings/garStrings.Designer.cs
generated
@@ -60,6 +60,15 @@ namespace GameRes.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to File is too large.
|
||||||
|
/// </summary>
|
||||||
|
public static string MsgFileTooLarge {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MsgFileTooLarge", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Inappropriate encryption scheme.
|
/// Looks up a localized string similar to Inappropriate encryption scheme.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -69,6 +78,15 @@ namespace GameRes.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Invalid file name.
|
||||||
|
/// </summary>
|
||||||
|
public static string MsgInvalidFileName {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MsgInvalidFileName", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Invalid file format.
|
/// Looks up a localized string similar to Invalid file format.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -117,9 +117,15 @@
|
|||||||
<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="MsgFileTooLarge" xml:space="preserve">
|
||||||
|
<value>File is too large</value>
|
||||||
|
</data>
|
||||||
<data name="MsgInvalidEncryption" xml:space="preserve">
|
<data name="MsgInvalidEncryption" xml:space="preserve">
|
||||||
<value>Inappropriate encryption scheme</value>
|
<value>Inappropriate encryption scheme</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MsgInvalidFileName" xml:space="preserve">
|
||||||
|
<value>Invalid file name</value>
|
||||||
|
</data>
|
||||||
<data name="MsgInvalidFormat" xml:space="preserve">
|
<data name="MsgInvalidFormat" xml:space="preserve">
|
||||||
<value>Invalid file format</value>
|
<value>Invalid file format</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
@@ -117,9 +117,15 @@
|
|||||||
<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="MsgFileTooLarge" xml:space="preserve">
|
||||||
|
<value>Слишком большой размер файла</value>
|
||||||
|
</data>
|
||||||
<data name="MsgInvalidEncryption" xml:space="preserve">
|
<data name="MsgInvalidEncryption" xml:space="preserve">
|
||||||
<value>Неподходящий метод шифрования</value>
|
<value>Неподходящий метод шифрования</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MsgInvalidFileName" xml:space="preserve">
|
||||||
|
<value>Недопустимое имя файла</value>
|
||||||
|
</data>
|
||||||
<data name="MsgInvalidFormat" xml:space="preserve">
|
<data name="MsgInvalidFormat" xml:space="preserve">
|
||||||
<value>Некорректный формат файла</value>
|
<value>Некорректный формат файла</value>
|
||||||
</data>
|
</data>
|
||||||
|
|||||||
140
GarCreate.cs
Normal file
140
GarCreate.cs
Normal file
@@ -0,0 +1,140 @@
|
|||||||
|
//! \file GarCreate.cs
|
||||||
|
//! \date Fri Jul 25 05:56:29 2014
|
||||||
|
//! \brief Create archive frontend.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2014 by morkt
|
||||||
|
//
|
||||||
|
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
// of this software and associated documentation files (the "Software"), to
|
||||||
|
// deal in the Software without restriction, including without limitation the
|
||||||
|
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
// sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
// furnished to do so, subject to the following conditions:
|
||||||
|
//
|
||||||
|
// The above copyright notice and this permission notice shall be included in
|
||||||
|
// all copies or substantial portions of the Software.
|
||||||
|
//
|
||||||
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
// IN THE SOFTWARE.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Input;
|
||||||
|
using GameRes;
|
||||||
|
using GARbro.GUI.Strings;
|
||||||
|
|
||||||
|
namespace GARbro.GUI
|
||||||
|
{
|
||||||
|
public partial class MainWindow : Window
|
||||||
|
{
|
||||||
|
private void CreateArchiveExec (object sender, ExecutedRoutedEventArgs e)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Directory.SetCurrentDirectory (CurrentPath);
|
||||||
|
var items = CurrentDirectory.SelectedItems.Cast<EntryViewModel>();
|
||||||
|
string arc_name = Path.GetFileName (CurrentPath);
|
||||||
|
if (!items.Skip (1).Any()) // items.Count() == 1
|
||||||
|
{
|
||||||
|
var item = items.First();
|
||||||
|
if (item.IsDirectory)
|
||||||
|
arc_name = Path.GetFileNameWithoutExtension (item.Name);
|
||||||
|
}
|
||||||
|
|
||||||
|
var dialog = new CreateArchiveDialog (arc_name);
|
||||||
|
dialog.Owner = this;
|
||||||
|
if (!dialog.ShowDialog().Value)
|
||||||
|
return;
|
||||||
|
if (string.IsNullOrEmpty (dialog.ArchiveName.Text))
|
||||||
|
{
|
||||||
|
SetStatusText ("Archive name is empty");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var format = dialog.ArchiveFormat.SelectedItem as ArchiveFormat;
|
||||||
|
if (null == format)
|
||||||
|
{
|
||||||
|
SetStatusText ("Format is not selected");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
IEnumerable<Entry> file_list;
|
||||||
|
if (format.IsHierarchic)
|
||||||
|
file_list = BuildFileList (items, AddFilesRecursive);
|
||||||
|
else
|
||||||
|
file_list = BuildFileList (items, AddFilesFromDir);
|
||||||
|
|
||||||
|
arc_name = Path.GetFullPath (dialog.ArchiveName.Text);
|
||||||
|
using (var tmp_file = new GARbro.Shell.TemporaryFile (Path.GetDirectoryName (arc_name),
|
||||||
|
Path.GetRandomFileName()))
|
||||||
|
{
|
||||||
|
using (var file = File.Create (tmp_file.Name))
|
||||||
|
format.Create (file, file_list, dialog.ArchiveOptions);
|
||||||
|
GARbro.Shell.File.Rename (tmp_file.Name, arc_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (Exception X)
|
||||||
|
{
|
||||||
|
PopupError (X.Message, guiStrings.TextCreateArchiveError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate void AddFilesEnumerator (IList<Entry> list, string path, DirectoryInfo path_info);
|
||||||
|
|
||||||
|
IEnumerable<Entry> BuildFileList (IEnumerable<EntryViewModel> files, AddFilesEnumerator add_files)
|
||||||
|
{
|
||||||
|
var list = new List<Entry>();
|
||||||
|
foreach (var entry in files)
|
||||||
|
{
|
||||||
|
if (entry.IsDirectory)
|
||||||
|
{
|
||||||
|
if (".." != entry.Name)
|
||||||
|
{
|
||||||
|
var dir = new DirectoryInfo (entry.Name);
|
||||||
|
add_files (list, entry.Name, dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (entry.Size < uint.MaxValue)
|
||||||
|
{
|
||||||
|
list.Add (entry.Source);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFilesFromDir (IList<Entry> list, string path, DirectoryInfo dir)
|
||||||
|
{
|
||||||
|
foreach (var file in dir.EnumerateFiles())
|
||||||
|
{
|
||||||
|
if (0 != (file.Attributes & (FileAttributes.Hidden | FileAttributes.System)))
|
||||||
|
continue;
|
||||||
|
if (file.Length >= uint.MaxValue)
|
||||||
|
continue;
|
||||||
|
string name = Path.Combine (path, file.Name);
|
||||||
|
var e = FormatCatalog.Instance.CreateEntry (name);
|
||||||
|
e.Size = (uint)file.Length;
|
||||||
|
list.Add (e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AddFilesRecursive (IList<Entry> list, string path, DirectoryInfo info)
|
||||||
|
{
|
||||||
|
foreach (var dir in info.EnumerateDirectories())
|
||||||
|
{
|
||||||
|
string subdir = Path.Combine (path, dir.Name);
|
||||||
|
var subdir_info = new DirectoryInfo (subdir);
|
||||||
|
AddFilesRecursive (list, subdir, subdir_info);
|
||||||
|
}
|
||||||
|
AddFilesFromDir (list, path, info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -36,7 +36,6 @@ using System.Windows.Media;
|
|||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Microsoft.VisualBasic.FileIO;
|
using Microsoft.VisualBasic.FileIO;
|
||||||
using Ookii.Dialogs.Wpf;
|
|
||||||
using GARbro.GUI.Properties;
|
using GARbro.GUI.Properties;
|
||||||
using GARbro.GUI.Strings;
|
using GARbro.GUI.Strings;
|
||||||
using GameRes;
|
using GameRes;
|
||||||
@@ -772,220 +771,6 @@ namespace GARbro.GUI
|
|||||||
*/
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Handle "Extract item" command.
|
|
||||||
/// </summary>
|
|
||||||
private void ExtractItemExec (object sender, ExecutedRoutedEventArgs e)
|
|
||||||
{
|
|
||||||
var entry = CurrentDirectory.SelectedItem as EntryViewModel;
|
|
||||||
if (null == entry)
|
|
||||||
return;
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (!ViewModel.IsArchive)
|
|
||||||
{
|
|
||||||
if (!entry.IsDirectory)
|
|
||||||
{
|
|
||||||
var arc_dir = CurrentPath;
|
|
||||||
var source = Path.Combine (arc_dir, entry.Name);
|
|
||||||
string destination = arc_dir;
|
|
||||||
// extract into directory named after archive
|
|
||||||
if (!string.IsNullOrEmpty (Path.GetExtension (entry.Name)))
|
|
||||||
destination = Path.GetFileNameWithoutExtension (source);
|
|
||||||
ExtractArchive (source, destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (null != m_app.CurrentArchive)
|
|
||||||
{
|
|
||||||
var vm = ViewModel as ArchiveViewModel;
|
|
||||||
string destination = Path.GetDirectoryName (vm.Path);
|
|
||||||
string arc_name = Path.GetFileName (vm.Path);
|
|
||||||
if (entry.Name == ".." && vm.SubDir == "") // root entry
|
|
||||||
{
|
|
||||||
ExtractArchive (m_app.CurrentArchive, arc_name, destination);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ExtractFileFromArchive (entry, destination);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
catch (Exception X)
|
|
||||||
{
|
|
||||||
PopupError (X.Message, guiStrings.MsgErrorExtracting);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractArchive (string path, string destination)
|
|
||||||
{
|
|
||||||
string arc_name = Path.GetFileName (path);
|
|
||||||
FormatCatalog.Instance.LastError = null;
|
|
||||||
var arc = ArcFile.TryOpen (path);
|
|
||||||
if (null != arc)
|
|
||||||
{
|
|
||||||
ExtractArchive (arc, arc_name, destination);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
string error_message;
|
|
||||||
if (FormatCatalog.Instance.LastError != null)
|
|
||||||
error_message = FormatCatalog.Instance.LastError.Message;
|
|
||||||
else
|
|
||||||
error_message = guiStrings.MsgUnknownFormat;
|
|
||||||
SetStatusText (string.Format ("{1}: {0}", error_message, arc_name));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractArchive (ArcFile arc, string arc_name, string destination)
|
|
||||||
{
|
|
||||||
if (0 == arc.Dir.Count)
|
|
||||||
{
|
|
||||||
SetStatusText (string.Format ("{1}: {0}", guiStrings.MsgEmptyArchive, arc_name));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
var extractDialog = new ExtractArchiveDialog (arc_name, destination);
|
|
||||||
extractDialog.Owner = this;
|
|
||||||
var result = extractDialog.ShowDialog();
|
|
||||||
if (!result.Value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
destination = extractDialog.DestinationDir.Text;
|
|
||||||
if (!string.IsNullOrEmpty (destination))
|
|
||||||
{
|
|
||||||
destination = Path.GetFullPath (destination);
|
|
||||||
Trace.WriteLine (destination, "Extract destination");
|
|
||||||
StopWatchDirectoryChanges();
|
|
||||||
try
|
|
||||||
{
|
|
||||||
Directory.CreateDirectory (destination);
|
|
||||||
Directory.SetCurrentDirectory (destination);
|
|
||||||
}
|
|
||||||
finally
|
|
||||||
{
|
|
||||||
m_watcher.EnableRaisingEvents = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
IEnumerable<Entry> file_list = arc.Dir;
|
|
||||||
bool skip_images = !extractDialog.ExtractImages.IsChecked.Value;
|
|
||||||
bool skip_script = !extractDialog.ExtractText.IsChecked.Value;
|
|
||||||
if (skip_images || skip_script)
|
|
||||||
file_list = file_list.Where (f => !(skip_images && f.Type == "image") && !(skip_script && f.Type == "script"));
|
|
||||||
|
|
||||||
if (!file_list.Any())
|
|
||||||
{
|
|
||||||
SetStatusText (string.Format ("{1}: {0}", guiStrings.MsgNoFiles, arc_name));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
ImageFormat image_format = null;
|
|
||||||
if (!skip_images)
|
|
||||||
image_format = extractDialog.GetImageFormat (extractDialog.ImageConversionFormat);
|
|
||||||
|
|
||||||
SetStatusText (string.Format(guiStrings.MsgExtractingTo, arc_name, destination));
|
|
||||||
ExtractFilesFromArchive (string.Format (guiStrings.MsgExtractingArchive, arc_name),
|
|
||||||
arc, file_list, image_format);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractFileFromArchive (EntryViewModel entry, string destination)
|
|
||||||
{
|
|
||||||
var extractDialog = new ExtractFile (entry, destination);
|
|
||||||
extractDialog.Owner = this;
|
|
||||||
var result = extractDialog.ShowDialog();
|
|
||||||
if (!result.Value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var file_list = (ViewModel as ArchiveViewModel).GetFiles (entry);
|
|
||||||
|
|
||||||
destination = extractDialog.DestinationDir.Text;
|
|
||||||
if (!string.IsNullOrEmpty (destination))
|
|
||||||
{
|
|
||||||
destination = Path.GetFullPath (destination);
|
|
||||||
Directory.CreateDirectory (destination);
|
|
||||||
Directory.SetCurrentDirectory (destination);
|
|
||||||
}
|
|
||||||
ImageFormat format = null;
|
|
||||||
if (entry.Type == "image")
|
|
||||||
format = extractDialog.GetImageFormat (extractDialog.ImageConversionFormat);
|
|
||||||
|
|
||||||
string arc_name = Path.GetFileName (CurrentPath);
|
|
||||||
ExtractFilesFromArchive (string.Format (guiStrings.MsgExtractingFile, arc_name),
|
|
||||||
m_app.CurrentArchive, file_list, format);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void ExtractFilesFromArchive (string text, ArcFile arc, IEnumerable<Entry> file_list,
|
|
||||||
ImageFormat image_format = null)
|
|
||||||
{
|
|
||||||
file_list = file_list.OrderBy (e => e.Offset);
|
|
||||||
var extractProgressDialog = new ProgressDialog ()
|
|
||||||
{
|
|
||||||
WindowTitle = guiStrings.TextTitle,
|
|
||||||
Text = text,
|
|
||||||
Description = "",
|
|
||||||
MinimizeBox = true,
|
|
||||||
};
|
|
||||||
if (!file_list.Skip (1).Any()) // 1 == file_list.Count()
|
|
||||||
{
|
|
||||||
extractProgressDialog.Description = file_list.First().Name;
|
|
||||||
extractProgressDialog.ProgressBarStyle = ProgressBarStyle.MarqueeProgressBar;
|
|
||||||
}
|
|
||||||
extractProgressDialog.DoWork += (s, e) =>
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
int total = file_list.Count();
|
|
||||||
int i = 0;
|
|
||||||
foreach (var entry in file_list)
|
|
||||||
{
|
|
||||||
if (extractProgressDialog.CancellationPending)
|
|
||||||
break;
|
|
||||||
if (total > 1)
|
|
||||||
extractProgressDialog.ReportProgress (i*100/total, null, entry.Name);
|
|
||||||
if (null != image_format && entry.Type == "image")
|
|
||||||
ExtractImage (arc, entry, image_format);
|
|
||||||
else
|
|
||||||
arc.Extract (entry);
|
|
||||||
++i;
|
|
||||||
}
|
|
||||||
SetStatusText (string.Format (guiStrings.MsgExtractCompletePlural, i,
|
|
||||||
Localization.Plural (i, "file")));
|
|
||||||
}
|
|
||||||
catch (Exception X)
|
|
||||||
{
|
|
||||||
SetStatusText (X.Message);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
extractProgressDialog.RunWorkerCompleted += (s, e) => {
|
|
||||||
extractProgressDialog.Dispose();
|
|
||||||
if (!ViewModel.IsArchive)
|
|
||||||
{
|
|
||||||
arc.Dispose();
|
|
||||||
Dispatcher.Invoke (RefreshView);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
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>
|
/// <summary>
|
||||||
/// Handle "Exit" command.
|
/// Handle "Exit" command.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
21
Strings/guiStrings.Designer.cs
generated
21
Strings/guiStrings.Designer.cs
generated
@@ -438,6 +438,18 @@ namespace GARbro.GUI.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to File {0}
|
||||||
|
///already exists.
|
||||||
|
///
|
||||||
|
///Overwrite?.
|
||||||
|
/// </summary>
|
||||||
|
public static string MsgOverwrite {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("MsgOverwrite", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Ready.
|
/// Looks up a localized string similar to Ready.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -546,6 +558,15 @@ namespace GARbro.GUI.Strings {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Looks up a localized string similar to Confirm overwrite.
|
||||||
|
/// </summary>
|
||||||
|
public static string TextConfirmOverwrite {
|
||||||
|
get {
|
||||||
|
return ResourceManager.GetString("TextConfirmOverwrite", resourceCulture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Looks up a localized string similar to Create archive.
|
/// Looks up a localized string similar to Create archive.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -318,4 +318,13 @@
|
|||||||
<data name="TooltipForward" xml:space="preserve">
|
<data name="TooltipForward" xml:space="preserve">
|
||||||
<value>Forward</value>
|
<value>Forward</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MsgOverwrite" xml:space="preserve">
|
||||||
|
<value>File {0}
|
||||||
|
already exists.
|
||||||
|
|
||||||
|
Overwrite?</value>
|
||||||
|
</data>
|
||||||
|
<data name="TextConfirmOverwrite" xml:space="preserve">
|
||||||
|
<value>Confirm overwrite</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
@@ -321,4 +321,13 @@
|
|||||||
<data name="TooltipForward" xml:space="preserve">
|
<data name="TooltipForward" xml:space="preserve">
|
||||||
<value>Вперёд</value>
|
<value>Вперёд</value>
|
||||||
</data>
|
</data>
|
||||||
|
<data name="MsgOverwrite" xml:space="preserve">
|
||||||
|
<value>Файл под именем '{0}'
|
||||||
|
уже существует.
|
||||||
|
|
||||||
|
Перезаписать?</value>
|
||||||
|
</data>
|
||||||
|
<data name="TextConfirmOverwrite" xml:space="preserve">
|
||||||
|
<value>Подтвердите перезапись</value>
|
||||||
|
</data>
|
||||||
</root>
|
</root>
|
||||||
Reference in New Issue
Block a user