Ver código fonte

Merge remote-tracking branch 'origin/pr/167'

* origin/pr/167:
  More documentation and added another column for default_dispvm to Qube Manager
  Added DVM Template column to Qube Manager
  Rewritten Qube Manager widgets
Marek Marczykowski-Górecki 5 anos atrás
pai
commit
278a72d461
3 arquivos alterados com 143 adições e 168 exclusões
  1. 43 16
      qubesmanager/qube_manager.py
  2. 53 149
      qubesmanager/table_widgets.py
  3. 47 3
      ui/qubemanager.ui

+ 43 - 16
qubesmanager/qube_manager.py

@@ -75,9 +75,6 @@ class VmRowInTable:
     # pylint: disable=too-few-public-methods
     def __init__(self, vm, row_no, table):
         self.vm = vm
-        # TODO: replace a various different widgets with a more generic
-        # VmFeatureWidget or VMPropertyWidget
-
 
         table_widgets.row_height = VmManagerWindow.row_height
         table.setRowHeight(row_no, VmManagerWindow.row_height)
@@ -94,7 +91,7 @@ class VmRowInTable:
         table.setItem(row_no, VmManagerWindow.columns_indices['Label'],
                       self.label_widget.table_item)
 
-        self.name_widget = table_widgets.VmNameItem(vm)
+        self.name_widget = table_widgets.VMPropertyItem(vm, "name")
         table.setItem(row_no, VmManagerWindow.columns_indices['Name'],
                       self.name_widget)
 
@@ -108,7 +105,8 @@ class VmRowInTable:
         table.setItem(row_no, VmManagerWindow.columns_indices['Template'],
                       self.template_widget)
 
-        self.netvm_widget = table_widgets.VmNetvmItem(vm)
+        self.netvm_widget = table_widgets.VMPropertyItem(vm, "netvm",
+                                                         check_default=True)
         table.setItem(row_no, VmManagerWindow.columns_indices['NetVM'],
                       self.netvm_widget)
 
@@ -120,19 +118,32 @@ class VmRowInTable:
         table.setItem(row_no, VmManagerWindow.columns_indices['Internal'],
                       self.internal_widget)
 
-        self.ip_widget = table_widgets.VmIPItem(vm)
+        self.ip_widget = table_widgets.VMPropertyItem(vm, "ip")
         table.setItem(row_no, VmManagerWindow.columns_indices['IP'],
                       self.ip_widget)
 
-        self.include_in_backups_widget = \
-            table_widgets.VmIncludeInBackupsItem(vm)
+        self.include_in_backups_widget = table_widgets.VMPropertyItem(
+            vm, "include_in_backups",
+            empty_function=(lambda x: not bool(x)))
         table.setItem(row_no, VmManagerWindow.columns_indices[
-            'Backups'], self.include_in_backups_widget)
+            'Include in backups'], self.include_in_backups_widget)
 
-        self.last_backup_widget = table_widgets.VmLastBackupItem(vm)
+        self.last_backup_widget = table_widgets.VmLastBackupItem(
+            vm, "backup_timestamp")
         table.setItem(row_no, VmManagerWindow.columns_indices[
             'Last backup'], self.last_backup_widget)
 
+        self.dvm_template_widget = table_widgets.VMPropertyItem(
+            vm, "default_dispvm")
+        table.setItem(row_no, VmManagerWindow.columns_indices['Default DispVM'],
+                      self.dvm_template_widget)
+
+        self.is_dispvm_template_widget = table_widgets.VMPropertyItem(
+            vm, "template_for_dispvms", empty_function=(lambda x: not x))
+        table.setItem(
+            row_no, VmManagerWindow.columns_indices['Is DVM Template'],
+            self.is_dispvm_template_widget)
+
         self.table = table
 
     def update(self, update_size_on_disk=False, event=None):
@@ -160,6 +171,10 @@ class VmRowInTable:
                 self.include_in_backups_widget.update()
             if not event or event.endswith(':backup_timestamp'):
                 self.last_backup_widget.update()
+            if not event or event.endswith(':default_dispvm'):
+                self.dvm_template_widget.update()
+            if not event or event.endswith(':template_for_dispvms'):
+                self.is_dispvm_template_widget.update()
             if update_size_on_disk:
                 self.size_widget.update()
         except exc.QubesPropertyAccessError:
@@ -331,8 +346,10 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
                        "Size": 6,
                        "Internal": 7,
                        "IP": 8,
-                       "Backups": 9,
+                       "Include in backups": 9,
                        "Last backup": 10,
+                       "Default DispVM": 11,
+                       "Is DVM Template": 12
                       }
 
     def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
@@ -373,10 +390,11 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
             self.columns_indices["NetVM"]: self.action_netvm,
             self.columns_indices["Size"]: self.action_size_on_disk,
             self.columns_indices["Internal"]: self.action_internal,
-            self.columns_indices["IP"]: self
-                .action_ip, self.columns_indices["Backups"]: self
-                .action_backups, self.columns_indices["Last backup"]: self
-            .action_last_backup
+            self.columns_indices["IP"]: self.action_ip,
+            self.columns_indices["Include in backups"]: self.action_backups,
+            self.columns_indices["Last backup"]: self.action_last_backup,
+            self.columns_indices["Default DispVM"]: self.action_dispvm_template,
+            self.columns_indices["Is DVM Template"]: self.action_is_dvm_template
         }
 
         self.visible_columns_count = len(self.columns_indices)
@@ -1173,7 +1191,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
         self.showhide_column(self.columns_indices['IP'], checked)
 
     def on_action_backups_toggled(self, checked):
-        self.showhide_column(self.columns_indices['Backups'], checked)
+        self.showhide_column(
+            self.columns_indices['Include in backups'], checked)
 
     def on_action_last_backup_toggled(self, checked):
         self.showhide_column(self.columns_indices['Last backup'], checked)
@@ -1187,6 +1206,14 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
     def on_action_size_on_disk_toggled(self, checked):
         self.showhide_column(self.columns_indices['Size'], checked)
 
+    # pylint: disable=invalid-name
+    def on_action_dispvm_template_toggled(self, checked):
+        self.showhide_column(self.columns_indices['Default DispVM'], checked)
+
+    # pylint: disable=invalid-name
+    def on_action_is_dvm_template_toggled(self, checked):
+        self.showhide_column(self.columns_indices['Is DVM Template'], checked)
+
     # noinspection PyArgumentList
     @QtCore.pyqtSlot(name='on_action_about_qubes_triggered')
     def action_about_qubes_triggered(self):  # pylint: disable=no-self-use

+ 53 - 149
qubesmanager/table_widgets.py

@@ -71,7 +71,6 @@ class VmIconWidget(QtGui.QWidget):
         self.label_icon.setFixedSize(icon_sz)
 
 
-
 class VmTypeWidget(VmIconWidget):
     class VmTypeItem(QtGui.QTableWidgetItem):
         def __init__(self, value, vm):
@@ -160,22 +159,6 @@ class VmLabelWidget(VmIconWidget):
             self.set_icon(icon_path)
 
 
-class VmNameItem(QtGui.QTableWidgetItem):
-    def __init__(self, vm):
-        super(VmNameItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-        self.setText(vm.name)
-        self.setTextAlignment(QtCore.Qt.AlignVCenter)
-        self.qid = vm.qid
-
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        return super(VmNameItem, self).__lt__(other)
-
-
 class VmStatusIcon(QtGui.QLabel):
     def __init__(self, vm, parent=None):
         super(VmStatusIcon, self).__init__(parent)
@@ -281,26 +264,47 @@ class VmInfoWidget(QtGui.QWidget):
         self.upd_info.update_outdated()
 
 
-class VmTemplateItem(QtGui.QTableWidgetItem):
-    def __init__(self, vm):
-        super(VmTemplateItem, self).__init__()
+class VMPropertyItem(QtGui.QTableWidgetItem):
+    def __init__(self, vm, property_name, empty_function=(lambda x: False),
+                 check_default=False):
+        """
+        Class used to represent Qube Manager table widget.
+        :param vm: vm object
+        :param property_name: name of the property the widget represents
+        :param empty_function: a function that, when applied to values of
+        vm.property_name, returns True when the property value should be
+        represented as an empty string and False otherwise; by default this
+        function always returns false (vm.property_name is represented by an
+        empty string only when it actually is one)
+        :param check_default: if True, the widget will prepend its text with
+        "default" if the if the property is set to DEFAULT
+        """
+        super(VMPropertyItem, self).__init__()
         self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
+        self.setTextAlignment(QtCore.Qt.AlignVCenter)
         self.vm = vm
         self.qid = vm.qid
+        self.property_name = property_name
         self.name = vm.name
-        self.setTextAlignment(QtCore.Qt.AlignVCenter)
+        self.empty_function = empty_function
+        self.check_default = check_default
         self.update()
 
     def update(self):
-        if getattr(self.vm, 'template', None) is not None:
-            self.setText(self.vm.template.name)
+        val = getattr(self.vm, self.property_name, None)
+        if self.empty_function(val):
+            text = ""
+        elif val is None:
+            text = "n/a"
+        elif val is True:
+            text = "Yes"
         else:
-            font = QtGui.QFont()
-            font.setStyle(QtGui.QFont.StyleItalic)
-            self.setFont(font)
-            self.setTextColor(QtGui.QColor("gray"))
+            text = str(val)
 
-            self.setText(self.vm.klass)
+        if self.check_default and hasattr(self.vm, self.property_name) and \
+                self.vm.property_is_default(self.property_name):
+            text = 'default (' + text + ')'
+        self.setText(text)
 
     def __lt__(self, other):
         if self.qid == 0:
@@ -309,61 +313,32 @@ class VmTemplateItem(QtGui.QTableWidgetItem):
             return False
         if self.text() == other.text():
             return self.name < other.name
-        return super(VmTemplateItem, self).__lt__(other)
+        return super(VMPropertyItem, self).__lt__(other)
 
 
-class VmNetvmItem(QtGui.QTableWidgetItem):
+class VmTemplateItem(VMPropertyItem):
     def __init__(self, vm):
-        super(VmNetvmItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-        self.vm = vm
-        self.qid = vm.qid
-        self.name = vm.name
-        self.setTextAlignment(QtCore.Qt.AlignVCenter)
-        self.update()
+        super(VmTemplateItem, self).__init__(vm, "template")
 
     def update(self):
-        if getattr(self.vm, 'netvm', None) is None:
-            self.setText("n/a")
+        if getattr(self.vm, 'template', None) is not None:
+            self.setText(self.vm.template.name)
         else:
-            if self.vm.property_is_default('netvm'):
-                text = 'default (' + self.vm.netvm.name +')'
-            else:
-                text = self.vm.netvm.name
-            self.setText(text)
+            font = QtGui.QFont()
+            font.setStyle(QtGui.QFont.StyleItalic)
+            self.setFont(font)
+            self.setTextColor(QtGui.QColor("gray"))
 
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        if self.text() == other.text():
-            return self.name < other.name
-        return super(VmNetvmItem, self).__lt__(other)
+            self.setText(self.vm.klass)
 
 
-class VmInternalItem(QtGui.QTableWidgetItem):
+class VmInternalItem(VMPropertyItem):
     def __init__(self, vm):
-        super(VmInternalItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-
-        self.vm = vm
-        self.qid = vm.qid
-        self.name = vm.name
-        self.update()
+        super(VmInternalItem, self).__init__(vm, None)
 
     def update(self):
-        self.internal = self.vm.features.get('internal', False)
-        self.setText("Yes" if self.internal else "")
-
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        if self.internal == other.internal:
-            return self.name < other.name
-        return super(VmInternalItem, self).__lt__(other)
+        internal = self.vm.features.get('internal', False)
+        self.setText("Yes" if internal else "")
 
 
 # features man qvm-features
@@ -474,6 +449,7 @@ class VmUpdateInfoWidget(QtGui.QWidget):
                         alignment=QtCore.Qt.AlignCenter)
                 self.icon.setVisible(True)
 
+
 class VmSizeOnDiskItem(QtGui.QTableWidgetItem):
     def __init__(self, vm):
         super(VmSizeOnDiskItem, self).__init__()
@@ -504,87 +480,15 @@ class VmSizeOnDiskItem(QtGui.QTableWidgetItem):
         return self.value < other.value
 
 
-class VmIPItem(QtGui.QTableWidgetItem):
-    def __init__(self, vm):
-        super(VmIPItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-
-        self.vm = vm
-        self.qid = vm.qid
-        self.name = vm.name
-        self.update()
-
-    def update(self):
-        self.ip = getattr(self.vm, 'ip', None)
-        self.setText(self.ip if self.ip is not None else 'n/a')
-
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        if self.ip == other.ip:
-            return self.name < other.name
-        return super(VmIPItem, self).__lt__(other)
-
-
-class VmIncludeInBackupsItem(QtGui.QTableWidgetItem):
-    def __init__(self, vm):
-        super(VmIncludeInBackupsItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-
-        self.vm = vm
-        self.name = vm.name
-        self.qid = vm.qid
-        self.update()
-
-    def update(self):
-        if getattr(self.vm, 'include_in_backups', None):
-            self.setText("Yes")
-            self.include_in_backups = True
-        else:
-            self.setText("")
-            self.include_in_backups = False
-
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        if self.include_in_backups == other.include_in_backups:
-            return self.name < other.name
-        return self.include_in_backups < other.include_in_backups
-
-
-class VmLastBackupItem(QtGui.QTableWidgetItem):
-    def __init__(self, vm):
-        super(VmLastBackupItem, self).__init__()
-        self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
-
-        self.vm = vm
-        self.qid = vm.qid
-        self.name = vm.name
-        self.update()
+class VmLastBackupItem(VMPropertyItem):
+    def __init__(self, vm, property_name):
+        super(VmLastBackupItem, self).__init__(vm, property_name)
 
     def update(self):
-        self.backup_timestamp = getattr(self.vm, 'backup_timestamp', None)
+        backup_timestamp = getattr(self.vm, 'backup_timestamp', None)
 
-        if self.backup_timestamp:
+        if backup_timestamp:
             self.setText(
-                str(datetime.datetime.fromtimestamp(self.backup_timestamp)))
+                str(datetime.datetime.fromtimestamp(backup_timestamp)))
         else:
             self.setText("")
-
-    #pylint: disable=too-many-return-statements
-    def __lt__(self, other):
-        if self.qid == 0:
-            return True
-        if other.qid == 0:
-            return False
-        if self.backup_timestamp == other.backup_timestamp:
-            return self.name < other.name
-        if not self.backup_timestamp:
-            return False
-        if not other.backup_timestamp:
-            return True
-        return self.backup_timestamp < other.backup_timestamp

+ 47 - 3
ui/qubemanager.ui

@@ -136,7 +136,7 @@
        <number>10</number>
       </property>
       <property name="columnCount">
-       <number>11</number>
+       <number>13</number>
       </property>
       <attribute name="horizontalHeaderCascadingSectionResizes">
        <bool>false</bool>
@@ -211,7 +211,8 @@
       </column>
       <column>
        <property name="text">
-        <string>Disk usage</string>
+        <string>Disk
+usage</string>
        </property>
       </column>
       <column>
@@ -226,7 +227,8 @@
       </column>
       <column>
        <property name="text">
-        <string>Backups</string>
+        <string>Include
+in backups</string>
        </property>
       </column>
       <column>
@@ -234,6 +236,18 @@
         <string>Last backup</string>
        </property>
       </column>
+      <column>
+       <property name="text">
+        <string>Default
+DisposableVM</string>
+       </property>
+      </column>
+      <column>
+       <property name="text">
+        <string>Is template for 
+DisposableVMs</string>
+       </property>
+      </column>
      </widget>
     </item>
    </layout>
@@ -276,6 +290,8 @@
     <addaction name="action_ip"/>
     <addaction name="action_backups"/>
     <addaction name="action_last_backup"/>
+    <addaction name="action_dispvm_template"/>
+    <addaction name="action_is_dvm_template"/>
     <addaction name="separator"/>
     <addaction name="action_toolbar"/>
     <addaction name="action_menubar"/>
@@ -830,6 +846,34 @@
     <string>Launch a tool that allows multiple templates to be changed at once</string>
    </property>
   </action>
+  <action name="action_dispvm_template">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Default DisposableVMs</string>
+   </property>
+   <property name="toolTip">
+    <string>Default DisposableVMs</string>
+   </property>
+  </action>
+  <action name="action_is_dvm_template">
+   <property name="checkable">
+    <bool>true</bool>
+   </property>
+   <property name="checked">
+    <bool>true</bool>
+   </property>
+   <property name="text">
+    <string>Is Template for DisposableVMs</string>
+   </property>
+   <property name="toolTip">
+    <string>Is Template for DisposableVMs</string>
+   </property>
+  </action>
  </widget>
  <resources>
   <include location="../resources.qrc"/>