[kupfer] preferences: add new tab for configure keybinding



commit 464a1312a699d1d1ed0f531ee23dfe5a8a5e6b1a
Author: Karol BÄ?dkowski <karol bedkowski gmail com>
Date:   Thu Apr 7 22:13:13 2005 +0200

    preferences: add new tab for configure keybinding

 data/getkey_dialog.ui      |  136 ++++++++++++++++++++++++
 data/preferences.ui        |  252 +++++++++++++++++++++++++++----------------
 kupfer/ui/getkey_dialog.py |   85 +++++++++++++++
 kupfer/ui/preferences.py   |  171 ++++++++++++++++++++++++++----
 po/POTFILES.in             |    2 +
 5 files changed, 529 insertions(+), 117 deletions(-)
---
diff --git a/data/getkey_dialog.ui b/data/getkey_dialog.ui
new file mode 100644
index 0000000..d470b3f
--- /dev/null
+++ b/data/getkey_dialog.ui
@@ -0,0 +1,136 @@
+<?xml version="1.0"?>
+<interface>
+  <requires lib="gtk+" version="2.16"/>
+  <!-- interface-naming-policy project-wide -->
+  <object class="GtkDialog" id="dialoggetkey">
+    <property name="border_width">6</property>
+    <property name="title" translatable="yes">Set Keyboard Shortcut</property>
+    <property name="resizable">False</property>
+    <property name="modal">True</property>
+    <property name="window_position">center</property>
+    <property name="type_hint">normal</property>
+    <property name="has_separator">False</property>
+    <signal name="key_press_event" handler="on_dialoggetkey_key_press_event"/>
+    <signal name="key_release_event" handler="on_dialoggetkey_key_release_event"/>
+    <child internal-child="vbox">
+      <object class="GtkVBox" id="dialog-vbox1">
+        <property name="visible">True</property>
+        <property name="orientation">vertical</property>
+        <property name="spacing">12</property>
+        <child>
+          <object class="GtkHBox" id="hbox5">
+            <property name="visible">True</property>
+            <property name="spacing">12</property>
+            <child>
+              <object class="GtkImage" id="image1">
+                <property name="visible">True</property>
+                <property name="stock">gtk-preferences</property>
+                <property name="icon-size">6</property>
+              </object>
+              <packing>
+                <property name="position">0</property>
+              </packing>
+            </child>
+            <child>
+              <object class="GtkVBox" id="vbox1">
+                <property name="visible">True</property>
+                <property name="orientation">vertical</property>
+                <property name="spacing">12</property>
+                <child>
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">0</property>
+                    <property name="label" translatable="yes">Set Keyboard Shortcut</property>
+                    <attributes>
+                      <attribute name="weight" value="bold"/>
+                      <attribute name="scale" value="1,000000"/>
+                    </attributes>
+                  </object>
+                  <packing>
+                    <property name="position">0</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkLabel" id="label1">
+                    <property name="visible">True</property>
+                    <property name="xalign">0</property>
+                    <property name="yalign">0</property>
+                    <property name="label" translatable="yes">Please press desired key combination</property>
+                    <property name="use_markup">True</property>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkHBox" id="hbox1">
+                    <property name="visible">True</property>
+                    <property name="spacing">12</property>
+                    <child>
+                      <object class="GtkImage" id="imagekeybindingaux">
+                        <property name="visible">True</property>
+                        <property name="stock">gtk-dialog-error</property>
+                      </object>
+                      <packing>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="labelkeybindingaux">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="label" translatable="yes">Keybinding could not be bound</property>
+                      </object>
+                      <packing>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
+              </object>
+              <packing>
+                <property name="position">1</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="position">1</property>
+          </packing>
+        </child>
+        <child internal-child="action_area">
+          <object class="GtkHButtonBox" id="dialog-action_area1">
+            <property name="visible">True</property>
+            <property name="layout_style">end</property>
+            <child>
+              <object class="GtkButton" id="buttoncancel">
+                <property name="label">gtk-cancel</property>
+                <property name="visible">True</property>
+                <property name="can_focus">False</property>
+                <property name="receives_default">False</property>
+                <property name="use_stock">True</property>
+                <signal name="activate" handler="on_buttoncancel_activate"/>
+              </object>
+              <packing>
+                <property name="expand">False</property>
+                <property name="fill">False</property>
+                <property name="position">0</property>
+              </packing>
+            </child>
+          </object>
+          <packing>
+            <property name="expand">False</property>
+            <property name="pack_type">end</property>
+            <property name="position">0</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+    <action-widgets>
+      <action-widget response="0">buttoncancel</action-widget>
+    </action-widgets>
+  </object>
+</interface>
diff --git a/data/preferences.ui b/data/preferences.ui
index 29ed596..4894af0 100644
--- a/data/preferences.ui
+++ b/data/preferences.ui
@@ -103,98 +103,7 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkFrame" id="frame3">
-                            <property name="visible">True</property>
-                            <property name="label_xalign">0</property>
-                            <property name="shadow_type">none</property>
-                            <child>
-                              <object class="GtkAlignment" id="alignment3">
-                                <property name="visible">True</property>
-                                <property name="top_padding">3</property>
-                                <property name="left_padding">12</property>
-                                <child>
-                                  <object class="GtkVBox" id="vbox4">
-                                    <property name="visible">True</property>
-                                    <property name="orientation">vertical</property>
-                                    <child>
-                                      <object class="GtkHBox" id="hbox3">
-                                        <property name="visible">True</property>
-                                        <child>
-                                          <object class="GtkEntry" id="entrykeybinding">
-                                            <property name="visible">True</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="invisible_char">&#x25CF;</property>
-                                            <property name="text">&lt;Ctrl&gt;space</property>
-                                            <signal name="changed" handler="on_entrykeybinding_changed"/>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="padding">8</property>
-                                            <property name="position">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkButton" id="buttonkeybinding">
-                                            <property name="label">gtk-apply</property>
-                                            <property name="visible">True</property>
-                                            <property name="sensitive">False</property>
-                                            <property name="can_focus">True</property>
-                                            <property name="receives_default">True</property>
-                                            <property name="use_stock">True</property>
-                                            <signal name="clicked" handler="on_buttonkeybinding_clicked"/>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="position">1</property>
-                                          </packing>
-                                        </child>
-                                      </object>
-                                      <packing>
-                                        <property name="position">0</property>
-                                      </packing>
-                                    </child>
-                                    <child>
-                                      <object class="GtkHBox" id="hbox4">
-                                        <property name="visible">True</property>
-                                        <property name="spacing">5</property>
-                                        <child>
-                                          <object class="GtkImage" id="imagekeybindingaux">
-                                            <property name="stock">gtk-apply</property>
-                                            <property name="icon-size">1</property>
-                                          </object>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="position">0</property>
-                                          </packing>
-                                        </child>
-                                        <child>
-                                          <object class="GtkLabel" id="labelkeybindingaux"/>
-                                          <packing>
-                                            <property name="expand">False</property>
-                                            <property name="position">1</property>
-                                          </packing>
-                                        </child>
-                                      </object>
-                                      <packing>
-                                        <property name="position">1</property>
-                                      </packing>
-                                    </child>
-                                  </object>
-                                </child>
-                              </object>
-                            </child>
-                            <child type="label">
-                              <object class="GtkLabel" id="label4">
-                                <property name="visible">True</property>
-                                <property name="label" translatable="yes">&lt;b&gt;Keybinding&lt;/b&gt;</property>
-                                <property name="use_markup">True</property>
-                              </object>
-                            </child>
-                          </object>
-                          <packing>
-                            <property name="expand">False</property>
-                            <property name="position">2</property>
-                          </packing>
+                          <placeholder/>
                         </child>
                       </object>
                       <packing>
