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:
Marek Marczykowski-Górecki 2019-04-04 01:26:03 +02:00
commit 278a72d461
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
3 changed files with 151 additions and 176 deletions

View File

@ -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

View File

@ -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

View File

@ -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"/>