Merge remote-tracking branch 'qubesos/pr/91'

* qubesos/pr/91: (27 commits)
  Fix long line warning
  Pretty confusion with regex trying to make  travis happy
  Added exceptions for domain add and remove
  Fix pylint and travis errors
  Fix misspelling on Updates Timer() and better timeout
  Added missing updates() method for some widget
  Fix missing template updates-available
  Added startup progress dialog
  More elegant fix for settings size
  Removed debug print
  Outdated state cleanup
  Revert "Removed progress wait when updating template"
  This tries to fix some rare case when it stops receieving dbus events
  Added Timer for template updates
  Refresh table selection when pause/resume
  Added calls to table_selection_changed()
  VmRowInTable dbus events moved to VmManagerWindow
  Set settings dialog to minimun size, it gets adjusted properly to good view
  - Removed unnedeed calls to vms_in_table[vm.qid].update()
  - Removed update_single_row() and add direct calls to update()  (Some of them could be deleted since dbus events will handle them)
  ...
This commit is contained in:
Marek Marczykowski-Górecki 2018-05-22 03:30:21 +02:00
commit 5b752fc55b
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
4 changed files with 196 additions and 121 deletions

View File

@ -29,6 +29,9 @@ import subprocess
import time import time
from datetime import datetime, timedelta from datetime import datetime, timedelta
import traceback import traceback
import threading
from pydbus import SessionBus
from qubesadmin import Qubes from qubesadmin import Qubes
from qubesadmin import exc from qubesadmin import exc
@ -36,6 +39,8 @@ from qubesadmin import exc
from PyQt4 import QtGui # pylint: disable=import-error from PyQt4 import QtGui # pylint: disable=import-error
from PyQt4 import QtCore # pylint: disable=import-error from PyQt4 import QtCore # pylint: disable=import-error
from qubesmanager.about import AboutDialog
from . import ui_qubemanager # pylint: disable=no-name-in-module from . import ui_qubemanager # pylint: disable=no-name-in-module
from . import thread_monitor from . import thread_monitor
from . import table_widgets from . import table_widgets
@ -44,9 +49,6 @@ from . import global_settings
from . import restore from . import restore
from . import backup from . import backup
from . import log_dialog from . import log_dialog
import threading
from qubesmanager.about import AboutDialog
class SearchBox(QtGui.QLineEdit): class SearchBox(QtGui.QLineEdit):
@ -68,13 +70,12 @@ class SearchBox(QtGui.QLineEdit):
class VmRowInTable(object): class VmRowInTable(object):
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
def __init__(self, vm, row_no, table): def __init__(self, vm, row_no, table):
self.vm = vm self.vm = vm
self.row_no = row_no
# TODO: replace a various different widgets with a more generic # TODO: replace a various different widgets with a more generic
# VmFeatureWidget or VMPropertyWidget # VmFeatureWidget or VMPropertyWidget
table_widgets.row_height = VmManagerWindow.row_height table_widgets.row_height = VmManagerWindow.row_height
table.setRowHeight(row_no, VmManagerWindow.row_height) table.setRowHeight(row_no, VmManagerWindow.row_height)
@ -129,6 +130,8 @@ class VmRowInTable(object):
table.setItem(row_no, VmManagerWindow.columns_indices[ table.setItem(row_no, VmManagerWindow.columns_indices[
'Last backup'], self.last_backup_widget) 'Last backup'], self.last_backup_widget)
self.table = table
def update(self, update_size_on_disk=False): def update(self, update_size_on_disk=False):
""" """
Update info in a single VM row Update info in a single VM row
@ -136,7 +139,13 @@ class VmRowInTable(object):
widget will extract the data from VM object widget will extract the data from VM object
:return: None :return: None
""" """
self.info_widget.update_vm_state(self.vm) self.info_widget.update_vm_state()
self.template_widget.update()
self.netvm_widget.update()
self.internal_widget.update()
self.ip_widget.update()
self.include_in_backups_widget.update()
self.last_backup_widget.update()
if update_size_on_disk: if update_size_on_disk:
self.size_widget.update() self.size_widget.update()
@ -363,16 +372,121 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.load_manager_settings() self.load_manager_settings()
# disabling the table for the duration of filling speeds up the process
# immensely. Yes, really.
self.table.setDisabled(True)
self.fill_table() self.fill_table()
self.table.setEnabled(True)
self.update_size_on_disk = False self.update_size_on_disk = False
self.shutdown_monitor = {} self.shutdown_monitor = {}
# Connect dbus events
self.bus = SessionBus()
manager = self.bus.get("org.qubes.DomainManager1")
manager.DomainAdded.connect(self.on_domain_added)
manager.DomainRemoved.connect(self.on_domain_removed)
manager.Failed.connect(self.on_failed)
manager.Halted.connect(self.on_halted)
manager.Halting.connect(self.on_halting)
manager.Starting.connect(self.on_starting)
manager.Started.connect(self.on_started)
# Check Updates Timer
timer = QtCore.QTimer(self)
timer.timeout.connect(self.check_updates)
timer.start(1000 * 30) # 30s
def check_updates(self):
for vm in self.qubes_app.domains:
if vm.klass == 'TemplateVM':
self.vms_in_table[vm.qid].update()
def on_domain_added(self, _, domain):
#needs to clear cache
self.qubes_app.domains.clear_cache()
qid = int(domain.split('/')[-1])
self.table.setSortingEnabled(False)
row_no = self.table.rowCount()
self.table.setRowCount(row_no + 1)
for vm in self.qubes_app.domains:
if vm.qid == qid:
vm_row = VmRowInTable(vm, row_no, self.table)
self.vms_in_table[vm.qid] = vm_row
self.table.setSortingEnabled(True)
return
# Never should reach here
raise RuntimeError('Added domain not found')
def on_domain_removed(self, _, domain):
#needs to clear cache
self.qubes_app.domains.clear_cache()
qid = int(domain.split('/')[-1])
# Find row and remove
try:
row_index = 0
vm_item = self.table.item(row_index, self.columns_indices["Name"])
while vm_item.qid != qid:
row_index += 1
vm_item = self.table.item(row_index,\
self.columns_indices["Name"])
except:
raise RuntimeError('Deleted domain not found')
self.table.removeRow(row_index)
del self.vms_in_table[qid]
def on_failed(self, _, domain):
qid = int(domain.split('/')[-1])
self.vms_in_table[qid].update()
if self.vms_in_table[qid].vm == self.get_selected_vm():
self.table_selection_changed()
def on_halted(self, _, domain):
qid = int(domain.split('/')[-1])
self.vms_in_table[qid].update()
if self.vms_in_table[qid].vm == self.get_selected_vm():
self.table_selection_changed()
# Check if is TemplatVM and update related AppVMs
starting_vm = self.vms_in_table[qid]
if starting_vm.vm.klass == 'TemplateVM':
for vm in starting_vm.vm.appvms:
if vm.klass == 'AppVM':
self.vms_in_table[vm.qid].update()
def on_halting(self, _, domain):
qid = int(domain.split('/')[-1])
self.vms_in_table[qid].update()
if self.vms_in_table[qid].vm == self.get_selected_vm():
self.table_selection_changed()
def on_started(self, _, domain):
qid = int(domain.split('/')[-1])
self.vms_in_table[qid].update()
if self.vms_in_table[qid].vm == self.get_selected_vm():
self.table_selection_changed()
def on_starting(self, _, domain):
qid = int(domain.split('/')[-1])
self.vms_in_table[qid].update()
if self.vms_in_table[qid].vm == self.get_selected_vm():
self.table_selection_changed()
# Check if is TemplatVM and update related AppVMs
starting_vm = self.vms_in_table[qid]
if starting_vm.vm.klass == 'TemplateVM':
for vm in starting_vm.vm.appvms:
if vm.klass == 'AppVM':
self.vms_in_table[vm.qid].update()
def load_manager_settings(self): def load_manager_settings(self):
# visible columns # visible columns
self.visible_columns_count = 0 self.visible_columns_count = 0
@ -403,26 +517,16 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
def get_vms_list(self): def get_vms_list(self):
return [vm for vm in self.qubes_app.domains] return [vm for vm in self.qubes_app.domains]
def update_single_row(self, vm):
# this fuction should be used to update a row that already exists
# to add a row, one needs to use the update_table function - the
# whole table needs to be redrawn (and sorted)
if vm in self.qubes_app.domains:
self.vms_in_table[vm.qid].update()
else:
self.update_table()
def fill_table(self): def fill_table(self):
# save current selection progress = QtGui.QProgressDialog(
row_index = self.table.currentRow() self.tr(
selected_qid = -1 "Loading Qube Manager..."), "", 0, 0)
if row_index != -1: progress.setWindowTitle(self.tr("Qube Manager"))
vm_item = self.table.item(row_index, self.columns_indices["Name"]) progress.setCancelButton(None)
if vm_item: progress.setModal(True)
selected_qid = vm_item.qid progress.show()
self.table.setSortingEnabled(False) self.table.setSortingEnabled(False)
self.table.clearContents()
vms_list = self.get_vms_list() vms_list = self.get_vms_list()
vms_in_table = {} vms_in_table = {}
@ -439,12 +543,9 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.vms_list = vms_list self.vms_list = vms_list
self.vms_in_table = vms_in_table self.vms_in_table = vms_in_table
if selected_qid in vms_in_table.keys():
self.table.setCurrentItem(
self.vms_in_table[selected_qid].name_widget)
self.table.setSortingEnabled(True) self.table.setSortingEnabled(True)
self.showhide_vms() progress.hide()
def showhide_vms(self): def showhide_vms(self):
if not self.search: if not self.search:
@ -467,19 +568,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
def action_search_triggered(self): def action_search_triggered(self):
self.searchbox.setFocus() self.searchbox.setFocus()
def update_table(self):
# disabling the table speeds up the process of filling it
self.table.setDisabled(True)
self.fill_table()
self.table.setEnabled(True)
# TODO: instead of manually refreshing the entire table, use dbus events
# reapply sorting
if self.sort_by_column:
self.table.sortByColumn(self.columns_indices[self.sort_by_column])
self.table_selection_changed()
# noinspection PyPep8Naming # noinspection PyPep8Naming
def sort_indicator_changed(self, column, order): def sort_indicator_changed(self, column, order):
self.sort_by_column = [name for name in self.columns_indices if self.sort_by_column = [name for name in self.columns_indices if
@ -530,8 +618,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.action_set_keyboard_layout.setEnabled( self.action_set_keyboard_layout.setEnabled(
vm.qid != 0 and vm.qid != 0 and
vm.get_power_state() != "Paused" and vm.is_running()) vm.get_power_state() != "Paused" and vm.is_running())
self.update_single_row(vm)
else: else:
self.action_settings.setEnabled(False) self.action_settings.setEnabled(False)
self.action_removevm.setEnabled(False) self.action_removevm.setEnabled(False)
@ -640,7 +726,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.tr("ERROR: {0}").format( self.tr("ERROR: {0}").format(
t_monitor.error_msg)) t_monitor.error_msg))
self.update_table()
@staticmethod @staticmethod
def do_remove_vm(vm, qubes_app, t_monitor): def do_remove_vm(vm, qubes_app, t_monitor):
@ -695,7 +780,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.tr("Exception while cloning:<br>{0}").format( self.tr("Exception while cloning:<br>{0}").format(
t_monitor.error_msg)) t_monitor.error_msg))
self.update_table()
@staticmethod @staticmethod
def do_clone_vm(src_vm, qubes_app, dst_name, t_monitor): def do_clone_vm(src_vm, qubes_app, dst_name, t_monitor):
@ -716,6 +800,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
if vm.get_power_state() in ["Paused", "Suspended"]: if vm.get_power_state() in ["Paused", "Suspended"]:
try: try:
vm.unpause() vm.unpause()
self.vms_in_table[vm.qid].update()
self.table_selection_changed()
except exc.QubesException as ex: except exc.QubesException as ex:
QtGui.QMessageBox.warning( QtGui.QMessageBox.warning(
None, self.tr("Error unpausing Qube!"), None, self.tr("Error unpausing Qube!"),
@ -723,7 +809,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
return return
self.start_vm(vm) self.start_vm(vm)
self.update_single_row(vm)
def start_vm(self, vm): def start_vm(self, vm):
if vm.is_running(): if vm.is_running():
@ -744,7 +829,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.tr("Error starting Qube!"), self.tr("Error starting Qube!"),
self.tr("ERROR: {0}").format(t_monitor.error_msg)) self.tr("ERROR: {0}").format(t_monitor.error_msg))
self.update_single_row(vm)
@staticmethod @staticmethod
def do_start_vm(vm, t_monitor): def do_start_vm(vm, t_monitor):
@ -769,7 +853,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
vm = self.get_selected_vm() vm = self.get_selected_vm()
try: try:
vm.pause() vm.pause()
self.update_single_row(vm) self.vms_in_table[vm.qid].update()
self.table_selection_changed()
except exc.QubesException as ex: except exc.QubesException as ex:
QtGui.QMessageBox.warning( QtGui.QMessageBox.warning(
None, None,
@ -794,7 +879,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
if reply == QtGui.QMessageBox.Yes: if reply == QtGui.QMessageBox.Yes:
self.shutdown_vm(vm) self.shutdown_vm(vm)
self.update_single_row(vm)
def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout, def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout,
check_time=vm_restart_check_timeout, and_restart=False): check_time=vm_restart_check_timeout, and_restart=False):
@ -835,8 +919,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
else: else:
self.start_vm(vm) self.start_vm(vm)
self.update_single_row(vm)
# noinspection PyArgumentList # noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_killvm_triggered') @QtCore.pyqtSlot(name='on_action_killvm_triggered')
def action_killvm_triggered(self): def action_killvm_triggered(self):
@ -879,7 +961,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
settings_window = settings.VMSettingsWindow( settings_window = settings.VMSettingsWindow(
vm, self.qt_app, "basic") vm, self.qt_app, "basic")
settings_window.exec_() settings_window.exec_()
self.update_single_row(vm) self.vms_in_table[vm.qid].update()
# noinspection PyArgumentList # noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_appmenus_triggered') @QtCore.pyqtSlot(name='on_action_appmenus_triggered')
@ -890,11 +972,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
vm, self.qt_app, "applications") vm, self.qt_app, "applications")
settings_window.exec_() settings_window.exec_()
# noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_refresh_list_triggered')
def action_refresh_list_triggered(self):
self.qubes_app.domains.clear_cache()
self.update_table()
# noinspection PyArgumentList # noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_updatevm_triggered') @QtCore.pyqtSlot(name='on_action_updatevm_triggered')
@ -940,7 +1017,6 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
self.tr("Error on Qube update!"), self.tr("Error on Qube update!"),
self.tr("ERROR: {0}").format(t_monitor.error_msg)) self.tr("ERROR: {0}").format(t_monitor.error_msg))
self.update_single_row(vm)
@staticmethod @staticmethod
def do_update_vm(vm, t_monitor): def do_update_vm(vm, t_monitor):
@ -1213,10 +1289,7 @@ def main():
qubes_app = Qubes() qubes_app = Qubes()
manager_window = VmManagerWindow(qt_app, qubes_app) manager_window = VmManagerWindow(qt_app, qubes_app)
manager_window.show() manager_window.show()
timer = QtCore.QTimer()
timer.singleShot(1, manager_window.update_table)
qt_app.exec_() qt_app.exec_()

