mirror of
https://github.com/crskycode/GARbro.git
synced 2024-11-23 13:45:34 +08:00
added dialog popup on extraction errors.
looks like Ookii.Dialogs have to be replaced with manual progress dialog implementation, as i have no control over progress dialog window once extraction has begun. frankly, i just need to be able to call StopProgressDialog and StartProgressDialog from IProgressDialog interface, but Ookii does not provide such low-level access.
This commit is contained in:
parent
5c9d56c841
commit
154699160b
20
GUI/FileErrorDialog.xaml
Normal file
20
GUI/FileErrorDialog.xaml
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<w:ModalWindow x:Class="GARbro.GUI.FileErrorDialog"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:w="clr-namespace:Rnd.Windows"
|
||||||
|
Title="{Binding Title}" ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||||
|
ResizeMode="NoResize" SizeToContent="WidthAndHeight"
|
||||||
|
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
|
||||||
|
<StackPanel Orientation="Vertical">
|
||||||
|
<TextBox x:Name="ErrorText" Text="{Binding Text}" IsReadOnly="True" Background="Transparent" BorderThickness="0" Margin="10"/>
|
||||||
|
<Separator/>
|
||||||
|
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" VerticalAlignment="Center">
|
||||||
|
<CheckBox x:Name="IgnoreErrors" Content="_Ignore further errors" Margin="10" VerticalAlignment="Center"/>
|
||||||
|
<Button Content="_Continue" Margin="10" Width="75" Height="25" IsDefault="True" Click="ContinueButton_Click"/>
|
||||||
|
<Button Content="_Abort" Margin="10" Width="75" Height="25" IsCancel="True" Click="AbortButton_Click"/>
|
||||||
|
</StackPanel>
|
||||||
|
</StackPanel>
|
||||||
|
<Window.InputBindings>
|
||||||
|
<KeyBinding Gesture="Ctrl+C" Command="{Binding CopyCommand}"/>
|
||||||
|
</Window.InputBindings>
|
||||||
|
</w:ModalWindow>
|
76
GUI/FileErrorDialog.xaml.cs
Normal file
76
GUI/FileErrorDialog.xaml.cs
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
using System;
|
||||||
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Input;
|
||||||
|
|
||||||
|
namespace GARbro.GUI
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Interaction logic for FileErrorDialog.xaml
|
||||||
|
/// </summary>
|
||||||
|
public partial class FileErrorDialog : Rnd.Windows.ModalWindow
|
||||||
|
{
|
||||||
|
public FileErrorDialog (string title, string error_text)
|
||||||
|
{
|
||||||
|
InitializeComponent();
|
||||||
|
this.DataContext = new ViewModel { Title = title, Text = error_text };
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ContinueButton_Click (object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.DialogResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AbortButton_Click (object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
|
this.DialogResult = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ViewModel
|
||||||
|
{
|
||||||
|
public string Title { get; set; }
|
||||||
|
public string Text { get; set; }
|
||||||
|
public ICommand CopyCommand { get; private set; }
|
||||||
|
|
||||||
|
public ViewModel ()
|
||||||
|
{
|
||||||
|
CopyCommand = new ActionCommand (CopyText);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void CopyText ()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
Clipboard.SetText (Text);
|
||||||
|
}
|
||||||
|
catch (Exception X)
|
||||||
|
{
|
||||||
|
System.Diagnostics.Trace.WriteLine (X.Message, "Clipboard error");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ActionCommand : ICommand
|
||||||
|
{
|
||||||
|
readonly Action m_action;
|
||||||
|
|
||||||
|
public ActionCommand (Action action)
|
||||||
|
{
|
||||||
|
m_action = action;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Execute (object parameter)
|
||||||
|
{
|
||||||
|
m_action();
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool CanExecute (object parameter)
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable 67
|
||||||
|
public event EventHandler CanExecuteChanged;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -147,6 +147,9 @@
|
|||||||
<Compile Include="ExtractFile.xaml.cs">
|
<Compile Include="ExtractFile.xaml.cs">
|
||||||
<DependentUpon>ExtractFile.xaml</DependentUpon>
|
<DependentUpon>ExtractFile.xaml</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="FileErrorDialog.xaml.cs">
|
||||||
|
<DependentUpon>FileErrorDialog.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="GarConvert.cs" />
|
<Compile Include="GarConvert.cs" />
|
||||||
<Compile Include="GarCreate.cs" />
|
<Compile Include="GarCreate.cs" />
|
||||||
<Compile Include="GarExtract.cs" />
|
<Compile Include="GarExtract.cs" />
|
||||||
@ -195,6 +198,10 @@
|
|||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
</Page>
|
</Page>
|
||||||
|
<Page Include="FileErrorDialog.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="MainWindow.xaml">
|
<Page Include="MainWindow.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
@ -28,13 +28,13 @@ using System.IO;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Diagnostics;
|
using System.Runtime.InteropServices;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
|
using System.Windows.Interop;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
using Ookii.Dialogs.Wpf;
|
using Ookii.Dialogs.Wpf;
|
||||||
using GameRes;
|
using GameRes;
|
||||||
using GameRes.Strings;
|
|
||||||
using GARbro.GUI.Strings;
|
using GARbro.GUI.Strings;
|
||||||
using GARbro.GUI.Properties;
|
using GARbro.GUI.Properties;
|
||||||
|
|
||||||
@ -116,6 +116,7 @@ namespace GARbro.GUI
|
|||||||
private bool m_convert_audio;
|
private bool m_convert_audio;
|
||||||
private ImageFormat m_image_format;
|
private ImageFormat m_image_format;
|
||||||
private int m_extract_count;
|
private int m_extract_count;
|
||||||
|
private int m_skip_count;
|
||||||
private bool m_extract_in_progress = false;
|
private bool m_extract_in_progress = false;
|
||||||
private ProgressDialog m_progress_dialog;
|
private ProgressDialog m_progress_dialog;
|
||||||
private Exception m_pending_error;
|
private Exception m_pending_error;
|
||||||
@ -269,7 +270,6 @@ namespace GARbro.GUI
|
|||||||
m_progress_dialog.ProgressBarStyle = ProgressBarStyle.MarqueeProgressBar;
|
m_progress_dialog.ProgressBarStyle = ProgressBarStyle.MarqueeProgressBar;
|
||||||
}
|
}
|
||||||
m_convert_audio = !m_skip_audio && Settings.Default.appConvertAudio;
|
m_convert_audio = !m_skip_audio && Settings.Default.appConvertAudio;
|
||||||
m_extract_count = 0;
|
|
||||||
m_pending_error = null;
|
m_pending_error = null;
|
||||||
m_progress_dialog.DoWork += (s, e) => ExtractWorker (file_list);
|
m_progress_dialog.DoWork += (s, e) => ExtractWorker (file_list);
|
||||||
m_progress_dialog.RunWorkerCompleted += OnExtractComplete;
|
m_progress_dialog.RunWorkerCompleted += OnExtractComplete;
|
||||||
@ -279,16 +279,20 @@ namespace GARbro.GUI
|
|||||||
|
|
||||||
void ExtractWorker (IEnumerable<Entry> file_list)
|
void ExtractWorker (IEnumerable<Entry> file_list)
|
||||||
{
|
{
|
||||||
try
|
m_extract_count = 0;
|
||||||
|
m_skip_count = 0;
|
||||||
|
var arc = m_fs.Source;
|
||||||
|
int total = file_list.Count();
|
||||||
|
int progress_count = 0;
|
||||||
|
bool ignore_errors = false;
|
||||||
|
foreach (var entry in file_list)
|
||||||
{
|
{
|
||||||
var arc = m_fs.Source;
|
if (m_progress_dialog.CancellationPending)
|
||||||
int total = file_list.Count();
|
break;
|
||||||
foreach (var entry in file_list)
|
if (total > 1)
|
||||||
|
m_progress_dialog.ReportProgress (progress_count++*100/total, null, entry.Name);
|
||||||
|
try
|
||||||
{
|
{
|
||||||
if (m_progress_dialog.CancellationPending)
|
|
||||||
break;
|
|
||||||
if (total > 1)
|
|
||||||
m_progress_dialog.ReportProgress (m_extract_count*100/total, null, entry.Name);
|
|
||||||
if (null != m_image_format && entry.Type == "image")
|
if (null != m_image_format && entry.Type == "image")
|
||||||
ExtractImage (arc, entry, m_image_format);
|
ExtractImage (arc, entry, m_image_format);
|
||||||
else if (m_convert_audio && entry.Type == "audio")
|
else if (m_convert_audio && entry.Type == "audio")
|
||||||
@ -297,43 +301,85 @@ namespace GARbro.GUI
|
|||||||
arc.Extract (entry);
|
arc.Extract (entry);
|
||||||
++m_extract_count;
|
++m_extract_count;
|
||||||
}
|
}
|
||||||
|
catch (Exception X)
|
||||||
|
{
|
||||||
|
if (!ignore_errors)
|
||||||
|
{
|
||||||
|
IntPtr progress_handle = IntPtr.Zero;
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var error_text = string.Format ("{0}\n{1}\n{2}", "Failed to extract file",
|
||||||
|
entry.Name, X.Message);
|
||||||
|
bool dialog_result = false;
|
||||||
|
m_main.Dispatcher.Invoke (() => {
|
||||||
|
progress_handle = HideProgressDialog();
|
||||||
|
var dialog = new FileErrorDialog ("File extraction error", error_text);
|
||||||
|
dialog.Owner = m_main;
|
||||||
|
dialog_result = dialog.ShowDialog() ?? false;
|
||||||
|
ignore_errors = dialog.IgnoreErrors.IsChecked ?? false;
|
||||||
|
});
|
||||||
|
if (!dialog_result)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
if (progress_handle != IntPtr.Zero)
|
||||||
|
ShowWindow (progress_handle, SW_SHOW);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++m_skip_count;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch (Exception X)
|
}
|
||||||
{
|
|
||||||
m_pending_error = X;
|
const int SW_HIDE = 0;
|
||||||
}
|
const int SW_SHOW = 5;
|
||||||
|
|
||||||
|
[DllImport("user32.dll", SetLastError = true)]
|
||||||
|
static extern IntPtr FindWindowEx (IntPtr hwndParent, IntPtr hwndChildAfter, string lpszClass, string lpszWindow);
|
||||||
|
[DllImport("user32.dll")][return: MarshalAs(UnmanagedType.Bool)]
|
||||||
|
static extern bool ShowWindow (IntPtr hWnd, int nCmdShow);
|
||||||
|
|
||||||
|
IntPtr HideProgressDialog ()
|
||||||
|
{
|
||||||
|
// IntPtr parent = new WindowInteropHelper (m_main).Handle;
|
||||||
|
// var found = FindWindowEx (parent, IntPtr.Zero, null, m_progress_dialog.WindowTitle);
|
||||||
|
var found = FindWindowEx (IntPtr.Zero, IntPtr.Zero, null, m_progress_dialog.WindowTitle);
|
||||||
|
if (IntPtr.Zero != found)
|
||||||
|
ShowWindow (found, SW_HIDE);
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ShowErrorDialog (string error_text)
|
||||||
|
{
|
||||||
|
var dialog = new FileErrorDialog ("File extraction error", error_text);
|
||||||
|
dialog.Owner = m_main;
|
||||||
|
return dialog.ShowDialog() ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ExtractImage (ArcFile arc, Entry entry, ImageFormat target_format)
|
void ExtractImage (ArcFile arc, Entry entry, ImageFormat target_format)
|
||||||
{
|
{
|
||||||
try
|
using (var decoder = arc.OpenImage (entry))
|
||||||
{
|
{
|
||||||
using (var decoder = arc.OpenImage (entry))
|
var src_format = decoder.SourceFormat; // could be null
|
||||||
|
string target_ext = target_format.Extensions.FirstOrDefault() ?? "";
|
||||||
|
string outname = FindUniqueFileName (entry.Name, target_ext);
|
||||||
|
if (src_format == target_format)
|
||||||
{
|
{
|
||||||
var src_format = decoder.SourceFormat; // could be null
|
// source format is the same as a target, copy file as is
|
||||||
string target_ext = target_format.Extensions.FirstOrDefault() ?? "";
|
using (var output = ArchiveFormat.CreateFile (outname))
|
||||||
string outname = FindUniqueFileName (entry.Name, target_ext);
|
decoder.Source.CopyTo (output);
|
||||||
if (src_format == target_format)
|
return;
|
||||||
{
|
}
|
||||||
// source format is the same as a target, copy file as is
|
ImageData image = decoder.Image;
|
||||||
using (var output = ArchiveFormat.CreateFile (outname))
|
if (m_adjust_image_offset)
|
||||||
decoder.Source.CopyTo (output);
|
{
|
||||||
return;
|
image = AdjustImageOffset (image);
|
||||||
}
|
}
|
||||||
ImageData image = decoder.Image;
|
using (var outfile = ArchiveFormat.CreateFile (outname))
|
||||||
if (m_adjust_image_offset)
|
{
|
||||||
{
|
target_format.Write (outfile, image);
|
||||||
image = AdjustImageOffset (image);
|
|
||||||
}
|
|
||||||
using (var outfile = ArchiveFormat.CreateFile (outname))
|
|
||||||
{
|
|
||||||
target_format.Write (outfile, image);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
catch
|
|
||||||
{
|
|
||||||
throw new InvalidFormatException (string.Format ("{1}: {0}", guiStrings.MsgUnableInterpretImage, entry.Name));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -372,7 +418,7 @@ namespace GARbro.GUI
|
|||||||
using (var sound = AudioFormat.Read (file))
|
using (var sound = AudioFormat.Read (file))
|
||||||
{
|
{
|
||||||
if (null == sound)
|
if (null == sound)
|
||||||
throw new InvalidFormatException (string.Format ("{1}: {0}", guiStrings.MsgUnableInterpretAudio, entry.Name));
|
throw new InvalidFormatException (guiStrings.MsgUnableInterpretAudio);
|
||||||
ConvertAudio (entry.Name, sound);
|
ConvertAudio (entry.Name, sound);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user