@@ -302,6 +211,161 @@
                   </packing>
                 </child>
                 <child>
+                  <object class="GtkVBox" id="vbox7">
+                    <property name="visible">True</property>
+                    <property name="border_width">6</property>
+                    <property name="orientation">vertical</property>
+                    <property name="spacing">6</property>
+                    <child>
+                      <object class="GtkLabel" id="label4">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="yalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Global Keyboard Shortcuts&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment6">
+                        <property name="visible">True</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkVBox" id="vbox8">
+                            <property name="visible">True</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">2</property>
+                            <child>
+                              <object class="GtkScrolledWindow" id="keybindings_list_parent">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="hscrollbar_policy">automatic</property>
+                                <property name="vscrollbar_policy">automatic</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHButtonBox" id="hbuttonbox3">
+                                <property name="visible">True</property>
+                                <property name="layout_style">end</property>
+                                <child>
+                                  <object class="GtkButton" id="button_reset_keys">
+                                    <property name="label" translatable="yes">Reset</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <signal name="clicked" handler="on_button_reset_keys_clicked"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkLabel" id="label8">
+                        <property name="visible">True</property>
+                        <property name="xalign">0</property>
+                        <property name="yalign">0</property>
+                        <property name="label" translatable="yes">&lt;b&gt;Browser Keyboard Shortcuts&lt;/b&gt;</property>
+                        <property name="use_markup">True</property>
+                      </object>
+                      <packing>
+                        <property name="expand">False</property>
+                        <property name="position">2</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkAlignment" id="alignment7">
+                        <property name="visible">True</property>
+                        <property name="left_padding">12</property>
+                        <child>
+                          <object class="GtkVBox" id="vbox4">
+                            <property name="visible">True</property>
+                            <property name="orientation">vertical</property>
+                            <property name="spacing">2</property>
+                            <child>
+                              <object class="GtkScrolledWindow" id="gkeybindings_list_parent">
+                                <property name="visible">True</property>
+                                <property name="can_focus">True</property>
+                                <property name="hscrollbar_policy">automatic</property>
+                                <property name="vscrollbar_policy">automatic</property>
+                                <child>
+                                  <placeholder/>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="position">0</property>
+                              </packing>
+                            </child>
+                            <child>
+                              <object class="GtkHButtonBox" id="hbuttonbox4">
+                                <property name="visible">True</property>
+                                <property name="layout_style">end</property>
+                                <child>
+                                  <object class="GtkButton" id="button_reset_gkeys">
+                                    <property name="label" translatable="yes">Reset</property>
+                                    <property name="visible">True</property>
+                                    <property name="can_focus">True</property>
+                                    <property name="receives_default">True</property>
+                                    <signal name="clicked" handler="on_button_reset_gkeys_clicked"/>
+                                  </object>
+                                  <packing>
+                                    <property name="expand">False</property>
+                                    <property name="fill">False</property>
+                                    <property name="position">0</property>
+                                  </packing>
+                                </child>
+                              </object>
+                              <packing>
+                                <property name="expand">False</property>
+                                <property name="position">1</property>
+                              </packing>
+                            </child>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="position">3</property>
+                      </packing>
+                    </child>
+                  </object>
+                  <packing>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child type="tab">
+                  <object class="GtkLabel" id="label2">
+                    <property name="visible">True</property>
+                    <property name="label" translatable="yes">Keyboard</property>
+                  </object>
+                  <packing>
+                    <property name="position">2</property>
+                    <property name="tab_fill">False</property>
+                  </packing>
+                </child>
+                <child>
                   <object class="GtkHBox" id="hbox1">
                     <property name="visible">True</property>
                     <property name="spacing">10</property>
