Revision: 2300
Author: jprantan
Date: Mon Oct 19 21:46:54 2009
Log: Initial implementation for Get Selection From User keyword, issue 414.
http://code.google.com/p/robotframework/source/detail?r=2300

Modified:
 /trunk/src/robot/libraries/Dialogs.py

=======================================
--- /trunk/src/robot/libraries/Dialogs.py       Thu Aug 13 06:04:37 2009
+++ /trunk/src/robot/libraries/Dialogs.py       Mon Oct 19 21:46:54 2009
@@ -61,27 +61,150 @@
         raise ValueError('No value provided by user')
     return value

+def get_selection_from_user(message, *values):
+    """Pauses the test execution and asks user to select value
+
+    `message` is the instruction shown in the dialog. and `values` are
+    the options given to the user. Selecting 'Cancel' fails the keyword.
+    """
+    value = _get_selection_from_user(message, values)
+    if value is None:
+        raise ValueError('No value provided by user')
+    return value
+
+def _pause_execution(message):
+    _MessageDialog(message)
+
+def _execute_manual_step(message):
+    return _PassFailDialog(message).result
+
+def _get_value_from_user(message, default):
+    return _InputDialog(message, default).result
+
+def _get_selection_from_user(message, values):
+    return _SelectionDialog(message, list(values)).result
+

 if not sys.platform.startswith('java'):
     # CPython implementation

-    from Tkinter import Tk
+    from Tkinter import Tk, Toplevel, Frame, Listbox, Label, Button,\
+                        BOTH, END, ACTIVE, LEFT
     import tkMessageBox
     import tkSimpleDialog

-    Tk().withdraw() # Hides the main frame.
+    # Hides the main frame when tkMessageBox and tkSimpleDialog is used
+    Tk().withdraw()


-    def _pause_execution(message):
-        tkMessageBox.showinfo(DIALOG_TITLE, message)
-
-    def _execute_manual_step(message):
-        message += '\n\n<Yes> means PASS and <No> means FAIL.'
-        return tkMessageBox.askyesno(DIALOG_TITLE, message)
-
-    def _get_value_from_user(message, default):
-        return tkSimpleDialog.askstring(DIALOG_TITLE, message,
-                                        initialvalue=default)
+    class _AbstractTkDialog(Toplevel):
+
+        def __init__(self, title):
+            parent = Tk()
+            parent.withdraw() # Hides the main frame.
+            Toplevel.__init__(self, parent)
+            self.title(title)
+            self.parent = parent
+            self.result = None
+            body = Frame(self)
+            self.initial_focus = self.body(body)
+            body.pack(padx=5, pady=5, expand=1, fill=BOTH)
+            self.buttonbox()
+            self.grab_set()
+            if not self.initial_focus:
+                self.initial_focus = self
+            self.protocol("WM_DELETE_WINDOW", self._right_clicked)
+            self.geometry("+%d+%d" % (parent.winfo_rootx()+50,
+            parent.winfo_rooty()+50))
+            self.initial_focus.focus_set()
+            self.wait_window(self)
+
+        def buttonbox(self):
+            box = Frame(self)
+ w = Button(box, text=self._left_button, width=10, command=self._left_clicked, default=ACTIVE)
+            w.pack(side=LEFT, padx=5, pady=5)
+ w = Button(box, text=self._right_button, width=10, command=self._right_clicked)
+            w.pack(side=LEFT, padx=5, pady=5)
+            self.bind("&lt;Return>", self._left_clicked)
+            self.bind("&lt;Escape>", self._right_clicked)
+            box.pack()
+
+        def _left_clicked(self, event=None):
+            if not self.validate():
+                self.initial_focus.focus_set()
+                return
+            self.withdraw()
+            self.update_idletasks()
+            self.apply()
+            self._right_clicked()
+
+        def _right_clicked(self, event=None):
+            self.parent.focus_set()
+            self.destroy()
+
+        def body(self, parent):
+            raise NotImplementedError()
+
+        def validate(self):
+            raise NotImplementedError()
+
+        def apply(self):
+            raise NotImplementedError()
+
+
+    class _MessageDialog:
+
+        def __init__(self, message):
+            tkMessageBox.showinfo(DIALOG_TITLE, message)
+
+
+    class _InputDialog:
+
+        def __init__(self, message, default):
+            self.result = tkSimpleDialog.askstring(DIALOG_TITLE, message,
+                                                   initialvalue=default)
+
+
+    class _SelectionDialog(_AbstractTkDialog):
+        _left_button = 'OK'
+        _right_button = 'Cancel'
+
+        def __init__(self, message, values):
+            self._message = message
+            self._values = values
+            _AbstractTkDialog.__init__(self, "Select one option")
+
+        def body(self, parent):
+            Label(parent, text=self._message).pack(fill=BOTH)
+            self._listbox = Listbox(parent)
+            self._listbox.pack(fill=BOTH)
+            for item in self._values:
+                self._listbox.insert(END, item)
+            return self._listbox
+
+        def validate(self):
+            return self._listbox.curselection()
+
+        def apply(self):
+            self.result = self._listbox.get(self._listbox.curselection())
+
+
+    class _PassFailDialog(_AbstractTkDialog):
+        _left_button = 'PASS'
+        _right_button = 'FAIL'
+
+        def __init__(self, message):
+            self._message = message
+            _AbstractTkDialog.__init__(self, DIALOG_TITLE)
+
+        def body(self, parent):
+            Label(parent, text=self._message).pack(fill=BOTH)
+
+        def validate(self):
+            return True
+
+        def apply(self):
+            self.result = True


 else:
@@ -89,53 +212,78 @@

     import time
     from javax.swing import JOptionPane
-    from javax.swing.JOptionPane import PLAIN_MESSAGE, YES_NO_OPTION, \
- OK_CANCEL_OPTION, DEFAULT_OPTION, UNINITIALIZED_VALUE, CLOSED_OPTION
-
-    def _pause_execution(message):
-        _show_dialog(message, PLAIN_MESSAGE)
-
-    def _execute_manual_step(message):
-        return 0 == _show_dialog(message, PLAIN_MESSAGE,
-                                 YES_NO_OPTION, ['PASS', 'FAIL'])
-
-    def _get_value_from_user(message, default):
-        return _show_dialog(message, PLAIN_MESSAGE, OK_CANCEL_OPTION,
-                            initial_value=default, input=True)
-
-    def _show_dialog(message, message_type, option_type=DEFAULT_OPTION,
-                     options=None, initial_value=None, input=False):
-        pane = JOptionPane(message, message_type, option_type,
-                           None, options, initial_value)
-        pane.setInitialSelectionValue(initial_value)
-        pane.setWantsInput(input)
-        _create_dialog_and_wait_it_to_be_closed(pane)
-        if input:
-            return _get_input_value(pane)
-        return _get_selected_button_index(pane, options)
-
-    def _create_dialog_and_wait_it_to_be_closed(pane):
-        dialog = pane.createDialog(None, DIALOG_TITLE)
-        dialog.setModal(0);
-        dialog.show()
-        while dialog.isShowing():
-            time.sleep(0.2)
-        dialog.dispose()
-
-    def _get_input_value(pane):
-        value = pane.getInputValue()
-        if value == UNINITIALIZED_VALUE:
-            return None
-        return value
-
-    def _get_selected_button_index(pane, options):
-        value = pane.getValue();
-        if options is None:
-            try:
-                return int(value)
-            except ValueError, TypeError:
-                return CLOSED_OPTION
-        if value in options:
-            return options.index(value)
-        return CLOSED_OPTION
-
+ from javax.swing.JOptionPane import PLAIN_MESSAGE, UNINITIALIZED_VALUE, \
+        YES_NO_OPTION, OK_CANCEL_OPTION, DEFAULT_OPTION
+
+
+    class _AbstractSwingDialog:
+
+        def __init__(self, message):
+            self._message = message
+            self.result = self._show_dialog()
+
+        def _show_dialog(self):
+            self._create_pane()
+            self._create_dialog_and_wait_it_to_be_closed()
+            return self._get_value()
+
+        def _create_dialog_and_wait_it_to_be_closed(self):
+            dialog = self._pane.createDialog(None, DIALOG_TITLE)
+            dialog.setModal(0);
+            dialog.show()
+            while dialog.isShowing():
+                time.sleep(0.2)
+            dialog.dispose()
+
+        def _get_value(self):
+            value = self._pane.getInputValue()
+            if value == UNINITIALIZED_VALUE:
+                return None
+            return value
+
+
+    class _MessageDialog(_AbstractSwingDialog):
+
+        def _create_pane(self):
+            self._pane = JOptionPane(self._message, PLAIN_MESSAGE,
+                                     DEFAULT_OPTION)
+
+
+    class _InputDialog(_AbstractSwingDialog):
+
+        def __init__(self, message, default):
+            self._default = default
+            _AbstractSwingDialog.__init__(self, message)
+
+        def _create_pane(self):
+            self._pane = JOptionPane(self._message, PLAIN_MESSAGE,
+                                     OK_CANCEL_OPTION)
+            self._pane.setWantsInput(True)
+            self._pane.setInitialSelectionValue(self._default)
+
+    class _SelectionDialog(_AbstractSwingDialog):
+
+        def __init__(self, message, options):
+            self._options = options
+            _AbstractSwingDialog.__init__(self, message)
+
+        def _create_pane(self):
+            self._pane = JOptionPane(self._message, PLAIN_MESSAGE,
+                                     OK_CANCEL_OPTION)
+            self._pane.setWantsInput(True)
+            self._pane.setSelectionValues(self._options)
+
+
+    class _PassFailDialog(_AbstractSwingDialog):
+
+        def _create_pane(self):
+            self._buttons = ['PASS', 'FAIL']
+ self._pane = JOptionPane(self._message, PLAIN_MESSAGE, YES_NO_OPTION,
+                                     None, self._buttons, 'PASS')
+
+        def _get_value(self):
+            value = self._pane.getValue()
+            if value in self._buttons and self._buttons.index(value) == 0:
+                return True
+            return False
+

Reply via email to