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
This commit is contained in:
		
						commit
						278a72d461
					
				| @ -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 | ||||
|  | ||||
| @ -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,16 +264,62 @@ 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): | ||||
|         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: | ||||
|             text = str(val) | ||||
| 
 | ||||
|         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: | ||||
|             return True | ||||
|         if other.qid == 0: | ||||
|             return False | ||||
|         if self.text() == other.text(): | ||||
|             return self.name < other.name | ||||
|         return super(VMPropertyItem, self).__lt__(other) | ||||
| 
 | ||||
| 
 | ||||
| class VmTemplateItem(VMPropertyItem): | ||||
|     def __init__(self, vm): | ||||
|         super(VmTemplateItem, self).__init__(vm, "template") | ||||
| 
 | ||||
|     def update(self): | ||||
|         if getattr(self.vm, 'template', None) is not None: | ||||
|             self.setText(self.vm.template.name) | ||||
| @ -302,68 +331,14 @@ class VmTemplateItem(QtGui.QTableWidgetItem): | ||||
| 
 | ||||
|             self.setText(self.vm.klass) | ||||
| 
 | ||||
|     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(VmTemplateItem, self).__lt__(other) | ||||
| 
 | ||||
| 
 | ||||
| class VmNetvmItem(QtGui.QTableWidgetItem): | ||||
| class VmInternalItem(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(VmInternalItem, self).__init__(vm, None) | ||||
| 
 | ||||
|     def update(self): | ||||
|         if getattr(self.vm, 'netvm', None) is None: | ||||
|             self.setText("n/a") | ||||
|         else: | ||||
|             if self.vm.property_is_default('netvm'): | ||||
|                 text = 'default (' + self.vm.netvm.name +')' | ||||
|             else: | ||||
|                 text = self.vm.netvm.name | ||||
|             self.setText(text) | ||||
| 
 | ||||
|     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) | ||||
| 
 | ||||
| 
 | ||||
| class VmInternalItem(QtGui.QTableWidgetItem): | ||||
|     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() | ||||
| 
 | ||||
|     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() | ||||
| class VmLastBackupItem(VMPropertyItem): | ||||
|     def __init__(self, vm, property_name): | ||||
|         super(VmLastBackupItem, self).__init__(vm, property_name) | ||||
| 
 | ||||
|     def update(self): | ||||
|         self.ip = getattr(self.vm, 'ip', None) | ||||
|         self.setText(self.ip if self.ip is not None else 'n/a') | ||||
|         backup_timestamp = getattr(self.vm, 'backup_timestamp', None) | ||||
| 
 | ||||
|     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() | ||||
| 
 | ||||
|     def update(self): | ||||
|         self.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 | ||||
|  | ||||
| @ -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"/> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Marek Marczykowski-Górecki
						Marek Marczykowski-Górecki