diff options
author | Vratislav Podzimek <vpodzime@redhat.com> | 2012-10-18 13:55:19 +0200 |
---|---|---|
committer | Vratislav Podzimek <vpodzime@redhat.com> | 2012-10-23 23:28:28 +0200 |
commit | 39bfa43b8c249695feb83b4cf3701726b262727a (patch) | |
tree | a44088d1cfc50b96cf670400e18abf6e9227f886 | |
parent | 394a1e9a38e9dd8633363a150b9338034c6630bb (diff) | |
download | anaconda-39bfa43b8c249695feb83b4cf3701726b262727a.tar.gz anaconda-39bfa43b8c249695feb83b4cf3701726b262727a.tar.xz anaconda-39bfa43b8c249695feb83b4cf3701726b262727a.zip |
Add dialog for configuring layout switching options
Resolves: rhbz#864785
Resolves: rhbz#859606
Resolves: rhbz#849504
-rw-r--r-- | pyanaconda/ui/gui/spokes/keyboard.glade | 181 | ||||
-rw-r--r-- | pyanaconda/ui/gui/spokes/keyboard.py | 129 |
2 files changed, 307 insertions, 3 deletions
diff --git a/pyanaconda/ui/gui/spokes/keyboard.glade b/pyanaconda/ui/gui/spokes/keyboard.glade index c122366eb..40c0e0976 100644 --- a/pyanaconda/ui/gui/spokes/keyboard.glade +++ b/pyanaconda/ui/gui/spokes/keyboard.glade @@ -2,7 +2,6 @@ <interface> <!-- interface-requires gtk+ 3.0 --> <!-- interface-requires AnacondaWidgets 1.0 --> - <object class="GtkTextBuffer" id="layoutTestBuffer"/> <object class="GtkDialog" id="addLayoutDialog"> <property name="can_focus">False</property> <property name="border_width">5</property> @@ -422,6 +421,7 @@ <property name="visible">True</property> <property name="can_focus">False</property> <property name="halign">end</property> + <property name="valign">start</property> <property name="label" translatable="yes">Alt + Shift to switch layouts.</property> <attributes> <attribute name="font-desc" value="Cantarell Italic 10"/> @@ -436,17 +436,18 @@ </child> <child> <object class="GtkButton" id="optionsButton"> - <property name="label" translatable="yes">_Options...</property> + <property name="label" translatable="yes">_Options</property> <property name="visible">True</property> <property name="can_focus">True</property> <property name="receives_default">True</property> <property name="halign">end</property> + <property name="valign">start</property> <property name="use_underline">True</property> + <signal name="clicked" handler="on_options_clicked" swapped="no"/> </object> <packing> <property name="expand">False</property> <property name="fill">True</property> - <property name="pack_type">end</property> <property name="position">3</property> </packing> </child> @@ -476,6 +477,7 @@ </object> </child> </object> + <object class="GtkTextBuffer" id="layoutTestBuffer"/> <object class="GtkListStore" id="newLayoutStore"> <columns> <!-- column-name name --> @@ -488,4 +490,177 @@ <object class="GtkTreeModelSort" id="newLayoutStoreSort"> <property name="model">newLayoutStoreFilter</property> </object> + <object class="GtkDialog" id="switchingDialog"> + <property name="can_focus">False</property> + <property name="border_width">5</property> + <property name="default_height">450</property> + <property name="type_hint">dialog</property> + <property name="decorated">False</property> + <child internal-child="vbox"> + <object class="GtkBox" id="dialog-vbox2"> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">2</property> + <child internal-child="action_area"> + <object class="GtkButtonBox" id="dialog-action_area2"> + <property name="can_focus">False</property> + <property name="layout_style">end</property> + <child> + <object class="GtkButton" id="button2"> + <property name="label">gtk-cancel</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkButton" id="button1"> + <property name="label">gtk-ok</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">True</property> + <property name="use_stock">True</property> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="pack_type">end</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkBox" id="box1"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="orientation">vertical</property> + <property name="spacing">6</property> + <child> + <object class="GtkLabel" id="headerLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="valign">start</property> + <property name="label" translatable="yes">LAYOUT SWITCHING OPTIONS</property> + <attributes> + <attribute name="font-desc" value="Cantarell Bold 10"/> + <attribute name="weight" value="bold"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">0</property> + </packing> + </child> + <child> + <object class="GtkLabel" id="descriptionLabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="halign">start</property> + <property name="label" translatable="yes">Which combination(s) would you prefer for switching between keyboard layouts?</property> + <property name="wrap">True</property> + <attributes> + <attribute name="font-desc" value="Cantarell 12"/> + </attributes> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + <child> + <object class="GtkScrolledWindow" id="scrolledwindow2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="margin_left">6</property> + <property name="margin_right">6</property> + <property name="margin_top">6</property> + <property name="vexpand">True</property> + <property name="hscrollbar_policy">never</property> + <property name="shadow_type">in</property> + <child> + <object class="GtkTreeView" id="treeview2"> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="vexpand">True</property> + <property name="model">switchingOptsSort</property> + <property name="headers_visible">False</property> + <property name="headers_clickable">False</property> + <property name="search_column">0</property> + <child internal-child="selection"> + <object class="GtkTreeSelection" id="treeview-selection"/> + </child> + <child> + <object class="GtkTreeViewColumn" id="useColumn"> + <property name="title" translatable="yes">use</property> + <child> + <object class="GtkCellRendererToggle" id="useRenderer"> + <signal name="toggled" handler="on_use_option_toggled" swapped="no"/> + </object> + <attributes> + <attribute name="active">1</attribute> + </attributes> + </child> + </object> + </child> + <child> + <object class="GtkTreeViewColumn" id="descColumn"> + <property name="title" translatable="yes">description</property> + <property name="expand">True</property> + <child> + <object class="GtkCellRendererText" id="descRenderer"/> + <attributes> + <attribute name="markup">0</attribute> + </attributes> + </child> + </object> + </child> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">1</property> + </packing> + </child> + </object> + </child> + <action-widgets> + <action-widget response="0">button2</action-widget> + <action-widget response="1">button1</action-widget> + </action-widgets> + </object> + <object class="GtkListStore" id="switchingOptsStore"> + <columns> + <!-- column-name description --> + <column type="gchararray"/> + <!-- column-name use --> + <column type="gboolean"/> + </columns> + </object> + <object class="GtkTreeModelSort" id="switchingOptsSort"> + <property name="model">switchingOptsStore</property> + </object> </interface> diff --git a/pyanaconda/ui/gui/spokes/keyboard.py b/pyanaconda/ui/gui/spokes/keyboard.py index ee248c49d..714d07db9 100644 --- a/pyanaconda/ui/gui/spokes/keyboard.py +++ b/pyanaconda/ui/gui/spokes/keyboard.py @@ -36,10 +36,19 @@ from pyanaconda import flags __all__ = ["KeyboardSpoke"] +# %s will be replaced by key combination like Alt+Shift +LAYOUT_SWITCHING_INFO = _("%s to switch layouts.") + def _show_layout(column, renderer, model, itr, wrapper): value = wrapper.name_to_show_str[model[itr][0]] renderer.set_property("text", value) +def _show_description(column, renderer, model, itr, wrapper): + value = wrapper.switch_to_show_str[model[itr][0]] + if model[itr][1]: + value = "<b>%s</b>" % value + renderer.set_property("markup", value) + class AddLayoutDialog(GUIObject): builderObjects = ["addLayoutDialog", "newLayoutStore", "newLayoutStoreFilter", "newLayoutStoreSort"] @@ -155,6 +164,91 @@ class AddLayoutDialog(GUIObject): def _addLayout(self, store, name): store.append([name]) + +class ConfigureSwitchingDialog(GUIObject): + """Class representing a dialog for layout switching configuration""" + + builderObjects = ["switchingDialog", "switchingOptsStore", + "switchingOptsSort",] + mainWidgetName = "switchingDialog" + uiFile = "spokes/keyboard.glade" + + def __init__(self, *args): + GUIObject.__init__(self, *args) + self._xkl_wrapper = keyboard.XklWrapper.get_instance() + + self._switchingOptsStore = self.builder.get_object("switchingOptsStore") + + def initialize(self): + # we want to display "Alt + Shift" rather than "grp:alt_shift_toggle" + descColumn = self.builder.get_object("descColumn") + descRenderer = self.builder.get_object("descRenderer") + descColumn.set_cell_data_func(descRenderer, _show_description, + self._xkl_wrapper) + + self._switchingOptsSort = self.builder.get_object("switchingOptsSort") + self._switchingOptsSort.set_default_sort_func(self._compare_options, None) + + for opt in self._xkl_wrapper.get_switching_options(): + self._add_option(opt) + + def refresh(self): + itr = self._switchingOptsStore.get_iter_first() + while itr: + option = self._switchingOptsStore[itr][0] + if option in self.data.keyboard.switch_options: + self._switchingOptsStore.set_value(itr, 1, True) + else: + self._switchingOptsStore.set_value(itr, 1, False) + + itr = self._switchingOptsStore.iter_next(itr) + + def run(self): + rc = self.window.run() + self.window.hide() + return rc + + def _add_option(self, option): + """Add option to the list as unchecked""" + + self._switchingOptsStore.append([option, False]) + + def _compare_options(self, model, itr1, itr2, user_data=None): + """ + We want to sort options by their show strings not their names. + This function is an instance of GtkTreeIterCompareFunc(). + + """ + + value1 = model[itr1][0] + value2 = model[itr2][0] + show_str1 = self._xkl_wrapper.switch_to_show_str[value1] + show_str2 = self._xkl_wrapper.switch_to_show_str[value2] + + if show_str1 < show_str2: + return -1 + elif show_str1 == show_str2: + return 0 + else: + return 1 + + @property + def checked_options(self): + """Property returning all checked options from the list""" + + ret = [row[0] for row in self._switchingOptsStore if row[1] and row[0]] + return ret + + def on_use_option_toggled(self, renderer, path, *args): + itr = self._switchingOptsSort.get_iter(path) + + # Get itr for the *store*. + itr = self._switchingOptsSort.convert_iter_to_child_iter(itr) + old_value = self._switchingOptsStore[itr][1] + + self._switchingOptsStore.set_value(itr, 1, not old_value) + + class KeyboardSpoke(NormalSpoke): builderObjects = ["addedLayoutStore", "keyboardWindow", "layoutTestBuffer"] @@ -202,6 +296,11 @@ class KeyboardSpoke(NormalSpoke): self._store = self.builder.get_object("addedLayoutStore") self._add_data_layouts() + self._switching_dialog = ConfigureSwitchingDialog(self.data) + self._switching_dialog.initialize() + + self._layoutSwitchLabel = self.builder.get_object("layoutSwitchLabel") + if not flags.can_touch_runtime_system("test X layouts"): # Disable area for testing layouts as we cannot make # it work without modifying runtime system @@ -241,6 +340,8 @@ class KeyboardSpoke(NormalSpoke): self._removeButton.set_sensitive(False) self._previewButton.set_sensitive(False) + self._refresh_switching_info() + def _addLayout(self, store, name): store.append([name]) if flags.can_touch_runtime_system("add runtime X layout"): @@ -257,6 +358,16 @@ class KeyboardSpoke(NormalSpoke): self._xkl_wrapper.remove_layout(store[itr][0]) store.remove(itr) + def _refresh_switching_info(self): + if self.data.keyboard.switch_options: + first_option = self.data.keyboard.switch_options[0] + desc = self._xkl_wrapper.switch_to_show_str[first_option] + + self._layoutSwitchLabel.set_text(LAYOUT_SWITCHING_INFO % desc) + else: + self._layoutSwitchLabel.set_text(_("Layout switching not " + "configured.")) + # Signal handlers. def on_add_clicked(self, button): dialog = AddLayoutDialog(self.data) @@ -389,6 +500,24 @@ class KeyboardSpoke(NormalSpoke): self._upButton.set_sensitive(True) self._downButton.set_sensitive(True) + def on_options_clicked(self, *args): + self._switching_dialog.refresh() + + with enlightbox(self.window, self._switching_dialog.window): + response = self._switching_dialog.run() + + if response != 1: + # Cancel clicked, dialog destroyed + return + + # OK clicked, set and save switching options. + new_options = self._switching_dialog.checked_options + self._xkl_wrapper.set_switching_options(new_options) + self.data.keyboard.switch_options = new_options + + # Refresh switching info label. + self._refresh_switching_info() + def _add_data_layouts(self): if self.data.keyboard.x_layouts: for layout in self.data.keyboard.x_layouts: |