diff --git a/MainWindow.xaml b/MainWindow.xaml
index 863c2b71..69ab5a6b 100644
--- a/MainWindow.xaml
+++ b/MainWindow.xaml
@@ -27,6 +27,8 @@
+
+
@@ -151,16 +153,16 @@
diff --git a/MainWindow.xaml.cs b/MainWindow.xaml.cs
index 20aa0669..d1723e63 100644
--- a/MainWindow.xaml.cs
+++ b/MainWindow.xaml.cs
@@ -25,6 +25,7 @@ using System;
using System.IO;
using System.Collections.Generic;
using System.ComponentModel;
+using System.Globalization;
using System.Linq;
using System.Text;
using System.Diagnostics;
@@ -108,7 +109,7 @@ namespace GARbro.GUI
{
if (null != m_lvSortByColumn)
{
- Settings.Default.lvSortColumn = m_lvSortByColumn.Tag.ToString();
+ Settings.Default.lvSortColumn = SortMode;
Settings.Default.lvSortDirection = m_lvSortDirection;
}
else
@@ -165,7 +166,7 @@ namespace GARbro.GUI
return;
if (null == node)
{
- while (MaxRecentFiles < m_recent_files.Count)
+ while (MaxRecentFiles <= m_recent_files.Count)
m_recent_files.RemoveLast();
m_recent_files.AddFirst (file);
}
@@ -200,10 +201,7 @@ namespace GARbro.GUI
if (value.IsArchive)
PushRecentFile (value.Path);
- if (m_lvSortByColumn != null)
- lv_Sort (m_lvSortByColumn.Tag.ToString(), m_lvSortDirection);
- else
- lv_Sort (null, m_lvSortDirection);
+ lv_Sort (SortMode, m_lvSortDirection);
if (!value.IsArchive && !string.IsNullOrEmpty (value.Path))
{
Directory.SetCurrentDirectory (value.Path);
@@ -395,16 +393,14 @@ namespace GARbro.GUI
GridViewColumnHeader m_lvSortByColumn = null;
ListSortDirection m_lvSortDirection = ListSortDirection.Ascending;
- public bool IsSortByName {
- get { return m_lvSortByColumn != null && "Name".Equals (m_lvSortByColumn.Tag); }
+ public string SortMode
+ {
+ get { return GetValue (SortModeProperty) as string; }
+ private set { SetValue (SortModeProperty, value); }
}
- public bool IsSortByType {
- get { return m_lvSortByColumn != null && "Type".Equals (m_lvSortByColumn.Tag); }
- }
- public bool IsSortBySize {
- get { return m_lvSortByColumn != null && "Size".Equals (m_lvSortByColumn.Tag); }
- }
- public bool IsUnsorted { get { return m_lvSortByColumn == null; } }
+
+ public static readonly DependencyProperty SortModeProperty =
+ DependencyProperty.RegisterAttached ("SortMode", typeof(string), typeof(MainWindow), new UIPropertyMetadata());
void lv_SetSortMode (string sortBy, ListSortDirection direction)
{
@@ -427,6 +423,7 @@ namespace GARbro.GUI
column.HeaderTemplate = Resources["SortArrowNone"] as DataTemplate;
}
}
+ SortMode = sortBy;
}
private void lv_Sort (string sortBy, ListSortDirection direction)
@@ -457,6 +454,7 @@ namespace GARbro.GUI
string sortBy = headerClicked.Tag.ToString();
lv_Sort (sortBy, direction);
+ SortMode = sortBy;
// Remove arrow from previously sorted header
if (m_lvSortByColumn != null && m_lvSortByColumn != headerClicked)
@@ -488,20 +486,31 @@ namespace GARbro.GUI
}
///
- /// Event handler for keys pressed in the right pane
+ /// Event handler for keys pressed in the directory view pane
///
private void lv_TextInput (object sender, TextCompositionEventArgs e)
{
- LookupItem (e.Text);
+ LookupItem (e.Text, e.Timestamp);
e.Handled = true;
}
+ class InputData
+ {
+ public int LastTime = 0;
+ public StringBuilder Phrase = new StringBuilder();
+ public bool Mismatch = false;
+ }
+
+ const int TextLookupTimeout = 1000; // milliseconds
+
+ InputData m_current_input = new InputData();
+
///
- /// Lookup item in listview pane by first letter.
+ /// Lookup item in listview pane by first letters of name.
///
- private void LookupItem (string key)
+ private void LookupItem (string key, int timestamp)
{
if (string.IsNullOrEmpty (key))
return;
@@ -509,20 +518,39 @@ namespace GARbro.GUI
if (source == null)
return;
- var current = CurrentDirectory.SelectedItem as EntryViewModel;
- int index = 0;
- if (current != null && current.Name.StartsWith (key, StringIgnoreCase))
- index = CurrentDirectory.SelectedIndex+1;
-
- for (int i = index, count = source.Count; i < count; ++i)
+ if (timestamp - m_current_input.LastTime > TextLookupTimeout)
{
- var entry = source.GetItemAt (i) as EntryViewModel;
- if (entry != null && entry.Name.StartsWith (key, StringIgnoreCase))
+ m_current_input.Phrase.Clear();
+ m_current_input.Mismatch = false;
+ }
+ m_current_input.LastTime = timestamp;
+ if (m_current_input.Mismatch)
+ return;
+
+ if (1 == m_current_input.Phrase.Length && m_current_input.Phrase[0] == key[0])
+ {
+ // same key repeats, lookup by first letter only
+ int current = CurrentDirectory.SelectedIndex;
+ if (current != -1 && current+1 < source.Count)
{
- lv_SelectItem (entry);
- break;
+ var next_item = source.GetItemAt (current+1) as EntryViewModel;
+ if (next_item != null && next_item.Name.StartsWith (key, StringIgnoreCase))
+ {
+ lv_SelectItem (next_item);
+ return;
+ }
}
}
+ else
+ {
+ m_current_input.Phrase.Append (key);
+ }
+ string input = m_current_input.Phrase.ToString();
+ var matched = source.Cast().Where (e => e.Name.StartsWith (input, StringIgnoreCase)).FirstOrDefault();
+ if (null != matched)
+ lv_SelectItem (matched);
+ else
+ m_current_input.Mismatch = true;
}
private void acb_OnKeyDown (object sender, KeyEventArgs e)
@@ -1087,6 +1115,23 @@ namespace GARbro.GUI
}
}
+ public class SortModeToBooleanConverter : IValueConverter
+ {
+ public object Convert (object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ string actual_mode = value as string;
+ string check_mode = parameter as string;
+ if (string.IsNullOrEmpty (check_mode))
+ return string.IsNullOrEmpty (actual_mode);
+ return check_mode.Equals (actual_mode);
+ }
+
+ public object ConvertBack (object value, Type targetType, object parameter, CultureInfo culture)
+ {
+ throw new NotImplementedException();
+ }
+ }
+
public class BooleanToCollapsedVisibilityConverter : IValueConverter
{
#region IValueConverter Members