@@ -377,7 +441,7 @@
                     </child>
                   </object>
                   <packing>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                   </packing>
                 </child>
                 <child type="tab">
@@ -386,7 +450,7 @@
                     <property name="label" translatable="yes">Plugins</property>
                   </object>
                   <packing>
-                    <property name="position">1</property>
+                    <property name="position">2</property>
                     <property name="tab_fill">False</property>
                   </packing>
                 </child>
diff --git a/kupfer/ui/getkey_dialog.py b/kupfer/ui/getkey_dialog.py
new file mode 100644
index 0000000..ffcb064
--- /dev/null
+++ b/kupfer/ui/getkey_dialog.py
@@ -0,0 +1,85 @@
+#!/usr/bin/python
+
+import gtk
+
+from kupfer import version, config
+
+
+class GetKeyDialogController(object):
+
+	def __init__(self, check_callback=None, previous_key=None):
+		'''@check_callback - optional function to check is entered key is valid.
+		@previous_key - optional previous keybinding, press equal act like cancel'''
+		builder = gtk.Builder()
+		builder.set_translation_domain(version.PACKAGE_NAME)
+
+		ui_file = config.get_data_file("getkey_dialog.ui")
+		builder.add_from_file(ui_file)
+		builder.connect_signals(self)
+		self.window = builder.get_object("dialoggetkey")
+		self.labelkey = builder.get_object('labelkey')
+		self.imagekeybindingaux = builder.get_object('imagekeybindingaux')
+		self.labelkeybindingaux = builder.get_object('labelkeybindingaux')
+
+		self.imagekeybindingaux.hide()
+		self.labelkeybindingaux.hide()
+
+		self._key = None
+		self._check_callback = check_callback
+		self._previous_key = previous_key
+
+		self.window.connect("focus-in-event", self.on_window_focus_in)
+		self.window.connect("focus-out-event", self.on_window_focus_out)
+
+	def run(self):
+		''' Run dialog, return key codes or None when user press cancel'''
+		self.window.run()
+		self.window.destroy()
+		return self._key
+
+	def on_buttoncancel_activate(self, _widget):
+		self._key = None
+		self.window.hide()
+
+	def on_dialoggetkey_key_press_event(self, _widget, event):
+		self.imagekeybindingaux.hide()
+		self.labelkeybindingaux.hide()
+		keyname = gtk.gdk.keyval_name(event.keyval)
+		if keyname == 'Escape':
+			self._key = None
+			self.window.hide()
+		elif keyname == 'BackSpace':
+			self._key = ''
+			self.window.hide()
+		elif gtk.accelerator_valid(event.keyval, event.state):
+			modifiers = gtk.accelerator_get_default_mod_mask()
+			state = event.state & modifiers
+			self._key = gtk.accelerator_name(event.keyval, state)
+			if self._previous_key is not None and self._key == self._previous_key:
+				self._key = None
+				self.window.hide()
+				return
+			if self._check_callback is None:
+				self.window.hide()
+				return
+			if self._check_callback(self._key):
+				self.window.hide()
+			else:
+				self.imagekeybindingaux.show()
+				self.labelkeybindingaux.show()
+				self._key = None
+
+	def on_dialoggetkey_key_release_event(self, widget, event):
+		pass
+
+	def on_window_focus_in(self, window, _event):
+		pass
+
+	def on_window_focus_out(self, _window, _event):
+		pass
+
+
+def ask_for_key(check_callback=None, previous_key=None):
+	dlg = GetKeyDialogController(check_callback, previous_key)
+	result = dlg.run()
+	return result
diff --git a/kupfer/ui/preferences.py b/kupfer/ui/preferences.py
index 5725fe5..cfe9bd9 100644
--- a/kupfer/ui/preferences.py
+++ b/kupfer/ui/preferences.py
@@ -14,9 +14,33 @@ from kupfer import scheduler, kupferstring
 from kupfer.core import settings, plugins, relevance
 from kupfer.ui import keybindings
 from kupfer.ui.credentials_dialog import ask_user_credentials