View File

@ -18,10 +18,10 @@
# #
# You should have received a copy of the GNU Lesser General Public License along # You should have received a copy of the GNU Lesser General Public License along
# with this program; if not, see <http://www.gnu.org/licenses/>. # with this program; if not, see <http://www.gnu.org/licenses/>.
import datetime
from PyQt4 import QtGui # pylint: disable=import-error from PyQt4 import QtGui # pylint: disable=import-error
from PyQt4 import QtCore # pylint: disable=import-error from PyQt4 import QtCore # pylint: disable=import-error
import datetime
# pylint: disable=too-few-public-methods # pylint: disable=too-few-public-methods
power_order = QtCore.Qt.DescendingOrder power_order = QtCore.Qt.DescendingOrder
@ -110,7 +110,6 @@ class VmTypeWidget(VmIconWidget):
class VmLabelWidget(VmIconWidget): class VmLabelWidget(VmIconWidget):
class VmLabelItem(QtGui.QTableWidgetItem): class VmLabelItem(QtGui.QTableWidgetItem):
def __init__(self, value, vm): def __init__(self, value, vm):
super(VmLabelWidget.VmLabelItem, self).__init__() super(VmLabelWidget.VmLabelItem, self).__init__()
@ -254,9 +253,9 @@ class VmInfoWidget(QtGui.QWidget):
self.table_item = self.VmInfoItem(self.upd_info.table_item, vm) self.table_item = self.VmInfoItem(self.upd_info.table_item, vm)
def update_vm_state(self, vm): def update_vm_state(self):
self.on_icon.update() self.on_icon.update()
self.upd_info.update_outdated(vm) self.upd_info.update_outdated()
class VmTemplateItem(QtGui.QTableWidgetItem): class VmTemplateItem(QtGui.QTableWidgetItem):
@ -264,18 +263,19 @@ class VmTemplateItem(QtGui.QTableWidgetItem):
super(VmTemplateItem, self).__init__() super(VmTemplateItem, self).__init__()
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.setTextAlignment(QtCore.Qt.AlignVCenter)
self.update()
if getattr(vm, 'template', None) is not None: def update(self):
self.setText(vm.template.name) if getattr(self.vm, 'template', None) is not None:
self.setText(self.vm.template.name)
else: else:
font = QtGui.QFont() font = QtGui.QFont()
font.setStyle(QtGui.QFont.StyleItalic) font.setStyle(QtGui.QFont.StyleItalic)
self.setFont(font) self.setFont(font)
self.setTextColor(QtGui.QColor("gray")) self.setTextColor(QtGui.QColor("gray"))
self.setText(vm.klass) self.setText(self.vm.klass)
self.setTextAlignment(QtCore.Qt.AlignVCenter)
def __lt__(self, other): def __lt__(self, other):
if self.vm.qid == 0: if self.vm.qid == 0:
@ -292,13 +292,14 @@ class VmNetvmItem(QtGui.QTableWidgetItem):
super(VmNetvmItem, self).__init__() super(VmNetvmItem, self).__init__()
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.setTextAlignment(QtCore.Qt.AlignVCenter)
self.update()
if getattr(vm, 'netvm', None) is None: def update(self):
if getattr(self.vm, 'netvm', None) is None:
self.setText("n/a") self.setText("n/a")
else: else:
self.setText(vm.netvm.name) self.setText(self.vm.netvm.name)
self.setTextAlignment(QtCore.Qt.AlignVCenter)
def __lt__(self, other): def __lt__(self, other):
if self.vm.qid == 0: if self.vm.qid == 0:
@ -316,10 +317,13 @@ class VmInternalItem(QtGui.QTableWidgetItem):
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.internal = vm.features.get('internal', False) self.update()
def update(self):
self.internal = self.vm.features.get('internal', False)
self.setText("Yes" if self.internal else "") self.setText("Yes" if self.internal else "")
def __lt__(self, other): def __lt__(self, other):
if self.vm.qid == 0: if self.vm.qid == 0:
return True return True
@ -330,7 +334,6 @@ class VmInternalItem(QtGui.QTableWidgetItem):
# features man qvm-features # features man qvm-features
class VmUpdateInfoWidget(QtGui.QWidget): class VmUpdateInfoWidget(QtGui.QWidget):
class VmUpdateInfoItem(QtGui.QTableWidgetItem): class VmUpdateInfoItem(QtGui.QTableWidgetItem):
def __init__(self, value, vm): def __init__(self, value, vm):
super(VmUpdateInfoWidget.VmUpdateInfoItem, self).__init__() super(VmUpdateInfoWidget.VmUpdateInfoItem, self).__init__()
@ -367,34 +370,38 @@ class VmUpdateInfoWidget(QtGui.QWidget):
layout.addWidget(self.icon, alignment=QtCore.Qt.AlignCenter) layout.addWidget(self.icon, alignment=QtCore.Qt.AlignCenter)
self.setLayout(layout) self.setLayout(layout)
self.vm = vm
self.previous_outdated_state = None self.previous_outdated_state = None
self.previous_update_recommended = None self.previous_update_recommended = None
self.value = None self.value = None
self.table_item = VmUpdateInfoWidget.VmUpdateInfoItem(self.value, vm) self.table_item = VmUpdateInfoWidget.VmUpdateInfoItem(self.value, vm)
self.update_outdated(vm) self.update_outdated()
def update_outdated(self, vm):
def update_outdated(self):
outdated_state = False outdated_state = False
for vol in vm.volumes.values(): if self.vm.is_running():
if vol.is_outdated(): if hasattr(self.vm, 'template') and self.vm.template.is_running():
outdated_state = "outdated" outdated_state = "to-be-outdated"
break
if not outdated_state and getattr(vm, 'template', None)\ if not outdated_state:
and vm.template.is_running(): for vol in self.vm.volumes.values():
outdated_state = "to-be-outdated" if vol.is_outdated():
if outdated_state != self.previous_outdated_state: outdated_state = "outdated"
self.update_status_widget(outdated_state) break
self.previous_outdated_state = outdated_state
updates_available = vm.features.get('updates-available', False) elif self.vm.klass == 'TemplateVM' and \
if updates_available != self.previous_update_recommended: self.vm.features.get('updates-available', False):
self.update_status_widget("update" if updates_available else None) outdated_state = 'update'
self.previous_update_recommended = updates_available
self.update_status_widget(outdated_state)
def update_status_widget(self, state): def update_status_widget(self, state):
if state == self.previous_outdated_state:
return
self.previous_outdated_state = state
self.value = state self.value = state
self.table_item.set_value(state) self.table_item.set_value(state)
if state == "update": if state == "update":
@ -414,22 +421,22 @@ class VmUpdateInfoWidget(QtGui.QWidget):
"The Template must be stopped before changes from its " "The Template must be stopped before changes from its "
"current session can be picked up by this qube.") "current session can be picked up by this qube.")
else: else:
label_text = ""
icon_path = None icon_path = None
tooltip_text = None
if hasattr(self, 'icon'):
self.icon.setVisible(False)
self.layout().removeWidget(self.icon)
del self.icon
if self.show_text: if self.show_text:
self.label.setText(label_text) self.label.setText(label_text)
else: else:
self.layout().removeWidget(self.icon)
self.icon.deleteLater()
if icon_path is not None: if icon_path is not None:
self.icon = VmIconWidget(icon_path, True, 0.7) self.icon = VmIconWidget(icon_path, True, 0.7)
self.icon.setToolTip(tooltip_text) self.icon.setToolTip(tooltip_text)
else: self.layout().addWidget(self.icon,\
self.icon = QtGui.QLabel(label_text) alignment=QtCore.Qt.AlignCenter)
self.layout().addWidget(self.icon, alignment=QtCore.Qt.AlignCenter) self.icon.setVisible(True)
class VmSizeOnDiskItem(QtGui.QTableWidgetItem): class VmSizeOnDiskItem(QtGui.QTableWidgetItem):
def __init__(self, vm): def __init__(self, vm):
@ -465,6 +472,9 @@ class VmIPItem(QtGui.QTableWidgetItem):
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.update()
def update(self):
self.ip = getattr(self.vm, 'ip', None) self.ip = getattr(self.vm, 'ip', None)
self.setText(self.ip if self.ip is not None else 'n/a') self.setText(self.ip if self.ip is not None else 'n/a')
@ -482,6 +492,9 @@ class VmIncludeInBackupsItem(QtGui.QTableWidgetItem):
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.update()
def update(self):
if getattr(self.vm, 'include_in_backups', None): if getattr(self.vm, 'include_in_backups', None):
self.setText("Yes") self.setText("Yes")
else: else:
@ -503,6 +516,9 @@ class VmLastBackupItem(QtGui.QTableWidgetItem):
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled) self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
self.vm = vm self.vm = vm
self.update()
def update(self):
self.backup_timestamp = getattr(self.vm, 'backup_timestamp', None) self.backup_timestamp = getattr(self.vm, 'backup_timestamp', None)
if self.backup_timestamp: if self.backup_timestamp:

View File

@ -281,7 +281,6 @@
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_search"/> <addaction name="action_search"/>
<addaction name="action_refresh_list"/>
</widget> </widget>
<widget class="QMenu" name="menu_vm"> <widget class="QMenu" name="menu_vm">
<property name="title"> <property name="title">
@ -369,7 +368,6 @@
<addaction name="action_backup"/> <addaction name="action_backup"/>
<addaction name="action_restore"/> <addaction name="action_restore"/>
<addaction name="separator"/> <addaction name="separator"/>
<addaction name="action_refresh_list"/>
</widget> </widget>
<action name="action_createvm"> <action name="action_createvm">
<property name="icon"> <property name="icon">
@ -818,18 +816,6 @@
<string>Ctrl+F</string> <string>Ctrl+F</string>
</property> </property>
</action> </action>
<action name="action_refresh_list">
<property name="icon">
<iconset resource="../resources.qrc">
<normaloff>:/outdated.png</normaloff>:/outdated.png</iconset>
</property>
<property name="text">
<string>Refresh qube list</string>
</property>
<property name="toolTip">
<string>Refresh qube list</string>
</property>
</action>
<action name="action_exit"> <action name="action_exit">
<property name="text"> <property name="text">
<string>&amp;Exit Qube Manager</string> <string>&amp;Exit Qube Manager</string>

View File

@ -6,8 +6,8 @@
<rect> <rect>
<x>0</x> <x>0</x>
<y>0</y> <y>0</y>
<width>1587</width> <width>680</width>
<height>861</height> <height>656</height>
</rect> </rect>
</property> </property>
<property name="windowTitle"> <property name="windowTitle">