archive creation methods moved to separate helper class.

This commit is contained in:
morkt
2014-07-29 07:14:09 +04:00
parent 1dc284ddfd
commit 06bbc60d78

View File

@@ -27,6 +27,7 @@ using System;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics; using System.Diagnostics;
using System.Windows; using System.Windows;
using System.Windows.Input; using System.Windows.Input;
@@ -43,62 +44,95 @@ namespace GARbro.GUI
StopWatchDirectoryChanges(); StopWatchDirectoryChanges();
try try
{ {
Directory.SetCurrentDirectory (CurrentPath); var archive_creator = new GarCreate (this);
var items = CurrentDirectory.SelectedItems.Cast<EntryViewModel>(); if (!archive_creator.Run())
string arc_name = Path.GetFileName (CurrentPath); ResumeWatchDirectoryChanges();
}
catch (Exception X)
{
ResumeWatchDirectoryChanges();
PopupError (X.Message, guiStrings.TextCreateArchiveError);
}
}
}
internal class GarCreate
{
private MainWindow m_main;
private string m_arc_name;
private IList<Entry> m_file_list;
private ProgressDialog m_progress_dialog;
private ArchiveFormat m_format;
private ResourceOptions m_options;
private Exception m_pending_error;
delegate void AddFilesEnumerator (IList<Entry> list, string path, DirectoryInfo path_info);
public GarCreate (MainWindow parent)
{
m_main = parent;
}
public bool Run ()
{
Directory.SetCurrentDirectory (m_main.CurrentPath);
var items = m_main.CurrentDirectory.SelectedItems.Cast<EntryViewModel>();
m_arc_name = Path.GetFileName (m_main.CurrentPath);
if (!items.Skip (1).Any()) // items.Count() == 1 if (!items.Skip (1).Any()) // items.Count() == 1
{ {
var item = items.First(); var item = items.First();
if (item.IsDirectory) if (item.IsDirectory)
arc_name = Path.GetFileNameWithoutExtension (item.Name); m_arc_name = Path.GetFileNameWithoutExtension (item.Name);
} }
var dialog = new CreateArchiveDialog (arc_name); var dialog = new CreateArchiveDialog (m_arc_name);
dialog.Owner = this; dialog.Owner = m_main;
if (!dialog.ShowDialog().Value) if (!dialog.ShowDialog().Value)
return; {
return false;
}
if (string.IsNullOrEmpty (dialog.ArchiveName.Text)) if (string.IsNullOrEmpty (dialog.ArchiveName.Text))
{ {
SetStatusText ("Archive name is empty"); m_main.SetStatusText ("Archive name is empty");
return; return false;
} }
var format = dialog.ArchiveFormat.SelectedItem as ArchiveFormat; m_format = dialog.ArchiveFormat.SelectedItem as ArchiveFormat;
if (null == format) if (null == m_format)
{ {
SetStatusText ("Format is not selected"); m_main.SetStatusText ("Format is not selected");
return; return false;
} }
m_options = dialog.ArchiveOptions;
IList<Entry> file_list; if (m_format.IsHierarchic)
if (format.IsHierarchic) m_file_list = BuildFileList (items, AddFilesRecursive);
file_list = BuildFileList (items, AddFilesRecursive);
else else
file_list = BuildFileList (items, AddFilesFromDir); m_file_list = BuildFileList (items, AddFilesFromDir);
arc_name = Path.GetFullPath (dialog.ArchiveName.Text); m_arc_name = Path.GetFullPath (dialog.ArchiveName.Text);
var createProgressDialog = new ProgressDialog () m_progress_dialog = new ProgressDialog ()
{ {
WindowTitle = guiStrings.TextTitle, WindowTitle = guiStrings.TextTitle,
Text = string.Format (guiStrings.MsgCreatingArchive, Path.GetFileName (arc_name)), Text = string.Format (guiStrings.MsgCreatingArchive, Path.GetFileName (m_arc_name)),
Description = "", Description = "",
MinimizeBox = true, MinimizeBox = true,
}; };
createProgressDialog.DoWork += (s, e) => m_progress_dialog.DoWork += CreateWorker;
m_progress_dialog.RunWorkerCompleted += OnCreateComplete;
m_progress_dialog.ShowDialog (m_main);
return true;
}
private int m_total = 1;
ArchiveOperation CreateEntryCallback (int i, Entry entry, string msg)
{ {
try if (m_progress_dialog.CancellationPending)
{
using (var tmp_file = new GARbro.Shell.TemporaryFile (Path.GetDirectoryName (arc_name),
Path.GetRandomFileName ()))
{
int total = file_list.Count() + 1;
using (var file = File.Create (tmp_file.Name))
{
format.Create (file, file_list, dialog.ArchiveOptions, (i, entry, msg) =>
{
if (createProgressDialog.CancellationPending)
throw new OperationCanceledException(); throw new OperationCanceledException();
int progress = i*100/total; int progress = i*100/m_total;
if (progress > 100)
progress = 100;
string notice = msg; string notice = msg;
if (null != entry) if (null != entry)
{ {
@@ -107,38 +141,53 @@ namespace GARbro.GUI
else else
notice = entry.Name; notice = entry.Name;
} }
createProgressDialog.ReportProgress (progress, null, notice); m_progress_dialog.ReportProgress (progress, null, notice);
return ArchiveOperation.Continue; return ArchiveOperation.Continue;
});
} }
GARbro.Shell.File.Rename (tmp_file.Name, arc_name);
} void CreateWorker (object sender, DoWorkEventArgs e)
}
catch (OperationCanceledException X)
{ {
m_watcher.EnableRaisingEvents = true; m_pending_error = null;
SetStatusText (X.Message); try
{
using (var tmp_file = new GARbro.Shell.TemporaryFile (Path.GetDirectoryName (m_arc_name),
Path.GetRandomFileName ()))
{
int m_total = m_file_list.Count() + 1;
using (var file = File.Create (tmp_file.Name))
{
m_format.Create (file, m_file_list, m_options, CreateEntryCallback);
}
if (!GARbro.Shell.File.Rename (tmp_file.Name, m_arc_name))
{
throw new Win32Exception (GARbro.Shell.File.GetLastError());
}
}
} }
catch (Exception X) catch (Exception X)
{ {
m_watcher.EnableRaisingEvents = true; m_pending_error = X;
PopupError (X.Message, guiStrings.TextCreateArchiveError);
}
};
createProgressDialog.RunWorkerCompleted += (s, e) => {
createProgressDialog.Dispose();
Dispatcher.Invoke (() => SetCurrentPosition (new DirectoryPosition (arc_name)));
};
createProgressDialog.ShowDialog (this);
}
catch (Exception X)
{
m_watcher.EnableRaisingEvents = true;
PopupError (X.Message, guiStrings.TextCreateArchiveError);
} }
} }
delegate void AddFilesEnumerator (IList<Entry> list, string path, DirectoryInfo path_info); void OnCreateComplete (object sender, RunWorkerCompletedEventArgs e)
{
m_progress_dialog.Dispose();
if (null == m_pending_error)
{
m_main.Dispatcher.Invoke (() => {
m_main.SaveCurrentPosition();
m_main.SetCurrentPosition (new DirectoryPosition (m_arc_name));
});
}
else
{
if (m_pending_error is OperationCanceledException)
m_main.SetStatusText (m_pending_error.Message);
else
m_main.PopupError (m_pending_error.Message, guiStrings.TextCreateArchiveError);
}
}
IList<Entry> BuildFileList (IEnumerable<EntryViewModel> files, AddFilesEnumerator add_files) IList<Entry> BuildFileList (IEnumerable<EntryViewModel> files, AddFilesEnumerator add_files)
{ {