+from kupfer.ui import getkey_dialog
 
 
 class PreferencesWindowController (pretty.OutputMixin):
+
+	KEYBINDING_NAMES = {
+		'keybinding': _("Show Main Interface"),
+		'magickeybinding': _("Show with Selection"),
+	}
+
+	KEYBINDING_TARGETS = {
+		"keybinding": keybindings.KEYBINDING_DEFAULT,
+		"magickeybinding": keybindings.KEYBINDING_MAGIC,
+	}
+
+	ACCELERATOR_NAMES = {
+		'activate': _('Alternate Activate'),
+		'compose_action': _('Compose Command'),
+		'reset_all': _('Reset All'),
+		'select_quit': _('Select Quit'),
+		'select_selected_file': _('Select Selected File'),
+		'select_selected_text': _('Select Selected Text'),
+		'show_help': _('Show Help'),
+		'switch_to_source': _('Switch to First Pane'),
+		"toggle_text_mode_quick": _('Toggle Text Mode'),
+	}
+
 	def __init__(self):
 		"""Load ui from data file"""
 		builder = gtk.Builder()
@@ -37,17 +61,14 @@ class PreferencesWindowController (pretty.OutputMixin):
 		self.plugin_about_parent = builder.get_object("plugin_about_parent")
 		self.preferences_notebook = builder.get_object("preferences_notebook")
 
