Do

Merge lp:~whatah/do/keybindings into lp:do

Proposed by whatah
Status: Merged
Approved by: Alex Launi
Approved revision: 1117
Merged at revision: not available
Proposed branch: lp:~whatah/do/keybindings
Merge into: lp:do
Diff against target: None lines
To merge this branch: bzr merge lp:~whatah/do/keybindings
Reviewer Review Type Date Requested Status
Alex Launi (community) Needs Fixing
Review via email: mp+4767@code.launchpad.net
To post a comment you must log in.
Revision history for this message
whatah (whatah) wrote :

Keybindings support - I'd like some feedback on the code

Revision history for this message
Alex Launi (alexlauni) wrote :

Couple of minor formatting things, you have a few cases of ! bool, remove the space and do !bool.
Can you rearrange some of the lines in CoreKeybindings so they're sorted by length? It just makes the code a little bit easier to read.
In a bunch of places you do
if (bool) {
  //block
  return true;
}
return false;

you should do
if (!bool)
  return false;

//block
return true;

^ this is a mono guidelines thing

It looks like youre using ',' as a delimeter for something in saving shortcuts, does this mean that ',' can not be used in a shortcut?

In Controller.cs, you have some odd newline formatting. We don't adhere to 80 cols rule, we say around 120, but that's not a hard rule; whatever is most readable is preferred.

Please clear out all of the commented code

review: Needs Fixing
lp:~whatah/do/keybindings updated
1113. By whatah

fixed some formatting issues (! bool -> !bool) and rearranged blocks so that return true is at the end of a function. Also sorted some lines by length

Revision history for this message
Alex Launi (alexlauni) wrote :

There is still whitespace issues in a bunch of the files, this needs cleared up, but can be done easily in vim. If you're using monodevelop, this is why. MD does weird stuff with whitespace.

line 104 in KeyBindingTreeView.cs, you should turn that anonymous function into a real function. It'll make the code cleaner, it's confusing to see a return statement in the middle of another function.

In the same file, can you localize the column headers?

