summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVratislav Podzimek <vpodzime@redhat.com>2012-10-18 13:55:19 +0200
committerVratislav Podzimek <vpodzime@redhat.com>2012-10-23 23:28:28 +0200
commit39bfa43b8c249695feb83b4cf3701726b262727a (patch)
treea44088d1cfc50b96cf670400e18abf6e9227f886
parent394a1e9a38e9dd8633363a150b9338034c6630bb (diff)
downloadanaconda-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.glade181
-rw-r--r--pyanaconda/ui/gui/spokes/keyboard.py129
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: