[node-patches] Change in ovirt-node[master]: ui: Add multi-select support for ui.Table

fabiand at fedoraproject.org fabiand at fedoraproject.org
Mon Jan 28 17:34:52 UTC 2013


Fabian Deutsch has uploaded a new change for review.

Change subject: ui: Add multi-select support for ui.Table
......................................................................

ui: Add multi-select support for ui.Table

Change-Id: Idce172f5b07cacb09e594c6083225373eab8d490
Signed-off-by: Fabian Deutsch <fabiand at fedoraproject.org>
---
M scripts/tui/src/ovirt/node/installer/installation_device_page.py
M scripts/tui/src/ovirt/node/ui/__init__.py
M scripts/tui/src/ovirt/node/ui/urwid_builder.py
M scripts/tui/src/ovirt/node/ui/widgets.py
4 files changed, 89 insertions(+), 21 deletions(-)


  git pull ssh://gerrit.ovirt.org:29418/ovirt-node refs/changes/73/11473/1

diff --git a/scripts/tui/src/ovirt/node/installer/installation_device_page.py b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
index 5bfe8aa..3ea1355 100644
--- a/scripts/tui/src/ovirt/node/installer/installation_device_page.py
+++ b/scripts/tui/src/ovirt/node/installer/installation_device_page.py
@@ -41,7 +41,7 @@
         if devices:
             first_dev = devices[0][0]
             self._model["label.details"] = first_dev
-            self._model["installation.device"] = first_dev
+            #self._model["installation.device"] = first_dev
         return self._model
 
     def validators(self):
@@ -57,7 +57,8 @@
 
         if devices:
             ws += [ui.Table("installation.device", "", " %6s  %11s  %5s" %
-                            ("Location", "Device Name", "Size"), devices),
+                            ("Location", "Device Name", "Size"), devices,
+                            multi=True),
                    DeviceDetails("label.details", "(No device)")
                    ]
         else:
@@ -83,9 +84,13 @@
 
     def on_change(self, changes):
         if changes.contains_any(["installation.device"]):
+            highlighted_device = changes["installation.device"]
+            all_selected_devices = self.widgets["installation.device"].selection()
+            self.logger.debug("devices: %s" % all_selected_devices)
             self._model.update(changes)
             w = self.widgets["label.details"]
-            w.set_device(changes["installation.device"])
+            if highlighted_device:
+                w.set_device(highlighted_device)
 
     def on_merge(self, effective_changes):
         changes = self.pending_changes(False)
diff --git a/scripts/tui/src/ovirt/node/ui/__init__.py b/scripts/tui/src/ovirt/node/ui/__init__.py
index 58a0dbb..818bb71 100644
--- a/scripts/tui/src/ovirt/node/ui/__init__.py
+++ b/scripts/tui/src/ovirt/node/ui/__init__.py
@@ -421,33 +421,66 @@
 
 class Table(InputElement):
     """Represents a simple Table with one column
-
-    Args:
-        header: A string
-        items: A list of tuples (key, label)
-        height: The height of the Table
     """
     on_activate = None
 
     def __init__(self, path, label, header, items, selected_item=None,
-                 height=5, enabled=True):
+                 height=5, enabled=True, multi=False):
+        """Args:
+        path: The model path to map to
+        label: An optional label
+        header: The header above the cells, can be used to name the rows)
+        items: A list of tuples (key, label) (both str like)
+        height: The height of the Table
+        selected_item: The item (key) which shall be selected initially
+        enabled: Whether the table can be changed or not
+        multi: Whether we allow multiple items to be selected
+        """
         super(Table, self).__init__(path, enabled)
         self.label = label
         self.header = header
         self.items = items
         self.height = height
-        self.select(selected_item or items[0][0])
+        self.multi = multi
         self.on_activate = self.new_signal()
-        self.on_activate.connect(SaveAction())
+        if multi:
+            self.selection(selected_item or [])
+            self.on_activate.connect(ChangeAction())
+        else:
+            self.selection(selected_item or items[0][0])
+            self.on_activate.connect(ChangeAction())
+            self.on_activate.connect(SaveAction())
 
-    def select(self, selected=None):
+    def selection(self, selected=None):
+        """Get/Select the given item (key) or multiple items if multi
+
+        Args:
+            selected: The item key to be selected
+        Returns:
+            The select item key or a list of keys which are selected
+        """
+        if self.multi:
+            return self.__selection_multi(selected)
+        return self.__selection(selected)
+
+    def __selection(self, selected=None):
         if selected in dict(self.items).keys():
             self.on_value_change(selected)
             self._selected = selected
         return self._selected
 
+    def __selection_multi(self, selected=None):
+        if type(selected) in [list, str, unicode]:
+            if type(selected) in [str, unicode]:
+                # for convenience create a list for single strings
+                selected = [selected]
+            self.on_value_change(selected)
+            self._selected = set([k for k in selected
+                                  if k in dict(self.items).keys()])
+        return list(self._selected)
+
     def value(self, value=None):
-        self.select(value)
+        return self.selection(value)
 
 
 class Window(Element):
diff --git a/scripts/tui/src/ovirt/node/ui/urwid_builder.py b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
index c8ed4f3..20ca2c8 100644
--- a/scripts/tui/src/ovirt/node/ui/urwid_builder.py
+++ b/scripts/tui/src/ovirt/node/ui/urwid_builder.py
@@ -227,31 +227,36 @@
 
     def _build_table(self, ui_table):
         children = []
+
         selected = None
         for key, label in ui_table.items:
             c = self._build_tableitem(ui_table, key, label)
             children.append(c)
-            if key == ui_table.select():
+            if key == ui_table.selection():
                 selected = c
+
         widget = uw.TableWidget(ui_table.label, ui_table.header,
                                 children, selected,
                                 ui_table.height, ui_table.enabled())
 
         def on_change_cb(w, d=None):
             ui_table.on_change({ui_table.path: w._key})
-            ui_table.select(w._key)
+            if ui_table.multi:
+                ui_table.selection(widget.selection())
+            else:
+                ui_table.selection(w._key)
 
         urwid.connect_signal(widget, "changed", on_change_cb)
 
         return widget
 
     def _build_tableitem(self, ui_table, key, label):
-        c = uw.TableEntryWidget(label)
+        c = uw.TableEntryWidget(label, multi=ui_table.multi)
         c._key = key
 
         def on_activate_cb(w, data):
             ui_table.on_change({ui_table.path: w._key})
-            ui_table.on_activate()
+            ui_table.on_activate({ui_table.path: w._key})
 
         urwid.connect_signal(c, "activate", on_activate_cb)
         return c
diff --git a/scripts/tui/src/ovirt/node/ui/widgets.py b/scripts/tui/src/ovirt/node/ui/widgets.py
index 82825f0..faee564 100644
--- a/scripts/tui/src/ovirt/node/ui/widgets.py
+++ b/scripts/tui/src/ovirt/node/ui/widgets.py
@@ -44,9 +44,13 @@
     _text = None
 
     signals = ["activate"]
+    checkboxes = {True: "[x] ",
+                  False: "[ ] "}
 
-    def __init__(self, title):
-        self._text = SelectableText(title)
+    def __init__(self, title, multi=False):
+        self.multi = multi
+        self.title = title
+        self._text = self.__build_child()
 #        self._text = Button(title)
 #        self._text.button_left = ""
 #        self._text.button_right = ""
@@ -55,15 +59,32 @@
 
     def keypress(self, size, key):
         if urwid.Button._command_map[key] == 'activate':
-            self._emit('activate', None)
+            self.__handle_activate()
         return key
 
     def mouse_event(self, size, event, button, x, y, focus):
         if button != 1 or not urwid.util.is_mouse_press(event):
             return False
 
-        self._emit('activate', self)
+        self.__handle_activate()
         return True
+
+    def is_selected(self):
+        return self._text.text.startswith(self.checkboxes[True])
+
+    def __build_child(self):
+        title = "%s" % self.title
+        if self.multi:
+            title = "%s%s" % (self.checkboxes[False], self.title)
+        self._text = SelectableText(title)
+        return self._text
+
+    def __handle_activate(self):
+        if self.multi:
+            is_checked = self.is_selected()
+            new_text = "%s%s" % (self.checkboxes[not is_checked], self.title)
+            self._text.set_text(new_text)
+        self._emit('activate', self)
 
 
 class TableWidget(urwid.WidgetWrap):
@@ -125,6 +146,10 @@
     def set_focus(self, n):
         self.__list.set_focus(n)
 
+    def selection(self):
+        selection = [w._key for w in self.__items if w.is_selected()]
+        return selection
+
 
 class PluginMenuEntry(TableEntryWidget):
     def __init__(self, title, plugin):


--
To view, visit http://gerrit.ovirt.org/11473
To unsubscribe, visit http://gerrit.ovirt.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: Idce172f5b07cacb09e594c6083225373eab8d490
Gerrit-PatchSet: 1
Gerrit-Project: ovirt-node
Gerrit-Branch: master
Gerrit-Owner: Fabian Deutsch <fabiand at fedoraproject.org>



More information about the node-patches mailing list