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

* origin/pr/270:
  Restored removed lines by accident (although I think that are useless at this moment)
  Fix pylint warnings
  Added saving and restore settings for showing checkboxes
  Removed unused import
  Enable 'Show' checkboxes by default
  Added filterAcceptsRow() to QubesProxyModel
  Added 'Show' Checkboxes to .ui
  Fix SelectionMode on ui file
This commit is contained in:
Marek Marczykowski-Górecki 2020-12-10 05:07:27 +01:00
commit c44880f9f5
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
2 changed files with 195 additions and 48 deletions

View File

@ -37,7 +37,7 @@ from PyQt5.QtCore import (Qt, QAbstractTableModel, QObject, pyqtSlot, QEvent,
# pylint: disable=import-error # pylint: disable=import-error
from PyQt5.QtWidgets import (QLineEdit, QStyledItemDelegate, QToolTip, from PyQt5.QtWidgets import (QLineEdit, QStyledItemDelegate, QToolTip,
QMenu, QInputDialog, QMainWindow, QProgressDialog, QStyleOptionViewItem, QMenu, QInputDialog, QMainWindow, QProgressDialog, QStyleOptionViewItem,
QAbstractItemView, QMessageBox) QMessageBox)
# pylint: disable=import-error # pylint: disable=import-error
from PyQt5.QtGui import (QIcon, QPixmap, QRegExpValidator, QFont, QColor) from PyQt5.QtGui import (QIcon, QPixmap, QRegExpValidator, QFont, QColor)
@ -630,8 +630,11 @@ class RunCommandThread(common_threads.QubesThread):
except (ChildProcessError, exc.QubesException) as ex: except (ChildProcessError, exc.QubesException) as ex:
self.msg = (self.tr("Error while running command!"), str(ex)) self.msg = (self.tr("Error while running command!"), str(ex))
class QubesProxyModel(QSortFilterProxyModel): class QubesProxyModel(QSortFilterProxyModel):
def __init__(self, window):
super().__init__()
self.window = window
def lessThan(self, left, right): def lessThan(self, left, right):
if left.data(self.sortRole()) != right.data(self.sortRole()): if left.data(self.sortRole()) != right.data(self.sortRole()):
return super().lessThan(left, right) return super().lessThan(left, right)
@ -641,6 +644,31 @@ class QubesProxyModel(QSortFilterProxyModel):
return left_vm.name.lower() < right_vm.name.lower() return left_vm.name.lower() < right_vm.name.lower()
# pylint: disable=too-many-return-statements
def filterAcceptsRow(self, sourceRow, sourceParent):
if self.window.show_all.isChecked():
return super().filterAcceptsRow(sourceRow, sourceParent)
index = self.sourceModel().index(sourceRow, 0, sourceParent)
vm = self.sourceModel().data(index, Qt.UserRole)
if self.window.show_running.isChecked() and \
vm.state['power'] == 'Running':
return super().filterAcceptsRow(sourceRow, sourceParent)
if self.window.show_halted.isChecked() and \
vm.state['power'] == 'Halted':
return super().filterAcceptsRow(sourceRow, sourceParent)
if self.window.show_network.isChecked() and \
getattr(vm.vm, 'provides_network', False):
return super().filterAcceptsRow(sourceRow, sourceParent)
if self.window.show_templates.isChecked() and vm.klass == 'TemplateVM':
return super().filterAcceptsRow(sourceRow, sourceParent)
if self.window.show_standalone.isChecked() \
and vm.klass == 'StandaloneVM':
return super().filterAcceptsRow(sourceRow, sourceParent)
return False
class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow): class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
# suppress saving settings while initializing widgets # suppress saving settings while initializing widgets
@ -659,38 +687,14 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.searchbox.setValidator(QRegExpValidator( self.searchbox.setValidator(QRegExpValidator(
QRegExp("[a-zA-Z0-9_-]*", Qt.CaseInsensitive), None)) QRegExp("[a-zA-Z0-9_-]*", Qt.CaseInsensitive), None))
self.searchbox.textChanged.connect(self.do_search) self.searchbox.textChanged.connect(self.do_search)
self.searchContainer.addWidget(self.searchbox) self.searchContainer.insertWidget(1, self.searchbox)
self.settings_windows = {} self.settings_windows = {}
self.frame_width = 0 self.frame_width = 0
self.frame_height = 0 self.frame_height = 0
self.context_menu = QMenu(self) self.__init_context_menu()
self.context_menu.addAction(self.action_settings)
self.context_menu.addAction(self.action_editfwrules)
self.context_menu.addAction(self.action_appmenus)
self.context_menu.addAction(self.action_set_keyboard_layout)
self.context_menu.addSeparator()
self.context_menu.addAction(self.action_updatevm)
self.context_menu.addAction(self.action_run_command_in_vm)
self.context_menu.addAction(self.action_open_console)
self.context_menu.addAction(self.action_resumevm)
self.context_menu.addAction(self.action_startvm_tools_install)
self.context_menu.addAction(self.action_pausevm)
self.context_menu.addAction(self.action_shutdownvm)
self.context_menu.addAction(self.action_restartvm)
self.context_menu.addAction(self.action_killvm)
self.context_menu.addSeparator()
self.context_menu.addAction(self.action_clonevm)
self.context_menu.addAction(self.action_removevm)
self.context_menu.addSeparator()
self.context_menu.addMenu(self.logs_menu)
self.context_menu.addSeparator()
self.tools_context_menu = QMenu(self) self.tools_context_menu = QMenu(self)
self.tools_context_menu.addAction(self.action_toolbar) self.tools_context_menu.addAction(self.action_toolbar)
@ -713,7 +717,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.fill_cache() self.fill_cache()
self.qubes_model = QubesTableModel(self.qubes_cache) self.qubes_model = QubesTableModel(self.qubes_cache)
self.proxy = QubesProxyModel() self.proxy = QubesProxyModel(self)
self.proxy.setSourceModel(self.qubes_model) self.proxy.setSourceModel(self.qubes_model)
self.proxy.setSortRole(Qt.UserRole + 1) self.proxy.setSortRole(Qt.UserRole + 1)
self.proxy.setSortCaseSensitivity(Qt.CaseInsensitive) self.proxy.setSortCaseSensitivity(Qt.CaseInsensitive)
@ -721,10 +725,16 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive) self.proxy.setFilterCaseSensitivity(Qt.CaseInsensitive)
self.proxy.layoutChanged.connect(self.save_sorting) self.proxy.layoutChanged.connect(self.save_sorting)
self.show_running.stateChanged.connect(self.invalidate)
self.show_halted.stateChanged.connect(self.invalidate)
self.show_network.stateChanged.connect(self.invalidate)
self.show_templates.stateChanged.connect(self.invalidate)
self.show_standalone.stateChanged.connect(self.invalidate)
self.show_all.stateChanged.connect(self.invalidate)
self.table.setModel(self.proxy) self.table.setModel(self.proxy)
self.table.setItemDelegateForColumn(3, StateIconDelegate()) self.table.setItemDelegateForColumn(3, StateIconDelegate())
self.table.resizeColumnsToContents() self.table.resizeColumnsToContents()
self.table.setSelectionMode(QAbstractItemView.ExtendedSelection)
selection_model = self.table.selectionModel() selection_model = self.table.selectionModel()
selection_model.selectionChanged.connect(self.table_selection_changed) selection_model.selectionChanged.connect(self.table_selection_changed)
@ -794,12 +804,52 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
self.check_updates() self.check_updates()
def __init_context_menu(self):
self.context_menu = QMenu(self)
self.context_menu.addAction(self.action_settings)
self.context_menu.addAction(self.action_editfwrules)
self.context_menu.addAction(self.action_appmenus)
self.context_menu.addAction(self.action_set_keyboard_layout)
self.context_menu.addSeparator()
self.context_menu.addAction(self.action_updatevm)
self.context_menu.addAction(self.action_run_command_in_vm)
self.context_menu.addAction(self.action_open_console)
self.context_menu.addAction(self.action_resumevm)
self.context_menu.addAction(self.action_startvm_tools_install)
self.context_menu.addAction(self.action_pausevm)
self.context_menu.addAction(self.action_shutdownvm)
self.context_menu.addAction(self.action_restartvm)
self.context_menu.addAction(self.action_killvm)
self.context_menu.addSeparator()
self.context_menu.addAction(self.action_clonevm)
self.context_menu.addAction(self.action_removevm)
self.context_menu.addSeparator()
self.context_menu.addMenu(self.logs_menu)
self.context_menu.addSeparator()
def save_showing(self):
self.manager_settings.setValue('show/running',
self.show_running.isChecked())
self.manager_settings.setValue('show/halted',
self.show_halted.isChecked())
self.manager_settings.setValue('show/network',
self.show_network.isChecked())
self.manager_settings.setValue('show/templates',
self.show_templates.isChecked())
self.manager_settings.setValue('show/standalone',
self.show_standalone.isChecked())
self.manager_settings.setValue('show/all', self.show_all.isChecked())
def save_sorting(self): def save_sorting(self):
self.manager_settings.setValue('view/sort_column', self.manager_settings.setValue('view/sort_column',
self.proxy.sortColumn()) self.proxy.sortColumn())
self.manager_settings.setValue('view/sort_order', self.manager_settings.setValue('view/sort_order',
self.proxy.sortOrder()) self.proxy.sortOrder())
def invalidate(self):
self.proxy.invalidate()
self.table.resizeColumnsToContents()
def fill_cache(self): def fill_cache(self):
progress = QProgressDialog( progress = QProgressDialog(
self.tr( self.tr(
@ -948,6 +998,20 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
defaultValue=True): defaultValue=True):
self.action_toolbar.setChecked(False) self.action_toolbar.setChecked(False)
# Restore show checkboxes
self.show_running.setChecked(self.manager_settings.value(
'show/running', "true") == "true")
self.show_halted.setChecked(self.manager_settings.value(
'show/halted', "true") == "true")
self.show_network.setChecked(self.manager_settings.value(
'show/network', "true") == "true")
self.show_templates.setChecked(self.manager_settings.value(
'show/templates', "true") == "true")
self.show_standalone.setChecked(self.manager_settings.value(
'show/standalone', "true") == "true")
self.show_all.setChecked(self.manager_settings.value(
'show/all', "true") == "true")
# load last window size # load last window size
self.resize(self.manager_settings.value("window_size", self.resize(self.manager_settings.value("window_size",
QSize(1100, 600))) QSize(1100, 600)))
@ -1264,6 +1328,9 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QMainWindow):
"\nError: {}".format(str(ex)))) "\nError: {}".format(str(ex))))
return return
def closeEvent(self, _):
self.save_showing()
# noinspection PyArgumentList # noinspection PyArgumentList
@pyqtSlot(name='on_action_settings_triggered') @pyqtSlot(name='on_action_settings_triggered')
def action_settings_triggered(self): def action_settings_triggered(self):