-		self.entrykeybinding = builder.get_object("entrykeybinding")
-		self.buttonkeybinding = builder.get_object("buttonkeybinding")
-		self.imagekeybindingaux = builder.get_object("imagekeybindingaux")
-		self.labelkeybindingaux = builder.get_object("labelkeybindingaux")
 		self.buttonremovedirectory = builder.get_object("buttonremovedirectory")
 		checkautostart = builder.get_object("checkautostart")
 		checkstatusicon = builder.get_object("checkstatusicon")
 		self.entry_plugins_filter = builder.get_object('entry_plugins_filter')
+		self.keybindings_list_parent = builder.get_object('keybindings_list_parent')
+		self.gkeybindings_list_parent = builder.get_object('gkeybindings_list_parent')
 
 		setctl = settings.GetSettingsController()
-		self.entrykeybinding.set_text(setctl.get_keybinding())
 		checkautostart.set_active(self._get_should_autostart())
 		checkstatusicon.set_active(setctl.get_show_status_icon())
 
@@ -123,6 +144,35 @@ class PreferencesWindowController (pretty.OutputMixin):
 		self.dirlist_parent.add(self.dir_table)
 		self.read_directory_settings()
 
+		# keybindings list
+		self.keybind_table, self.keybind_store = _create_conf_keys_list()
+		self.keybindings_list_parent.add(self.keybind_table)
+		self.keybind_table.connect("row-activated", self.on_keybindings_row_activate)
+		# global keybindings list
+		self.gkeybind_table, self.gkeybind_store = _create_conf_keys_list()
+		self.gkeybindings_list_parent.add(self.gkeybind_table)
+		self.gkeybind_table.connect("row-activated",
+				self.on_gkeybindings_row_activate)
+
+		self._show_keybindings(setctl)
+		self._show_gkeybindings(setctl)
+
+	def _show_keybindings(self, setctl):
+		names = self.KEYBINDING_NAMES
+		self.keybind_store.clear()
+		for binding in sorted(names, key=lambda k: names[k]):
+			accel = setctl.get_global_keybinding(binding)
+			label = gtk.accelerator_get_label(*gtk.accelerator_parse(accel))
+			self.keybind_store.append((names[binding], label, binding))
+
+	def _show_gkeybindings(self, setctl):
+		names = self.ACCELERATOR_NAMES
+		self.gkeybind_store.clear()
+		for binding in sorted(names, key=lambda k: names[k]):
+			accel = setctl.get_accelerator(binding)
+			label = gtk.accelerator_get_label(*gtk.accelerator_parse(accel))
+			self.gkeybind_store.append((names[binding], label, binding))
+
 	def read_directory_settings(self):
 		setctl = settings.GetSettingsController()
 		dirs = setctl.get_directories()