You mix { placement styles, in some places you do
foreach (...)
{
in others you do
foreach (...) {

use the latter. The same for if statements.

Does the keybinding class need an initialize method? Can the stuff in the init method actually go in the constructor?

lp:~whatah/do/keybindings updated
1114. By whatah

Fixed inconsistent use of braces after foreach and if.
Added localization support for column strings in KeybindingTreeView
Removed call of Initialize method in Do.cs and placed in Keybinding ctor.

1115. By whatah

Changed anonymous function to a declared function

1116. By whatah

Fixed whitespacing issues (all 8 spaces are converted to hard tabs)

1117. By whatah

Fixed namespace/class { style issues and moved Shortcut into Do.Core

Revision history for this message
Jason Smith (jassmith) wrote :

> Keybindings support - I'd like some feedback on the code

Use tabs instead of spaces as per the new regulation that we just made up but we all followed to this point by pure fluke.

Love, DBO

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'Do/Makefile.am'
2--- Do/Makefile.am 2009-02-19 03:09:17 +0000
3+++ Do/Makefile.am 2009-03-22 05:41:46 +0000
4@@ -16,6 +16,7 @@
5 gtk-gui/generated.cs \
6 src/AssemblyInfo.cs \
7 src/CorePreferences.cs \
8+ src/CoreKeybindings.cs \
9 src/Do.Core/Do.Core.Addins/AddinClassifier.cs \
10 src/Do.Core/Do.Core.Addins/CommunityAddinClassifier.cs \
11 src/Do.Core/Do.Core.Addins/GreedyAddinClassifier.cs \
12@@ -31,6 +32,8 @@
13 src/Do.Core/PluginManager.cs \
14 src/Do.Core/RelevanceProvider.cs \
15 src/Do.Core/SecondSearchController.cs \
16+ src/Do.Core/Shortcut.cs \
17+ src/Do.Core/ShortcutCallback.cs \
18 src/Do.Core/SimpleSearchContext.cs \
19 src/Do.Core/SimpleSearchController.cs \
20 src/Do.Core/ThirdSearchController.cs \
21
22=== added file 'Do/src/CoreKeybindings.cs'
23--- Do/src/CoreKeybindings.cs 1970-01-01 00:00:00 +0000
24+++ Do/src/CoreKeybindings.cs 2009-03-23 03:42:03 +0000
25@@ -0,0 +1,241 @@
26+
27+/* Keybindings.cs
28+ *
29+ * GNOME Do is the legal property of its developers. Please refer to the
30+ * COPYRIGHT file distributed with this
31+ * source distribution.
32+ *
33+ * This program is free software: you can redistribute it and/or modify
34+ * it under the terms of the GNU General Public License as published by
35+ * the Free Software Foundation, either version 3 of the License, or
36+ * (at your option) any later version.
37+ *
38+ * This program is distributed in the hope that it will be useful,
39+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
40+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
41+ * GNU General Public License for more details.
42+ *
43+ * You should have received a copy of the GNU General Public License
44+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
45+ */
46+
47+using System;
48+using System.Linq;
49+using System.Collections;
50+using System.Collections.Generic;
51+using Env = System.Environment;
52+
53+using Do.Platform;
54+
55+namespace Do
56+{
57+
58+ class CoreKeybindings {
59+ Dictionary<string, Shortcut> ShortcutMap ; // shortcut name -> shortcut
60+ Dictionary<string, string> KeycodeMap ; // keybinding -> shortcut name
61+ Dictionary<string, string> DefaultShortcutMap ; // default keybinding -> shortcut name
62+
63+ IPreferences Preferences { get; set; }
64+
65+ public ArrayList Shortcuts ;
66+ public Dictionary<string, List<KeyChangedCb>> PreferencesCbs;
67+ public delegate void KeyChangedCb (object sender, PreferencesChangedEventArgs e);
68+
69+ public CoreKeybindings ()
70+ {
71+
72+ Preferences = Services.Preferences.Get<CoreKeybindings> ();
73+ Preferences.PreferencesChanged += PreferencesChanged;
74+
75+ ShortcutMap = new Dictionary<string, Shortcut> (); // shortcut name -> shortcut
76+ KeycodeMap = new Dictionary<string, string> (); // keybinding -> shortcut name
77+ DefaultShortcutMap = new Dictionary<string, string> (); // default keybinding -> shortcut name
78+ Shortcuts = new ArrayList ();
79+ PreferencesCbs = new Dictionary<string, List<KeyChangedCb>> ();
80+ }
81+
82+ public void Initialize ()
83+ {
84+ // Read all values out of preferences and populate the KeybindingMap
85+ ReadShortcuts ();
86+ }
87+
88+ public bool RegisterShortcut (Shortcut sc, string defaultBinding)
89+ {
90+ if (!RegisterShortcut (sc))
91+ return false;
92+ if (!BindDefault (sc, defaultBinding))
93+ return false;
94+ return true;
95+ }
96+
97+ public bool RegisterShortcut (Shortcut sc)
98+ {
99+ // Add this shortcut to what?
100+ if (! Shortcuts.Contains (sc) && ! ShortcutMap.ContainsKey (sc.ShortcutName))
101+ {
102+ Shortcuts.Add (sc);
103+ ShortcutMap [sc.ShortcutName] = sc;
104+ PreferencesCbs [sc.ShortcutName] = new List<KeyChangedCb> ();
105+ SaveShortcuts ();
106+ return true;
107+ }
108+ return false;
109+ }
110+
111+ public Shortcut GetShortcutByKeycode (string keycode)
112+ {
113+ if (!KeycodeMap.ContainsKey (keycode)) {
114+ return null;
115+ }
116+ string scname = KeycodeMap [keycode];
117+
118+ if (!ShortcutMap.ContainsKey (scname)) {
119+ return null;
120+ }
121+
122+ return ShortcutMap [scname];
123+
124+ }
125+
126+ public string GetKeybinding (Shortcut sc)
127+ {
128+ return GetKeybinding (sc.ShortcutName);
129+ }
130+
131+ public string GetKeybinding (string sc)
132+ {
133+
134+ foreach (KeyValuePair<string, string> entry in KeycodeMap)
135+ {
136+ if (entry.Value == sc) {
137+ return entry.Key;
138+ }
139+ }
140+ return null;
141+ }
142+
143+ public string GetDefaultKeybinding (Shortcut sc)
144+ {
145+ return GetDefaultKeybinding (sc.ShortcutName);
146+ }
147+
148+ public string GetDefaultKeybinding (string sc)
149+ {
150+ foreach (KeyValuePair<string, string> entry in DefaultShortcutMap)
151+ {
152+ if (entry.Value == sc) {
153+ return entry.Key;
154+ }
155+ }
156+ return null;
157+ }
158+
159+
160+ public bool BindShortcut (Shortcut sc, string keycode)
161+ {
162+ // Add this function to our keybinding map
163+ return BindShortcut (sc.ShortcutName, keycode);
164+
165+ }
166+
167+ public bool BindShortcut (string sc, string keycode)
168+ {
169+ string oldcode = GetKeybinding (sc);
170+ if (oldcode != null)
171+ KeycodeMap.Remove (oldcode); // remove the old keybinding from the map
172+
173+ KeycodeMap [keycode] = sc;
174+ Preferences.Set (sc, keycode);
175+
176+ return true;
177+ }
178+
179+ // Add Default Keycode mapping - used for resetting to default or not overwriting read values
180+ public bool BindDefault (Shortcut sc, string keycode)
181+ {
182+ return BindDefault (sc.ShortcutName, keycode);
183+
184+ }
185+
186+ public bool BindDefault (string sc, string keycode)
187+ {
188+
189+ string assigned_keycode = GetKeybinding (sc);
190+ if (assigned_keycode == null)
191+ {
192+ // Put this shortcut in the mapping
193+ BindShortcut (sc, keycode);
194+ }
195+
196+ DefaultShortcutMap [keycode] = sc;
197+ return true;
198+
199+ }
200+
201+ public bool UnregisterShortcut (Shortcut sc)
202+ {
203+ if (Shortcuts.Contains (sc))
204+ {
205+ Shortcuts.Remove (sc);
206+ ShortcutMap.Remove (sc.ShortcutName);
207+ SaveShortcuts ();
208+ return true;
209+ }
210+ return false;
211+ }
212+
213+ public bool RegisterNotification (Shortcut sc, KeyChangedCb cb)
214+ {
215+ return RegisterNotification (sc.ShortcutName, cb);
216+ }
217+
218+ public bool RegisterNotification (string scname, KeyChangedCb cb)
219+ {
220+ PreferencesCbs [scname].Add (cb);
221+ return true;
222+ }
223+
224+ void SaveShortcuts ()
225+ {
226+ string scstring = "";
227+ foreach (Shortcut sc in Shortcuts)
228+ {
229+ scstring += sc.ShortcutName.Trim () + ",";
230+ }
231+ Preferences.Set ("RegisteredShortcuts", scstring);
232+ }
233+
234+ void ReadShortcuts ()
235+ {
236+ string scstring = Preferences.Get ("RegisteredShortcuts", "").Trim ();
237+ if (scstring == "")
238+ return;
239+
240+ foreach (string sc in scstring.Split (',')) {
241+ if (sc.Trim () == "")
242+ continue;
243+
244+ string keycode = Preferences.Get (sc, "");
245+ if (keycode != "")
246+ BindShortcut (sc, keycode);
247+ }
248+ }
249+
250+ void PreferencesChanged (object sender, PreferencesChangedEventArgs e)
251+ {
252+
253+ // if (GetKeybinding (e.Key) != null && GetKeybinding (e.Key).ToString ().Trim () == e.OldValue.ToString ().Trim ())
254+ // return;
255+ //
256+ if (PreferencesCbs.ContainsKey (e.Key))
257+ {
258+ foreach (KeyChangedCb cb in PreferencesCbs [e.Key]) {
259+ cb (this, e);
260+ }
261+ }
262+ }
263+
264+ }
265+
266+}
267
268=== modified file 'Do/src/CorePreferences.cs'
269--- Do/src/CorePreferences.cs 2009-01-09 01:17:59 +0000
270+++ Do/src/CorePreferences.cs 2009-03-23 03:05:45 +0000
271@@ -20,22 +20,21 @@
272
273 using System;
274 using System.Linq;
275+using System.Collections;
276+using System.Collections.Generic;
277 using Env = System.Environment;
278
279 using Do.Platform;
280
281 namespace Do
282 {
283-
284 class CorePreferences {
285
286 #region Key constants and default values
287 const string ThemeKey = "Theme";
288 const string QuietStartKey = "QuietStart";
289 const string StartAtLoginKey = "StartAtLogin";
290- const string SummonKeybindingKey = "SummonKeybinding";
291 const string AlwaysShowResultsKey = "AlwaysShowResults";
292- const string TextModeKeybindingKey = "TextModeKeybinding";
293
294 const string ThemeDefaultValue = "Classic Interface";
295 const bool QuietStartDefaultValue = false;
296@@ -46,10 +45,11 @@
297
298 const string DebugOption = "--debug";
299 const string LogToFileOption = "--log-to-file";
300+
301+
302 #endregion
303
304 public event EventHandler<PreferencesChangedEventArgs> ThemeChanged;
305- public event EventHandler<PreferencesChangedEventArgs> SummonKeybindingChanged;
306
307 IPreferences Preferences { get; set; }
308
309@@ -71,16 +71,6 @@
310 get { return CorePreferences.PeekDebug; }
311 }
312
313- public string SummonKeybinding {
314- get { return Preferences.Get (SummonKeybindingKey, SummonKeybindingDefaultValue); }
315- set { Preferences.Set (SummonKeybindingKey, value); }
316- }
317-
318- public string TextModeKeybinding {
319- get { return Preferences.Get (TextModeKeybindingKey, TextModeKeybindingDefaultValue); }
320- set { Preferences.Set (TextModeKeybindingKey, value); }
321- }
322-
323 public string Theme {
324 get { return Preferences.Get (ThemeKey, ThemeDefaultValue); }
325 set { Preferences.Set (ThemeKey, value); }
326@@ -106,6 +96,7 @@
327 return Env.GetCommandLineArgs ().Contains (option);
328 }
329
330+
331 void PreferencesChanged (object sender, PreferencesChangedEventArgs e)
332 {
333 switch (e.Key) {
334@@ -113,10 +104,6 @@
335 if (ThemeChanged != null)
336 ThemeChanged (this, e);
337 break;
338- case SummonKeybindingKey:
339- if (SummonKeybindingChanged != null)
340- SummonKeybindingChanged (this, e);
341- break;
342 }
343 }
344 }
345
346=== modified file 'Do/src/Do.Core/Controller.cs'
347--- Do/src/Do.Core/Controller.cs 2009-01-27 05:19:42 +0000
348+++ Do/src/Do.Core/Controller.cs 2009-03-23 03:42:03 +0000
349@@ -86,6 +86,7 @@
350 im_context.UsePreedit = false;
351 im_context.Commit += OnIMCommit;
352 im_context.FocusIn ();
353+
354 }
355
356 void OnIMCommit (object sender, Gtk.CommitArgs e)
357@@ -98,6 +99,99 @@
358 {
359 SetTheme (Do.Preferences.Theme);
360 Do.Preferences.ThemeChanged += OnThemeChanged;
361+
362+ // Register Shortcuts
363+ // TODO: Localize the text here.
364+ // Previous shortcuts
365+ Do.Keybindings.RegisterShortcut (
366+ new Shortcut ("SummonKey",
367+ Catalog.GetString ("Summon Gnome-Do"),
368+ OnSummonKeyPressEvent),
369+ "<Super>space");
370+ Do.Keybindings.RegisterShortcut (
371+ new Shortcut ("TextModeKey",
372+ Catalog.GetString ("Enter text mode"),
373+ OnTextModePressEvent),
374+ "period");
375+ // New shortcuts
376+ Do.Keybindings.RegisterShortcut (
377+ new Shortcut ("CopyKey",
378+ Catalog.GetString ("Copy Text"),
379+ OnCopyEvent),
380+ "<Control>c");
381+ Do.Keybindings.RegisterShortcut (
382+ new Shortcut ("PasteKey",
383+ Catalog.GetString ("Paste Text"),
384+ OnPasteEvent),
385+ "<Control>v");
386+ Do.Keybindings.RegisterShortcut (
387+ new Shortcut ("AlternateEscapeKey",
388+ Catalog.GetString ("Alternate Escape"),
389+ OnEscapeKeyPressEvent));
390+ Do.Keybindings.RegisterShortcut (
391+ new Shortcut ("AlternateActivateKey",
392+ Catalog.GetString ("Alternate Activate"),
393+ OnActivateKeyPressEvent));
394+ Do.Keybindings.RegisterShortcut (
395+ new Shortcut ("AlternateDeleteKey",
396+ Catalog.GetString ("Alternate Delete"),
397+ OnDeleteKeyPressEvent));
398+ Do.Keybindings.RegisterShortcut (
399+ new Shortcut ("ShiftTabKey",
400+ Catalog.GetString ("Previous Pane"),
401+ OnShiftTabKeyPressEvent),
402+ "ISO_Left_Tab");
403+ Do.Keybindings.RegisterShortcut (
404+ new Shortcut ("TabKey",
405+ Catalog.GetString ("Next Pane"),
406+ OnTabKeyPressEvent),
407+ "Tab");
408+ Do.Keybindings.RegisterShortcut (
409+ new Shortcut ("UpKey",
410+ Catalog.GetString ("Previous Result"),
411+ OnUpKeyPressEvent),
412+ "Up");
413+ Do.Keybindings.RegisterShortcut (
414+ new Shortcut ("DownKey",
415+ Catalog.GetString ("Next Result"),
416+ OnDownKeyPressEvent),
417+ "Down");
418+ Do.Keybindings.RegisterShortcut (
419+ new Shortcut ("HomeKey",
420+ Catalog.GetString ("First Result"),
421+ OnHomeKeyPressEvent),
422+ "Home");
423+ Do.Keybindings.RegisterShortcut (
424+ new Shortcut ("EndKey",
425+ Catalog.GetString ("Last Result"),
426+ OnEndKeyPressEvent),
427+ "End");
428+ Do.Keybindings.RegisterShortcut (
429+ new Shortcut ("PageUpKey",
430+ Catalog.GetString ("Previous 5 Results"),
431+ OnPageUpKeyPressEvent),
432+ "Page_Up");
433+ Do.Keybindings.RegisterShortcut (
434+ new Shortcut ("PageDownKey",
435+ Catalog.GetString ("Next 5 Results"),
436+ OnPageDownKeyPressEvent),
437+ "Page_Down");
438+ Do.Keybindings.RegisterShortcut (
439+ new Shortcut ("LeftKey",
440+ Catalog.GetString ("Step out of Item"),
441+ OnLeftKeyPressEvent),
442+ "Left");
443+ Do.Keybindings.RegisterShortcut (
444+ new Shortcut ("RightKey",
445+ Catalog.GetString ("Browse Into Item"),
446+ OnRightKeyPressEvent),
447+ "Right");
448+ Do.Keybindings.RegisterShortcut (
449+ new Shortcut ("CommaKey",
450+ Catalog.GetString ("Selection mode"),
451+ OnSelectionKeyPressEvent),
452+ "Comma");
453+
454 }
455
456 void OnSummoned ()
457@@ -319,8 +413,8 @@
458 {
459 return controllers [(int) pane].TextType == TextModeType.Explicit ||
460 controllers [(int) pane].TextType == TextModeType.ExplicitFinalized;
461- }
462-
463+ }
464+
465 #region KeyPress Handling
466
467 Key IfVertical (Key ifKey, Key elseKey)
468@@ -337,29 +431,8 @@
469 {
470 Key key = (Key) evnt.KeyValue;
471
472- // User set keybindings
473- if (KeyEventToString (evnt).Equals (Do.Preferences.SummonKeybinding)) {
474- OnSummonKeyPressEvent (evnt);
475- return;
476- }
477-
478- if (KeyEventToString (evnt).Equals (Do.Preferences.TextModeKeybinding)) {
479- OnTextModePressEvent (evnt);
480- return;
481- }
482-
483- // Check for paste
484- if ((evnt.State & ModifierType.ControlMask) != 0) {
485- if (evnt.Key == Key.v) {
486- OnPasteEvent ();
487- return;
488- }
489- if (evnt.Key == Key.c) {
490- OnCopyEvent ();
491- return;
492- }
493- }
494-
495+
496+ // Currently - only hardcoded are enter keys, escape and delete/backspace
497 if (key == Key.Escape) {
498 OnEscapeKeyPressEvent (evnt);
499 } else if (key == Key.Return ||
500@@ -369,27 +442,19 @@
501 } else if (key == Key.Delete ||
502 key == Key.BackSpace) {
503 OnDeleteKeyPressEvent (evnt);
504- } else if (key == Key.Tab ||
505- key == Key.ISO_Left_Tab) {
506- OnTabKeyPressEvent (evnt);
507- } else if (key == UpKey ||
508- key == DownKey ||
509- key == Key.Home ||
510- key == Key.End ||
511- key == Key.Page_Up ||
512- key == Key.Page_Down) {
513- OnUpDownKeyPressEvent (evnt);
514- } else if (key == RightKey ||
515- key == LeftKey) {
516- OnRightLeftKeyPressEvent (evnt);
517- } else if (key == Key.comma) {
518- OnSelectionKeyPressEvent (evnt);
519- } else {
520- OnInputKeyPressEvent (evnt);
521- }
522+ } else {
523+ // User set keybindings
524+ Shortcut sc = Do.Keybindings.GetShortcutByKeycode (KeyEventToString (evnt));
525+ if (sc != null)
526+ {
527+ sc.Callback (evnt);
528+ return;
529+ }
530+ OnInputKeyPressEvent (evnt);
531+ }
532 }
533
534- void OnPasteEvent ()
535+ void OnPasteEvent (EventKey evnt)
536 {
537 Gtk.Clipboard clip = Gtk.Clipboard.Get (Selection.Clipboard);
538 if (!clip.WaitIsTextAvailable ()) {
539@@ -399,7 +464,7 @@
540 SearchController.SetString (SearchController.Query + str);
541 }
542
543- void OnCopyEvent ()
544+ void OnCopyEvent (EventKey evnt)
545 {
546 Gtk.Clipboard clip = Gtk.Clipboard.Get (Selection.Clipboard);
547 if (SearchController.Selection != null)
548@@ -408,14 +473,14 @@
549
550 void OnActivateKeyPressEvent (EventKey evnt)
551 {
552- im_context.Reset ();
553- if (SearchController.TextType == TextModeType.Explicit) {
554- OnInputKeyPressEvent (evnt);
555- return;
556- }
557- bool shift_pressed = (evnt.State & ModifierType.ShiftMask) != 0;
558- PerformAction (!shift_pressed);
559- }
560+ im_context.Reset ();
561+ if (SearchController.TextType == TextModeType.Explicit) {
562+ OnInputKeyPressEvent (evnt);
563+ return;
564+ }
565+ bool shift_pressed = (evnt.State & ModifierType.ShiftMask) != 0;
566+ PerformAction (!shift_pressed);
567+ }
568
569 /// <summary>
570 /// This will set a secondary cursor unless we are operating on a text
571@@ -494,28 +559,32 @@
572 }
573 }
574
575- void OnRightLeftKeyPressEvent (EventKey evnt)
576+ void OnLeftKeyPressEvent (EventKey evnt)
577 {
578 im_context.Reset ();
579 if (!SearchController.Results.Any ()) return;
580
581- if ((Key) evnt.KeyValue == RightKey) {
582- // We're attempting to browse the contents of an item, so increase its
583- // relevance.
584- SearchController.Selection
585- .IncreaseRelevance (SearchController.Query, null);
586- if (SearchController.ItemChildSearch ()) GrowResults ();
587- } else if ((Key) evnt.KeyValue == LeftKey) {
588- // We're attempting to browse the parent of an item, so decrease its
589- // relevance. This makes it so we can merely visit an item's children,
590- // and navigate back out of the item, and leave that item's relevance
591- // unchanged.
592- SearchController.Selection
593- .DecreaseRelevance (SearchController.Query, null);
594- if (SearchController.ItemParentSearch ()) GrowResults ();
595- }
596+ // We're attempting to browse the parent of an item, so decrease its
597+ // relevance. This makes it so we can merely visit an item's children,
598+ // and navigate back out of the item, and leave that item's relevance
599+ // unchanged.
600+ SearchController.Selection
601+ .DecreaseRelevance (SearchController.Query, null);
602+ if (SearchController.ItemParentSearch ()) GrowResults ();
603 }
604-
605+
606+ // Hmm.
607+ void OnRightKeyPressEvent (EventKey evnt)
608+ {
609+ im_context.Reset ();
610+ if (!SearchController.Results.Any ()) return;
611+
612+ // We're attempting to browse the contents of an item, so increase its
613+ // relevance.
614+ SearchController.Selection.IncreaseRelevance (SearchController.Query, null);
615+ if (SearchController.ItemChildSearch ()) GrowResults ();
616+ }
617+
618 void OnTabKeyPressEvent (EventKey evnt)
619 {
620 im_context.Reset ();
621@@ -526,12 +595,21 @@
622 UpdatePane (CurrentPane);
623 }
624
625- if (evnt.Key == Key.Tab) {
626- NextPane ();
627- } else if (evnt.Key == Key.ISO_Left_Tab) {
628- PrevPane ();
629- }
630+ NextPane ();
631 }
632+
633+ void OnShiftTabKeyPressEvent (EventKey evnt)
634+ {
635+ im_context.Reset ();
636+ ShrinkResults ();
637+
638+ if (SearchController.TextType == TextModeType.Explicit) {
639+ SearchController.FinalizeTextMode ();
640+ UpdatePane (CurrentPane);
641+ }
642+ PrevPane ();
643+ }
644+
645
646 void OnTextModePressEvent (EventKey evnt)
647 {
648@@ -548,38 +626,56 @@
649 UpdatePane (CurrentPane);
650 }
651
652- void OnUpDownKeyPressEvent (EventKey evnt)
653+ void OnUpKeyPressEvent (EventKey evnt)
654+ {
655+ im_context.Reset ();
656+ if (!results_grown) {
657+ if (SearchController.Cursor > 0)
658+ GrowResults ();
659+ return;
660+ } else {
661+ if (SearchController.Cursor <= 0) {
662+ ShrinkResults ();
663+ return;
664+ }
665+ SearchController.Cursor--;
666+ }
667+ }
668+
669+ void OnDownKeyPressEvent (EventKey evnt)
670 {
671- im_context.Reset ();
672- if (evnt.Key == UpKey) {
673- if (!results_grown) {
674- if (SearchController.Cursor > 0)
675- GrowResults ();
676- return;
677- } else {
678- if (SearchController.Cursor <= 0) {
679- ShrinkResults ();
680- return;
681- }
682- SearchController.Cursor--;
683- }
684- } else if (evnt.Key == DownKey) {
685- if (!results_grown) {
686- GrowResults ();
687- return;
688- }
689- SearchController.Cursor++;
690- } else if (evnt.Key == Key.Home) {
691- SearchController.Cursor = 0;
692- } else if (evnt.Key == Key.End) {
693- SearchController.Cursor = SearchController.Results.Count - 1;
694- } else if (evnt.Key == Key.Page_Down) {
695- SearchController.Cursor += 5;
696- } else if (evnt.Key == Key.Page_Up) {
697- SearchController.Cursor -= 5;
698- }
699+ im_context.Reset ();
700+ if (!results_grown) {
701+ GrowResults ();
702+ return;
703+ }
704+ SearchController.Cursor++;
705 }
706-
707+
708+ void OnHomeKeyPressEvent (EventKey evnt)
709+ {
710+ im_context.Reset ();
711+ SearchController.Cursor = 0;
712+ }
713+
714+ void OnEndKeyPressEvent (EventKey evnt)
715+ {
716+ im_context.Reset ();
717+ SearchController.Cursor = SearchController.Results.Count - 1;
718+ }
719+
720+ void OnPageUpKeyPressEvent (EventKey evnt)
721+ {
722+ im_context.Reset ();
723+ SearchController.Cursor -= 5;
724+ }
725+
726+ void OnPageDownKeyPressEvent (EventKey evnt)
727+ {
728+ im_context.Reset ();
729+ SearchController.Cursor += 5;
730+ }
731+
732 /// <summary>
733 /// Converts a keypress into a human readable string for comparing
734 /// against values in GConf.
735
736=== added file 'Do/src/Do.Core/Shortcut.cs'
737--- Do/src/Do.Core/Shortcut.cs 1970-01-01 00:00:00 +0000
738+++ Do/src/Do.Core/Shortcut.cs 2009-03-23 03:26:01 +0000
739@@ -0,0 +1,46 @@
740+/* Shortcut.cs
741+ *
742+ * GNOME Do is the legal property of its developers. Please refer to the
743+ * COPYRIGHT file distributed with this
744+ * source distribution.
745+ *
746+ * This program is free software: you can redistribute it and/or modify
747+ * it under the terms of the GNU General Public License as published by
748+ * the Free Software Foundation, either version 3 of the License, or
749+ * (at your option) any later version.
750+ *
751+ * This program is distributed in the hope that it will be useful,
752+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
753+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
754+ * GNU General Public License for more details.
755+ *
756+ * You should have received a copy of the GNU General Public License
757+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
758+ */
759+
760+using System;
761+using System.Linq;
762+using System.Collections;
763+using System.Collections.Generic;
764+using Env = System.Environment;
765+
766+using Do.Platform;
767+
768+namespace Do
769+{
770+ class Shortcut {
771+ public string ShortcutName; // name of the shortcut
772+ public string FriendlyName; // display name of the shortcut
773+ public ShortcutCallback Callback; // callback function for this shortcut
774+
775+ public Shortcut (string name, string friendly, ShortcutCallback cb)
776+ {
777+ ShortcutName = name;
778+ FriendlyName = friendly;
779+ Callback = cb;
780+
781+ }
782+ }
783+}
784+
785+
786
787=== added file 'Do/src/Do.Core/ShortcutCallback.cs'
788--- Do/src/Do.Core/ShortcutCallback.cs 1970-01-01 00:00:00 +0000
789+++ Do/src/Do.Core/ShortcutCallback.cs 2009-03-23 03:05:45 +0000
790@@ -0,0 +1,28 @@
791+/* ShortcutCallback.cs
792+ *
793+ * GNOME Do is the legal property of its developers. Please refer to the
794+ * COPYRIGHT file distributed with this
795+ * source distribution.
796+ *
797+ * This program is free software: you can redistribute it and/or modify
798+ * it under the terms of the GNU General Public License as published by
799+ * the Free Software Foundation, either version 3 of the License, or
800+ * (at your option) any later version.
801+ *
802+ * This program is distributed in the hope that it will be useful,
803+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
804+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
805+ * GNU General Public License for more details.
806+ *
807+ * You should have received a copy of the GNU General Public License
808+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
809+ */
810+
811+using System;
812+using Do;
813+using Gdk;
814+using Mono.Unix;
815+namespace Do.Platform {
816+
817+ public delegate void ShortcutCallback (EventKey evtky);
818+}
819
820=== modified file 'Do/src/Do.UI/KeybindingTreeView.cs'
821--- Do/src/Do.UI/KeybindingTreeView.cs 2008-12-05 20:37:01 +0000
822+++ Do/src/Do.UI/KeybindingTreeView.cs 2009-03-23 03:05:45 +0000
823@@ -29,22 +29,29 @@
824 enum Column {
825 Action = 0,
826 Binding,
827+ DefaultKeybinding,
828+ ShortcutName,
829 NumColumns
830 }
831
832 public KeybindingTreeView ()
833 {
834- Model = new ListStore (typeof (string), typeof (string));
835+ Model = new ListStore (typeof (string), typeof (string), typeof (string), typeof (string));
836
837 CellRendererText actionCell = new CellRendererText ();
838 actionCell.Width = 150;
839 InsertColumn (-1, "Action", actionCell, "text", (int)Column.Action);
840
841 CellRendererAccel bindingCell = new CellRendererAccel ();
842+ bindingCell.AccelMode = CellRendererAccelMode.Gtk;
843 bindingCell.Editable = true;
844 bindingCell.AccelEdited += new AccelEditedHandler (OnAccelEdited);
845 bindingCell.AccelCleared += new AccelClearedHandler (OnAccelCleared);
846 InsertColumn (-1, "Shortcut", bindingCell, "text", (int)Column.Binding);
847+
848+ CellRendererText defaultbindingCell = new CellRendererText ();
849+ actionCell.Width = 150;
850+ InsertColumn (-1, "Default Shortcut", defaultbindingCell, "text", (int)Column.DefaultKeybinding);
851
852 RowActivated += new RowActivatedHandler (OnRowActivated);
853 ButtonPressEvent += new ButtonPressEventHandler (OnButtonPress);
854@@ -57,9 +64,12 @@
855 {
856 ListStore store = Model as ListStore;
857 store.Clear ();
858-
859- store.AppendValues ("Summon", Do.Preferences.SummonKeybinding);
860- store.AppendValues ("Text Mode", Do.Preferences.TextModeKeybinding);
861+
862+ foreach (Shortcut sc in Do.Keybindings.Shortcuts)
863+ {
864+ store.AppendValues (sc.FriendlyName, Do.Keybindings.GetKeybinding (sc),
865+ Do.Keybindings.GetDefaultKeybinding (sc), sc.ShortcutName);
866+ }
867 }
868
869 [GLib.ConnectBefore]
870@@ -91,7 +101,18 @@
871
872 string realKey = Gtk.Accelerator.Name (args.AccelKey, args.AccelMods);
873
874+ // Look for any other rows that have the same binding and then zero that binding out
875+ Model.Foreach ((model, path, treeiter) =>
876+ {
877+ string binding = model.GetValue (treeiter, (int)Column.Binding) as string;
878+ if (binding == realKey) {
879+ model.SetValue (treeiter, (int)Column.Binding, "");
880+ }
881+ return false;
882+ } );
883+
884 store.SetValue (iter, (int)Column.Binding, realKey);
885+
886 SaveBindings ();
887 }
888
889@@ -102,7 +123,9 @@
890
891 store = Model as ListStore;
892 store.GetIter (out iter, new TreePath (args.PathString));
893- store.SetValue (iter, (int)Column.Binding, "DISABLED");
894+ store.SetValue (iter, (int)Column.Binding, "");
895+
896+ SaveBindings ();
897 }
898
899 private void SaveBindings ()
900@@ -112,20 +135,15 @@
901
902 private bool SaveBindingsForeachFunc (TreeModel model, TreePath path, TreeIter iter)
903 {
904- string action, binding;
905- action = model.GetValue (iter, (int)Column.Action) as string;
906-
907- switch (action.ToLower ()) {
908- case "summon":
909- binding = model.GetValue (iter, (int)Column.Binding) as string;
910- Do.Preferences.SummonKeybinding = binding;
911- break;
912- case "text mode":
913- binding = model.GetValue (iter, (int)Column.Binding) as string;
914- Do.Preferences.TextModeKeybinding = binding;
915- break;
916- }
917+ string binding, shortcutname;
918+ binding = model.GetValue (iter, (int)Column.Binding) as string;
919+ shortcutname = model.GetValue (iter, (int)Column.ShortcutName) as string;
920+
921+ if (binding != null && binding != "DISABLED" && binding != Do.Keybindings.GetKeybinding (shortcutname))
922+ Do.Keybindings.BindShortcut (shortcutname, binding);
923 return false;
924 }
925+
926 }
927+
928 }
929
930=== modified file 'Do/src/Do.cs'
931--- Do/src/Do.cs 2009-01-20 04:56:39 +0000
932+++ Do/src/Do.cs 2009-03-23 03:26:01 +0000
933@@ -37,6 +37,7 @@
934 static UniverseManager universe_manager;
935
936 public static CorePreferences Preferences { get; private set; }
937+ public static CoreKeybindings Keybindings { get; private set; }
938
939 internal static void Main (string [] args)
940 {
941@@ -54,6 +55,9 @@
942
943 Preferences = new CorePreferences ();
944
945+ Keybindings = new CoreKeybindings ();
946+ Keybindings.Initialize ();
947+
948 // Now we can set the preferred log level.
949 if (Preferences.QuietStart)
950 Log.DisplayLevel = LogLevel.Error;
951@@ -95,11 +99,24 @@
952 return universe_manager;
953 }
954 }
955+
956+ static void SummonKeyCb (object sender, PreferencesChangedEventArgs e)
957+ {
958+ try {
959+ if (e.OldValue != null)
960+ keybinder.Unbind (e.OldValue as string);
961+ keybinder.Bind (Keybindings.GetKeybinding ("SummonKey"), OnActivate);
962+ } catch (Exception ex) {
963+ Log.Error ("Could not bind summon key: {0}", ex.Message);
964+ Log.Debug (ex.StackTrace);
965+ }
966+
967+ }
968
969 static void SetupKeybindings ()
970 {
971 try {
972- keybinder.Bind (Preferences.SummonKeybinding, OnActivate);
973+ keybinder.Bind (Keybindings.GetKeybinding ("SummonKey"), OnActivate);
974 } catch (Exception e) {
975 Log.Error ("Could not bind summon key: {0}", e.Message);
976 Log.Debug (e.StackTrace);
977@@ -107,16 +124,7 @@
978
979 // Watch preferences for changes to the keybinding so we
980 // can change the binding when the user reassigns it.
981- Preferences.SummonKeybindingChanged += (sender, e) => {
982- try {
983- if (e.OldValue != null)
984- keybinder.Unbind (e.OldValue as string);
985- keybinder.Bind (Preferences.SummonKeybinding, OnActivate);
986- } catch (Exception ex) {
987- Log.Error ("Could not bind summon key: {0}", ex.Message);
988- Log.Debug (ex.StackTrace);
989- }
990- };
991+ Keybindings.RegisterNotification ("SummonKey", SummonKeyCb);
992 }
993
994 static void OnActivate (object sender, EventArgs e)