diff --git a/AutoComplete.cs b/AutoComplete.cs index f6ec0af5..72c713d5 100644 --- a/AutoComplete.cs +++ b/AutoComplete.cs @@ -72,17 +72,20 @@ namespace GARbro.GUI { try { - var candidates = new List(); - string dirname = Path.GetDirectoryName (this.Text); - if (!string.IsNullOrEmpty (dirname) && Directory.Exists (dirname)) + if (!GameRes.VFS.IsVirtual) { - foreach (var dir in Directory.GetDirectories (dirname)) + var candidates = new List(); + string dirname = Path.GetDirectoryName (this.Text); + if (!string.IsNullOrEmpty (dirname) && Directory.Exists (dirname)) { - if (dir.StartsWith (dirname, StringComparison.CurrentCultureIgnoreCase)) - candidates.Add (dir); + foreach (var dir in Directory.GetDirectories (dirname)) + { + if (dir.StartsWith (dirname, StringComparison.CurrentCultureIgnoreCase)) + candidates.Add (dir); + } } + this.ItemsSource = candidates; } - this.ItemsSource = candidates; } catch { diff --git a/GARbro.sln b/GARbro.sln index ea6b4b33..35f7bc91 100644 --- a/GARbro.sln +++ b/GARbro.sln @@ -29,21 +29,21 @@ Global Release|Any CPU = Release|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution - {B966F292-431A-4D8A-A1D3-1EB45048A1D2}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {B966F292-431A-4D8A-A1D3-1EB45048A1D2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {B966F292-431A-4D8A-A1D3-1EB45048A1D2}.Release|Any CPU.ActiveCfg = Release|Any CPU - {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Debug|Any CPU.Build.0 = Release|Any CPU + {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Debug|Any CPU.Build.0 = Debug|Any CPU {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Release|Any CPU.ActiveCfg = Release|Any CPU {A8865685-27CC-427B-AC38-E48D2AD05DF4}.Release|Any CPU.Build.0 = Release|Any CPU - {453C087F-E416-4AE9-8C03-D8760DA0574B}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {453C087F-E416-4AE9-8C03-D8760DA0574B}.Debug|Any CPU.Build.0 = Release|Any CPU + {453C087F-E416-4AE9-8C03-D8760DA0574B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {453C087F-E416-4AE9-8C03-D8760DA0574B}.Debug|Any CPU.Build.0 = Debug|Any CPU {453C087F-E416-4AE9-8C03-D8760DA0574B}.Release|Any CPU.ActiveCfg = Release|Any CPU {453C087F-E416-4AE9-8C03-D8760DA0574B}.Release|Any CPU.Build.0 = Release|Any CPU - {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Debug|Any CPU.ActiveCfg = Release|Any CPU - {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Debug|Any CPU.Build.0 = Release|Any CPU + {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Debug|Any CPU.Build.0 = Debug|Any CPU {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Release|Any CPU.ActiveCfg = Release|Any CPU {2935BE57-C4E0-43E7-86DE-C1848C820B19}.Release|Any CPU.Build.0 = Release|Any CPU - {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Debug|Any CPU.ActiveCfg = Release|Any CPU + {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {757EB8B1-F62C-4690-AC3D-DAE4A5576B3E}.Release|Any CPU.ActiveCfg = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution diff --git a/GameRes/FileSystem.cs b/GameRes/FileSystem.cs index 32d2b85e..c0aab7a4 100644 --- a/GameRes/FileSystem.cs +++ b/GameRes/FileSystem.cs @@ -77,7 +77,7 @@ namespace GameRes } } - public class PhysicalFileSystem : IFileSystem + public sealed class PhysicalFileSystem : IFileSystem { public string CurrentDirectory { @@ -396,6 +396,8 @@ namespace GameRes if (entry.Name == LastVisitedPath && null != LastVisitedArc) { Push (LastVisitedPath, LastVisitedArc); + if (LastVisitedArc is FlatArchiveFileSystem) + CurrentArchive = (LastVisitedArc as FlatArchiveFileSystem).Source; return; } Flush(); diff --git a/GameRes/Properties/AssemblyInfo.cs b/GameRes/Properties/AssemblyInfo.cs index 9ed6d3e2..3d76340c 100644 --- a/GameRes/Properties/AssemblyInfo.cs +++ b/GameRes/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("1.1.9.91")] -[assembly: AssemblyFileVersion ("1.1.9.91")] +[assembly: AssemblyVersion ("1.1.9.92")] +[assembly: AssemblyFileVersion ("1.1.9.92")] diff --git a/GarExtract.cs b/GarExtract.cs index 8d619c65..55fb9be1 100644 --- a/GarExtract.cs +++ b/GarExtract.cs @@ -75,11 +75,11 @@ namespace GARbro.GUI extractor.ExtractAll (destination); } } - else if (vm.Path.Skip (1).Any()) + else if (vm.Path.Count > 1) { if (string.IsNullOrEmpty (destination)) destination = Path.GetDirectoryName (vm.Path.First()); - var archive_name = vm.Path.Reverse().Skip (1).First(); + var archive_name = vm.Path[vm.Path.Count-2]; extractor = new GarExtract (this, archive_name, VFS.CurrentArchive); if (null == entry || (entry.Name == ".." && string.IsNullOrEmpty (vm.Path.Last()))) // root entry extractor.ExtractAll (destination); diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs index 213bc461..986e04ca 100644 --- a/MainWindow.xaml.cs +++ b/MainWindow.xaml.cs @@ -223,9 +223,14 @@ namespace GARbro.GUI StopWatchDirectoryChanges(); var cvs = this.Resources["ListViewSource"] as CollectionViewSource; cvs.Source = value; - pathLine.Text = value.Path.Last(); - if (value.IsArchive && !value.Path.Skip (2).Any()) + // update path textbox + var path_component = value.Path.Last(); + if (string.IsNullOrEmpty (path_component) && value.Path.Count > 1) + path_component = value.Path[value.Path.Count-2]; + pathLine.Text = path_component; + + if (value.IsArchive && value.Path.Count <= 2) PushRecentFile (value.Path.First()); lv_Sort (SortMode, m_lvSortDirection); @@ -237,14 +242,26 @@ namespace GARbro.GUI } } + /// + /// Save current position and update view model. + /// + void PushViewModel (DirectoryViewModel vm) + { + SaveCurrentPosition(); + ViewModel = vm; + } + DirectoryViewModel GetNewViewModel (string path) { - if (!VFS.IsVirtual) - path = Path.GetFullPath (path); - var entry = VFS.FindFile (path); - if (!(entry is SubDirEntry)) - SetBusyState(); - VFS.ChDir (entry); + if (!string.IsNullOrEmpty (path)) + { + if (!VFS.IsVirtual) + path = Path.GetFullPath (path); + var entry = VFS.FindFile (path); + if (!(entry is SubDirEntry)) + SetBusyState(); + VFS.ChDir (entry); + } return new DirectoryViewModel (VFS.FullPath, VFS.GetFiles(), VFS.IsVirtual); } @@ -618,7 +635,7 @@ namespace GARbro.GUI return; try { - ViewModel = GetNewViewModel (path); + PushViewModel (GetNewViewModel (path)); lv_Focus(); } catch (Exception X) @@ -716,9 +733,7 @@ namespace GARbro.GUI return; try { - var vm = GetNewViewModel (filename); - SaveCurrentPosition(); - ViewModel = vm; + PushViewModel (GetNewViewModel (filename)); if (null != VFS.CurrentArchive) SetStatusText (VFS.CurrentArchive.Description); lv_SelectItem (0); @@ -754,33 +769,32 @@ namespace GARbro.GUI entry = CurrentDirectory.SelectedItem as EntryViewModel; if (null == entry) return; - - var vm = ViewModel; - if (null == vm) - return; if ("audio" == entry.Type) { PlayFile (entry.Source); return; } - OpenDirectoryEntry (vm, entry); + OpenDirectoryEntry (ViewModel, entry); } private void OpenDirectoryEntry (DirectoryViewModel vm, EntryViewModel entry) { - string old_dir = vm.Path.Last(); + string old_dir = null == vm ? "" : vm.Path.Last(); string new_dir = entry.Source.Name; - if (!vm.IsArchive && ".." == new_dir) - new_dir = Path.Combine (old_dir, entry.Name); + if (".." == new_dir) + { + if (null != vm && !vm.IsArchive) + new_dir = Path.Combine (old_dir, entry.Name); + if (vm.Path.Count > 1 && string.IsNullOrEmpty (old_dir)) + old_dir = vm.Path[vm.Path.Count-2]; + } Trace.WriteLine (new_dir, "OpenDirectoryEntry"); int old_fs_count = VFS.Count; vm = TryCreateViewModel (new_dir); if (null == vm) - { return; - } - SaveCurrentPosition(); - ViewModel = vm; + + PushViewModel (vm); if (VFS.Count > old_fs_count && null != VFS.CurrentArchive) SetStatusText (string.Format ("{0}: {1}", VFS.CurrentArchive.Description, Localization.Format ("MsgFiles", VFS.CurrentArchive.Dir.Count()))); @@ -793,35 +807,6 @@ namespace GARbro.GUI lv_SelectItem (0); } - /* - private void OpenArchiveEntry (ArchiveViewModel vm, EntryViewModel entry) - { - if (entry.IsDirectory) - { - SaveCurrentPosition(); - var old_dir = vm.SubDir; - try - { - vm.ChDir (entry.Name); - if (".." == entry.Name) - lv_SelectItem (Path.GetFileName (old_dir)); - else - lv_SelectItem (0); - SetStatusText (""); - } - catch (Exception X) - { - SetStatusText (X.Message); - } - } - } - */ - - Stream OpenEntry (Entry entry) - { - return VFS.OpenStream (entry); - } - WaveOutEvent m_audio_device; WaveOutEvent AudioDevice { @@ -852,7 +837,7 @@ namespace GARbro.GUI try { SetBusyState(); - using (var input = OpenEntry (entry)) + using (var input = VFS.OpenStream (entry)) { FormatCatalog.Instance.LastError = null; sound = AudioFormat.Read (input); diff --git a/Properties/AssemblyInfo.cs b/Properties/AssemblyInfo.cs index cc51191d..42091249 100644 --- a/Properties/AssemblyInfo.cs +++ b/Properties/AssemblyInfo.cs @@ -51,5 +51,5 @@ using System.Windows; // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion ("1.1.8.660")] -[assembly: AssemblyFileVersion ("1.1.8.660")] +[assembly: AssemblyVersion ("1.1.8.661")] +[assembly: AssemblyFileVersion ("1.1.8.661")] diff --git a/ViewModel.cs b/ViewModel.cs index 5e75a0ba..ec6b6dee 100644 --- a/ViewModel.cs +++ b/ViewModel.cs @@ -41,13 +41,13 @@ namespace GARbro.GUI { public class DirectoryViewModel : ObservableCollection { - public IEnumerable Path { get; private set; } - public IEnumerable Source { get; private set; } - public bool IsArchive { get; private set; } + public IReadOnlyList Path { get; private set; } + public IEnumerable Source { get; private set; } + public bool IsArchive { get; private set; } public DirectoryViewModel (IEnumerable path, IEnumerable filelist, bool is_archive) { - Path = path; + Path = path.ToList(); Source = filelist; IsArchive = is_archive; ImportFromSource(); @@ -82,141 +82,6 @@ namespace GARbro.GUI } } - /* - public class ArchiveViewModel : DirectoryViewModel - { - public override bool IsArchive { get { return true; } } - public string SubDir { get; protected set; } - - public ArchiveViewModel (string path, ArcFile arc) - : base (path, arc.Dir) - { - } - - protected override void ImportFromSource () - { - UpdateModel (""); - } - - private string m_delimiter = "/"; - private static readonly char[] m_path_delimiters = { '/', '\\' }; - - public void ChDir (string subdir) - { - string new_path; - if (".." == subdir) - { - if (0 == SubDir.Length) - return; - var path = SubDir.Split (m_path_delimiters); - if (path.Length > 1) - new_path = string.Join (m_delimiter, path, 0, path.Length-1); - else - new_path = ""; - } - else - { - var entry = this.FirstOrDefault (e => e.Name.Equals (subdir, StringComparison.OrdinalIgnoreCase)); - if (null == entry) - throw new DirectoryNotFoundException (string.Format ("{1}: {0}", guiStrings.MsgDirectoryNotFound, subdir)); - if (SubDir.Length > 0) - new_path = SubDir + m_delimiter + entry.Name; - else - new_path = entry.Name; - } - UpdateModel (new_path); - } - - static readonly Regex path_re = new Regex (@"\G[/\\]?([^/\\]+)([/\\])"); - - private void UpdateModel (string root_path) - { - IEnumerable dir = Source; - if (!string.IsNullOrEmpty (root_path)) - { - dir = from entry in dir - where entry.Name.StartsWith (root_path+m_delimiter) - select entry; - if (!dir.Any()) - { - throw new DirectoryNotFoundException (string.Format ("{1}: {0}", guiStrings.MsgDirectoryNotFound, root_path)); - } - } - m_suppress_notification = true; - try - { - this.Clear(); - SubDir = root_path; - Add (new EntryViewModel (new SubDirEntry (".."), -2)); - var subdirs = new HashSet(); - foreach (var entry in dir) - { - var match = path_re.Match (entry.Name, root_path.Length); - if (match.Success) - { - string name = match.Groups[1].Value; - if (subdirs.Add (name)) - { - m_delimiter = match.Groups[2].Value; - Add (new EntryViewModel (new SubDirEntry (name), -1)); - } - } - else - { - Add (new EntryViewModel (entry, 0)); - } - } - } - finally - { - m_suppress_notification = false; - OnCollectionChanged (new NotifyCollectionChangedEventArgs(NotifyCollectionChangedAction.Reset)); - } - } - - public override void SetPosition (DirectoryPosition pos) - { - UpdateModel (pos.ArchivePath); - } - - public override IEnumerable GetFiles (IEnumerable entries) - { - var list = new List(); - foreach (var entry in entries) - { - if (!entry.IsDirectory) // add ordinary file - list.Add (entry.Source); - else if (".." == entry.Name) // skip reference to parent directory - continue; - else // add all files contained within directory, recursive - { - string path = GetPath (entry.Name); - list.AddRange (from file in Source - where file.Name.StartsWith (path) - select file); - } - } - return list; - } - - string GetPath (string dir) - { - if (SubDir.Length > 0) - return SubDir + m_delimiter + dir + m_delimiter; - else - return dir + m_delimiter; - } - - private bool m_suppress_notification = false; - - protected override void OnCollectionChanged (NotifyCollectionChangedEventArgs e) - { - if (!m_suppress_notification) - base.OnCollectionChanged(e); - } - } - */ - public class EntryViewModel : INotifyPropertyChanged { public EntryViewModel (Entry entry, int priority)