commit-gnue
[Top][All Lists]
Advanced

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

[gnue] r9420 - in trunk/gnue-forms/src/uidrivers/curses: . widgets


From: johannes
Subject: [gnue] r9420 - in trunk/gnue-forms/src/uidrivers/curses: . widgets
Date: Thu, 1 Mar 2007 08:48:40 -0600 (CST)

Author: johannes
Date: 2007-03-01 08:48:39 -0600 (Thu, 01 Mar 2007)
New Revision: 9420

Modified:
   trunk/gnue-forms/src/uidrivers/curses/UIdriver.py
   trunk/gnue-forms/src/uidrivers/curses/dialogs.py
   trunk/gnue-forms/src/uidrivers/curses/widgets/form.py
   trunk/gnue-forms/src/uidrivers/curses/widgets/page.py
Log:
Added File-Selection

issue152 in-progress


Modified: trunk/gnue-forms/src/uidrivers/curses/UIdriver.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/UIdriver.py   2007-02-28 14:10:07 UTC 
(rev 9419)
+++ trunk/gnue-forms/src/uidrivers/curses/UIdriver.py   2007-03-01 14:48:39 UTC 
(rev 9420)
@@ -369,6 +369,61 @@
         return (x, y)
 
     # -------------------------------------------------------------------------
+    # Get a key from keyboard
+    # -------------------------------------------------------------------------
+
+    def get_key(self, window):
+        """
+        Get keyboard input from the given window.  Function keys are returned
+        as curses.KEY_* constant (or a corresponding numeric value).  Other
+        (textual) input is returned as unicode.
+
+        @param window: the curses window to get the input from
+        @returns: curses.KEY_* constant for function keys or unicode string for
+            the given input
+        """
+
+        key = self.__get_next_key(window)
+
+        # Function keys are returned as key-code
+        if key > 255:
+            return key
+
+        result = [key]
+        if i18n.encoding.startswith('utf'):
+            for i in range(self.__get_hibits(key)-1):
+                result.append(self.__get_next_key(window))
+
+        return unicode("".join([chr(i) for i in result]), i18n.encoding)
+
+    # -------------------------------------------------------------------------
+
+    def __get_next_key(self, window):
+
+        # In nodelay mode the result of getch() is -1 if there is no input.
+        # This appears to be returned after a window resize (RESIZE event) too.
+        code = -1
+        while code < 0:
+            code = window.getch()
+
+        return code
+
+    # -------------------------------------------------------------------------
+
+    def __get_hibits(self, value):
+        """ Returns the number of set bits starting at the MSB """
+
+        result = 0
+        for i in range(7, -1, -1):
+            if value & (1 << i):
+                result += 1
+            else:
+                break
+
+        return result
+
+
+    # -------------------------------------------------------------------------
     # Helper method for forms to get active function keys
     # -------------------------------------------------------------------------
 

Modified: trunk/gnue-forms/src/uidrivers/curses/dialogs.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/dialogs.py    2007-02-28 14:10:07 UTC 
(rev 9419)
+++ trunk/gnue-forms/src/uidrivers/curses/dialogs.py    2007-03-01 14:48:39 UTC 
(rev 9420)
@@ -240,6 +240,7 @@
 
     def run(self):
 
+        old = curses.curs_set(1)
         self.__window.refresh()
 
         index = 0
@@ -263,7 +264,9 @@
             else:
                 index += 1
 
+        curses.curs_set(old)
 
+
     # -------------------------------------------------------------------------
     # Calculate and build the window
     # -------------------------------------------------------------------------
@@ -305,7 +308,7 @@
                 rightcol = max(rightcol, widest)
 
 
-        self.__width  = min(max(leftcol + rightcol + 4, width), right - left)
+        self.__width  = min(max(leftcol + rightcol + 4, width, len(title)+2), 
right - left)
         self.__height = min(height, bottom - top)
         self.__wtop   = (bottom - top - self.__height) / 2
         self.__wleft  = (right - left - self.__width) / 2

Modified: trunk/gnue-forms/src/uidrivers/curses/widgets/form.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/form.py       2007-02-28 
14:10:07 UTC (rev 9419)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/form.py       2007-03-01 
14:48:39 UTC (rev 9420)
@@ -22,9 +22,11 @@
 # $Id$
 
 import curses
+import os.path
 
 from gnue.forms.input.GFKeyMapper import KeyMapper
 
+from gnue.forms.uidrivers.curses.dialogs import InputDialog
 from gnue.forms.uidrivers.curses.widgets._base import UIHelper
 
 __all__ = ['UIForm']
@@ -169,6 +171,64 @@
         pass
 
     # -------------------------------------------------------------------------