@@ -200,26 +250,14 @@ class PreferencesWindowController (pretty.OutputMixin):
 		dfile.write(filename=autostart_file)
 
 	def on_entrykeybinding_changed(self, widget):
-		sensitive = widget.get_text() != keybindings.get_currently_bound_key()
-		self.buttonkeybinding.set_sensitive(sensitive)
-		self.imagekeybindingaux.hide()
-		self.labelkeybindingaux.hide()
+		pass
 
 	def on_buttonkeybinding_clicked(self, widget):
-		keystr = self.entrykeybinding.get_text()
-		self.output_debug("Try set keybinding with", keystr)
-		succ = keybindings.bind_key(keystr)
-		if succ:
-			self.imagekeybindingaux.set_property("stock", gtk.STOCK_APPLY)
-			self.labelkeybindingaux.set_text(_("Applied"))
-			self.buttonkeybinding.set_sensitive(False)
-		else:
-			self.imagekeybindingaux.set_property("stock",
-					gtk.STOCK_DIALOG_WARNING)
-			self.labelkeybindingaux.set_text(_("Keybinding could not be bound"))
-		self.imagekeybindingaux.show()
-		self.labelkeybindingaux.show()
-		if succ:
+		keystr = getkey_dialog.ask_for_key(keybindings.bind_key)
+		if keystr:
+			self.entrykeybinding.set_text(keystr)
+			self.output_debug("Try set keybinding with", keystr)
+			succ = keybindings.bind_key(keystr)
 			setctl = settings.GetSettingsController()
 			setctl.set_keybinding(keystr)
 
@@ -589,6 +627,62 @@ class PreferencesWindowController (pretty.OutputMixin):
 	def on_entry_plugins_filter_icon_press(self, entry, icon_pos, event):
 		entry.set_text('')
 
+	def on_keybindings_row_activate(self, treeview, path, view_column):
+		def bind_key_func(target):
+			def bind_key(keystr):
+				return keybindings.bind_key(keystr, target)
+			return bind_key
+
+		it = self.keybind_store.get_iter(path)
+		keybind_id = self.keybind_store.get_value(it, 2)
+		setctl = settings.GetSettingsController()
+		curr_key = setctl.get_global_keybinding(keybind_id)
+		bind_func = bind_key_func(self.KEYBINDING_TARGETS[keybind_id])
+		keystr = getkey_dialog.ask_for_key(bind_func, curr_key)
+		if keystr == '':
+			keybindings.bind_key(None, self.KEYBINDING_TARGETS[keybind_id])
+			self.keybind_store.set_value(it, 1, '')
+		elif self._is_good_keystr(keystr):
+			setctl.set_global_keybinding(keybind_id, keystr)
+			label = gtk.accelerator_get_label(*gtk.accelerator_parse(keystr))
+			self.keybind_store.set_value(it, 1, label)
+
+	def _is_good_keystr(self, keystr):
+		# Reject single letters so you can't bind 'A' etc
+		if keystr is None:
+			return False
+		ukeystr = kupferstring.tounicode(keystr)
+		return not (len(ukeystr) == 1 and ukeystr.isalnum())
+
+	def on_gkeybindings_row_activate(self, treeview, path, view_column):
+		it = self.gkeybind_store.get_iter(path)
+		keybind_id = self.gkeybind_store.get_value(it, 2)
+		setctl = settings.GetSettingsController()
+		curr_key = setctl.get_accelerator(keybind_id)
+		keystr = getkey_dialog.ask_for_key(previous_key=curr_key)
+		if self._is_good_keystr(keystr):
+			setctl.set_accelerator(keybind_id, keystr)
+			label = gtk.accelerator_get_label(*gtk.accelerator_parse(keystr))
+			self.gkeybind_store.set_value(it, 1, label)
+
+	def on_button_reset_keys_clicked(self, button):
+		if self.ask_user_for_reset_keybinding():
+			setctl = settings.GetSettingsController()
+			setctl.reset_keybindings()
+			self._show_keybindings(setctl)
+			# Unbind all before re-binding
+			for keybind_id, target in self.KEYBINDING_TARGETS.iteritems():
+				keybindings.bind_key(None, target)
+			for keybind_id, target in self.KEYBINDING_TARGETS.iteritems():
+				keystr = setctl.get_global_keybinding(keybind_id)
+				keybindings.bind_key(keystr, target)
+
+	def on_button_reset_gkeys_clicked(self, button):
+		if self.ask_user_for_reset_keybinding():
+			setctl = settings.GetSettingsController()
+			setctl.reset_accelerators()
+			self._show_gkeybindings(setctl)
+
 	def dir_table_cursor_changed(self, table):
 		curpath, curcol = table.get_cursor()
 		if not curpath or not self.dir_store:
@@ -612,6 +706,7 @@ class PreferencesWindowController (pretty.OutputMixin):
 		self.table.scroll_to_cell(table_path)
 		# FIXME: Revisit if we add new pages to the GtkNotebook
 		self.preferences_notebook.next_page()
+		self.preferences_notebook.next_page()
 		self.window.present()
 
 	def hide(self):
@@ -620,6 +715,36 @@ class PreferencesWindowController (pretty.OutputMixin):
 		self.hide()
 		return True
 
+	def ask_user_for_reset_keybinding(self):
+		dlg = gtk.MessageDialog(self.window, gtk.DIALOG_MODAL, gtk.MESSAGE_QUESTION)
+		dlg.set_markup(_("Reset all shortcuts to default values?"))
+		dlg.add_buttons(gtk.STOCK_CANCEL, gtk.RESPONSE_CLOSE,
+				_('Reset'), gtk.RESPONSE_ACCEPT)
+		result = dlg.run() == gtk.RESPONSE_ACCEPT
+		dlg.destroy()
+		return result
+
+
+_conf_keys_list_columns = [{"key": "name", "type":str, 'header': _('Name')},
+		{"key": "key", "type": str, 'header': _('Key') },
+		{"key": "keybinding_id", "type": str, 'header':  None}]
+_conf_keys_list_column_types = [c["type"] for c in _conf_keys_list_columns]
+
+def _create_conf_keys_list():
+	keybind_store = gtk.ListStore(*_conf_keys_list_column_types)
+	keybind_table = gtk.TreeView(keybind_store)
+	for idx, col in enumerate(_conf_keys_list_columns):
+		renderer = gtk.CellRendererText()
+		column = gtk.TreeViewColumn(col['header'], renderer, text=idx)
+		column.set_visible(col['header'] is not None)
+		keybind_table.append_column(column)
+	keybind_table.set_property("enable-search", False)
+	keybind_table.set_rules_hint(True)
+	keybind_table.set_headers_visible(True)
+	keybind_table.show()
+	return keybind_table, keybind_store
+
+
 _preferences_window = None
 
 def GetPreferencesWindowController():
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d61836e..f36113d 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,12 +8,14 @@ auxdata/kupfer-mimetypes.xml.in
 [type: gettext/glade] data/result.ui
 [type: gettext/glade] data/credentials_dialog.ui
 [type: gettext/glade] data/progress_dialog.ui
+[type: gettext/glade] data/getkey_dialog.ui
 extras/kupfer_provider.py
 
 
 kupfer/main.py
 kupfer/ui/browser.py
 kupfer/ui/preferences.py
+kupfer/ui/getkey_dialog.py
 kupfer/version.py
 kupfer/commandexec.py
 kupfer/execfile.py



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]