View File

@ -52,23 +52,6 @@
<property name="sizeConstraint"> <property name="sizeConstraint">
<enum>QLayout::SetDefaultConstraint</enum> <enum>QLayout::SetDefaultConstraint</enum>
</property> </property>
<item row="0" column="0">
<layout class="QHBoxLayout" name="searchContainer">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="1" column="0"> <item row="1" column="0">
<widget class="QTableView" name="table"> <widget class="QTableView" name="table">
<property name="minimumSize"> <property name="minimumSize">
@ -108,7 +91,7 @@
<bool>true</bool> <bool>true</bool>
</property> </property>
<property name="selectionMode"> <property name="selectionMode">
<enum>QAbstractItemView::SingleSelection</enum> <enum>QAbstractItemView::ExtendedSelection</enum>
</property> </property>
<property name="selectionBehavior"> <property name="selectionBehavior">
<enum>QAbstractItemView::SelectRows</enum> <enum>QAbstractItemView::SelectRows</enum>
@ -236,6 +219,103 @@ Template</string>
</column> </column>
</widget> </widget>
</item> </item>
<item row="0" column="0">
<layout class="QHBoxLayout" name="searchContainer">
<property name="spacing">
<number>6</number>
</property>
<property name="leftMargin">
<number>6</number>
</property>
<item>
<widget class="QLabel" name="label">
<property name="text">
<string>Search:</string>
</property>
</widget>
</item>
<item>
<widget class="QLabel" name="show_label">
<property name="text">
<string>Show:</string>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_running">
<property name="text">
<string>Running</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_halted">
<property name="text">
<string>Halted</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_network">
<property name="text">
<string>Network</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_templates">
<property name="text">
<string>Templates</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_standalone">
<property name="text">
<string>Standalone</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="show_all">
<property name="text">
<string>All</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
</layout>
</item>
</layout> </layout>
</widget> </widget>
<widget class="QMenuBar" name="menubar"> <widget class="QMenuBar" name="menubar">