+    # Show a file selection dialog
+    # -------------------------------------------------------------------------
+
+    def _ui_select_files_(self, title, default_dir, default_file, wildcard,
+            mode, multiple, overwrite_prompt, file_must_exist):
+        """
+        Bring up a dialog for selecting filenames.
+
+        @param title: Message to show on the dialog
+        @param default_dir: the default directory, or the empty string
+        @param default_file: the default filename, or the empty string
+        @param wildcard: a list of tuples describing the filters used by the
+            dialog.  Such a tuple constists of a description and a fileter.
+            Example: [('PNG Files', '*.png'), ('JPEG Files', '*.jpg')]
+            If no wildcard is given, all files will match (*.*)
+        @param mode: Is this dialog an open- or a save-dialog.  If mode is
+            'save' it is a save dialog, everything else would be an
+            open-dialog.
+        @param multiple: for open-dialog only: if True, allows selecting
+            multiple files
+        @param overwrite_prompt: for save-dialog only: if True, prompt for a
+            confirmation if a file will be overwritten
+        @param file_must_exist: if True, the user may only select files that
+            actually exist
+
+        @returns: a sequence of filenames or None if the dialog has been
+            cancelled.
+        """
+
+        defname = ''
+        if default_dir or default_file:
+            defname = os.path.join(default_dir, default_file)
+
+        while True:
+            filename = self.ask(u_("Filename"), defname)
+            if mode.lower().startswith('save'):
+                if os.path.exists(filename) and overwrite_prompt:
+                    ovw = self.ask(u_("File '%s' already exists. Overwrite") \
+                            % filename, u_("n"), [u_("y"), u_("n")])
+                    if ovw == u_("y"):
+                        break
+                else:
+                    break
+            else:
+                if file_must_exist and not os.path.exists(filename):
+                    self.ask(u_("File '%s' does not exist.") % filename, "",
+                            [chr(10)])
+                else:
+                    break
+
+        if filename:
+            result = [filename]
+        else:
+            result = None
+
+        return result
+
+    # -------------------------------------------------------------------------
     # Output a message on the status bar
     # -------------------------------------------------------------------------
 
@@ -367,7 +427,81 @@
         except curses.error:
             pass
 
+    # -------------------------------------------------------------------------
+    # Ask the user a question
+    # -------------------------------------------------------------------------
 
+    def ask(self, label, default, opts=[]):
+
+        (y, x) = self.__window.getmaxyx()
+        win = curses.newwin(2, x, y-2, 0)
+        win.keypad(1)
+        win.bkgd(' ', self._uiDriver.attr['status'])
+
+        text = label
+        if opts == [chr(10)]:
+            opts = []
+            text += " " + u_("Hit <Return> to continue.")
+        else:
+            if opts:
+                text += " (%s)" % ",".join(opts)
+            text += ":"
+
+        win.addstr(0, 1, text)
+        win.refresh()
+
+        while True:
+            answer = self.__accept(win, default, len(text) + 2, 0,
+                x - len(text) - 3, x, y)
+
+            if (answer is None) or (opts and answer in opts) or (not opts):
+                break
+
+        return answer
+
+
+    # -------------------------------------------------------------------------
+    # Get a string from keyboard input
+    # -------------------------------------------------------------------------
+
+    def __accept(self, window, default, x, y, maxlen, wx, wy):
+
+        result = default
+        old = curses.curs_set(1)
+        try:
+            gDebug(2, "x/y= %s/%s" % (x, y))
+            window.move(y, x)
+            pos = len(result)
+
+            while True:
+                txt = result.ljust(maxlen)[:maxlen]
+                window.addstr(y, x, txt, self._uiDriver.attr['focusentry'])
+                window.move(y, x + pos)
+                window.refresh()
+                key = self._uiDriver.get_key(window)
+                gDebug(2, "KEY=%r" % key)
+                if isinstance(key, basestring):
+                    if key == chr(27):
+                        result = ''
+                        break
+                    elif key == chr(10):
+                        break
+                    else:
+                        if len(result) < maxlen:
+                            result += key
+                            pos += 1
+                elif key == curses.KEY_BACKSPACE:
+                    if len(result) > 0:
+                        result = result[:-1]
+                        pos -= 1
+
+        finally:
+            curses.curs_set(old)
+
+        return result
+
+
+
 # =============================================================================
 # Configuration data
 # =============================================================================

Modified: trunk/gnue-forms/src/uidrivers/curses/widgets/page.py
===================================================================
--- trunk/gnue-forms/src/uidrivers/curses/widgets/page.py       2007-02-28 
14:10:07 UTC (rev 9419)
+++ trunk/gnue-forms/src/uidrivers/curses/widgets/page.py       2007-03-01 
14:48:39 UTC (rev 9420)
@@ -158,7 +158,7 @@
         except curses.error:
             pass
 
-        return self.__get_key()
+        return self._uiDriver.get_key(self.__window)
 
 
     # -------------------------------------------------------------------------
@@ -180,50 +180,6 @@
 
 
     # -------------------------------------------------------------------------
-
-    def __get_next_key(self):
-
-        # In nodelay mode the result of getch() is -1 if there is no input.
-        # This appears to be returned after a window resize (RESIZE event) too.
-        code = -1
-        while code < 0:
-            code = self.__window.getch()
-
-        return code
-
-    # -------------------------------------------------------------------------
-
-    def __get_hibits(self, value):
-        """ Returns the number of set bits starting at the MSB """
-
-        result = 0
-        for i in range(7, -1, -1):
-            if value & (1 << i):
-                result += 1
-            else:
-                break
-
-        return result
-
-    # -------------------------------------------------------------------------
-
-    def __get_key(self):
-
-        key = self.__get_next_key()
-
-        # Function keys are returned as key-code
-        if key > 255:
-            return key
-
-        result = [key]
-        if i18n.encoding.startswith('utf'):
-            for i in range(self.__get_hibits(key)-1):
-                result.append(self.__get_next_key())
-
-        return unicode("".join([chr(i) for i in result]), i18n.encoding)
-
-
-    # -------------------------------------------------------------------------
     # Virtual methods
     # -------------------------------------------------------------------------
 





reply via email to

[Prev in Thread] Current Thread [Next in Thread]