summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Sivak <msivak@redhat.com>2010-08-24 16:17:10 +0200
committerMartin Sivak <msivak@redhat.com>2010-08-24 16:17:10 +0200
commit05b78d2a5c4101e552954645df018b21aa32b8fb (patch)
tree88ce337f89088b04fd18e1a38d4fc1c7d2924b21
parentf273fe2502adf3023d816c9f495fad12140c9ddb (diff)
downloadfirstaidkit-05b78d2a5c4101e552954645df018b21aa32b8fb.zip
firstaidkit-05b78d2a5c4101e552954645df018b21aa32b8fb.tar.gz
firstaidkit-05b78d2a5c4101e552954645df018b21aa32b8fb.tar.xz
Improve the user experience
- Expert tab is hidden by default - Config dialog checks the format of entered values - Example plugin for dialogs updated
-rw-r--r--frontend/firstaidkit.glade36
-rw-r--r--frontend/frontend_gtk.py26
-rw-r--r--frontend/gtk-list.xml6
-rw-r--r--plugins/plugin_examples/dialogue.py6
-rw-r--r--pyfirstaidkit/plugins.py3
-rw-r--r--pyfirstaidkit/reporting.py7
6 files changed, 72 insertions, 12 deletions
diff --git a/frontend/firstaidkit.glade b/frontend/firstaidkit.glade
index 1d16cf6..869eba8 100644
--- a/frontend/firstaidkit.glade
+++ b/frontend/firstaidkit.glade
@@ -9,6 +9,8 @@
<property name="type">GTK_WINDOW_TOPLEVEL</property>
<property name="window_position">GTK_WIN_POS_NONE</property>
<property name="modal">False</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
<property name="resizable">True</property>
<property name="destroy_with_parent">False</property>
<property name="decorated">True</property>
@@ -65,11 +67,37 @@
</child>
<child>
- <widget class="GtkImageMenuItem" id="quit">
+ <widget class="GtkImageMenuItem" id="expert_mode1">
+ <property name="visible">True</property>
+ <property name="label" translatable="yes">Expert mode</property>
+ <property name="use_underline">True</property>
+ <signal name="activate" handler="on_mainmenu_expert_activate" last_modification_time="Tue, 24 Aug 2010 13:57:18 GMT"/>
+
+ <child internal-child="image">
+ <widget class="GtkImage" id="image1">
+ <property name="visible">True</property>
+ <property name="stock">gtk-properties</property>
+ <property name="icon_size">1</property>
+ <property name="xalign">0.5</property>
+ <property name="yalign">0.5</property>
+ <property name="xpad">0</property>
+ <property name="ypad">0</property>
+ </widget>
+ </child>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkSeparatorMenuItem" id="separatormenuitem2">
+ <property name="visible">True</property>
+ </widget>
+ </child>
+
+ <child>
+ <widget class="GtkImageMenuItem" id="quit1">
<property name="visible">True</property>
<property name="label">gtk-quit</property>
<property name="use_stock">True</property>
- <signal name="activate" handler="on_quit_activate"/>
</widget>
</child>
</widget>
@@ -118,6 +146,7 @@
<child>
<widget class="GtkVBox" id="vbox3">
+ <property name="border_width">3</property>
<property name="visible">True</property>
<property name="homogeneous">False</property>
<property name="spacing">0</property>
@@ -297,8 +326,7 @@
</child>
<child>
- <widget class="GtkVBox" id="vbox4">
- <property name="visible">True</property>
+ <widget class="GtkVBox" id="expert_page">
<property name="homogeneous">False</property>
<property name="spacing">0</property>
diff --git a/frontend/frontend_gtk.py b/frontend/frontend_gtk.py
index 86b6ed0..cbb113c 100644
--- a/frontend/frontend_gtk.py
+++ b/frontend/frontend_gtk.py
@@ -129,6 +129,11 @@ class CallbacksMainWindow(object):
dir = os.path.dirname(self._glade.relative_file(".")))
return True
+ def on_mainmenu_expert_activate(self, widget, *args):
+ self._glade.get_widget("expert_page").show()
+ self._data.pages.set_current_page(1)
+ return True
+
#advanced mode callbacks
def on_b_StartAdvanced_activate(self, widget, *args):
print("on_b_StartAdvanced_activate")
@@ -317,10 +322,16 @@ class ListDialog(object):
gtkb.add_from_file(os.path.join(dir, "gtk-list.xml"))
self._dialog = gtkb.get_object("listdialog")
self._dialog.set_title(title)
- self._store = gtkb.get_object("store")
+ self._store = gtk.ListStore(gobject.TYPE_STRING,
+ gobject.TYPE_STRING,
+ gobject.TYPE_STRING,
+ gobject.TYPE_STRING,
+ gobject.TYPE_PYOBJECT,
+ gobject.TYPE_STRING)
self._label = gtkb.get_object("label")
self._label.set_text(description)
self._view = gtkb.get_object("view")
+ self._view.set_model(self._store)
rend_text = gtk.CellRendererText()
rend_text_edit = gtk.CellRendererText()
@@ -328,7 +339,11 @@ class ListDialog(object):
rend_text_edit.connect('edited', self.edited_cb, self._store)
col_0 = gtk.TreeViewColumn('Key', rend_text, text = 1)
+ col_0.set_resizable(True)
+ col_0.set_expand(False)
col_1 = gtk.TreeViewColumn('Value', rend_text_edit, text = 2)
+ col_1.set_resizable(True)
+ col_1.set_expand(True)
self._view.append_column(col_0)
self._view.append_column(col_1)
@@ -345,7 +360,14 @@ class ListDialog(object):
return self._dialog.run()
def edited_cb(self, cell, path, new_data, store):
- store[path][2] = new_data
+ res = store[path][4].match(new_data)
+ if res is not None:
+ store[path][2] = new_data
+ else:
+ err = gtk.MessageDialog(type=gtk.MESSAGE_ERROR, buttons=gtk.BUTTONS_OK)
+ err.set_property("text", store[path][5])
+ err.run()
+ err.destroy()
def destroy(self):
self._dialog.destroy()
diff --git a/frontend/gtk-list.xml b/frontend/gtk-list.xml
index bde40e6..427652f 100644
--- a/frontend/gtk-list.xml
+++ b/frontend/gtk-list.xml
@@ -12,10 +12,16 @@
<column type="gchararray"/>
<!-- column-name tooltip -->
<column type="gchararray"/>
+ <!-- column-name regexp -->
+ <column type="gpointer"/>
+ <!-- column-name validator_error -->
+ <column type="gchararray"/>
</columns>
</object>
<object class="GtkDialog" id="listdialog">
<property name="border_width">5</property>
+ <property name="default_width">640</property>
+ <property name="default_height">480</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<signal name="close" handler="cb_close"/>
diff --git a/plugins/plugin_examples/dialogue.py b/plugins/plugin_examples/dialogue.py
index bcc5a00..d5c1857 100644
--- a/plugins/plugin_examples/dialogue.py
+++ b/plugins/plugin_examples/dialogue.py
@@ -78,9 +78,9 @@ class DialoguePlugin(Plugin):
level = PLUGIN)
config_options = [
- ("id:1", "PL", "5", "Password length"),
- ("id:2", "PS", "C", "Password strength"),
- ("id:3", "PL", "aA0.", "Password chars"),
+ ("id:1", "PL", "5", "Password length", "[1-9][0-9]*", "The length must be a valid number bigger than 0."),
+ ("id:2", "PS", "C", "Password strength", "[A-F]", "Use strength indicator A, B, C, D, E or F"),
+ ("id:3", "PL", "aA0.", "Password chars", ".*", "Any allowed characters.."),
]
s = self._reporting.config_question_wait("Setup choices",
diff --git a/pyfirstaidkit/plugins.py b/pyfirstaidkit/plugins.py
index 303cfc9..c0f1361 100644
--- a/pyfirstaidkit/plugins.py
+++ b/pyfirstaidkit/plugins.py
@@ -280,7 +280,8 @@ class Plugin(object):
message = func+" raised "+str(e))
self._reporting.stop(level = TASK, origin = self,
message = func)
- pass
+ if self._interpret._config.system.debug:
+ raise
return (self._state, self._result)
diff --git a/pyfirstaidkit/reporting.py b/pyfirstaidkit/reporting.py
index 9151db9..21a4b45 100644
--- a/pyfirstaidkit/reporting.py
+++ b/pyfirstaidkit/reporting.py
@@ -19,6 +19,7 @@ import Queue
import logging
import thread
import weakref
+import re
from errors import *
@@ -77,14 +78,16 @@ class Question(object):
class ConfigQuestion(Question):
"""A question that allows list of configurable variables
- Each item is a tuple (id, title, value, tooltip)"""
+ Each item is a tuple (id, title, value,
+ tooltip, regexp_validator, validator_error_msg)"""
def __init__(self, title, description, items):
super(ConfigQuestion, self).__init__(title)
assert len(items) > 0
self.title = title
self.description = description
- self.items = items
+ self.items = map(lambda x: (x[0], x[1], x[2], x[3],
+ re.compile("^"+x[4]+"$"), x[5]), items)
class ChoiceQuestion(Question):
"""A question that offers multiple options.