Skip to content

Commit

Permalink
Fixes to Template Switcher
Browse files Browse the repository at this point in the history
- improved behavior on double-click
- improved behavior on OK (progress dialog)
- no auto-close on OK

fixes QubesOS/qubes-issues#7639
  • Loading branch information
marmarta committed Oct 14, 2024
1 parent b0e40d2 commit fd23b57
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 15 deletions.
20 changes: 20 additions & 0 deletions qubesmanager/common_threads.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,3 +72,23 @@ def run(self):
self.msg_is_success = True
except exc.QubesException as ex:
self.msg = (self.tr("Error while cloning qube!"), str(ex))


class ChangeTemplatesThread(QtCore.QThread):
def __init__(self, progress_dialog, items_to_change, qubes_app):
super().__init__()
self.dialog = progress_dialog
self.items = items_to_change
self.qubes_app = qubes_app
self.errors = {}

def run(self):
i = 0
for vm, row in self.items:
i += 1
try:
setattr(self.qubes_app.domains[vm],
'template', row.new_item.currentText())
except Exception as ex: # pylint: disable=broad-except
self.errors[vm] = str(ex)
self.dialog.setValue(i)
66 changes: 51 additions & 15 deletions qubesmanager/template_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@

from . import ui_templatemanager # pylint: disable=no-name-in-module
from . import utils
from . import common_threads

column_names = ['State', 'Qube', 'Current template', 'New template']

Expand All @@ -45,14 +46,20 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.rows_in_table = {}
self.templates = []
self.timers = []
self.dialog = None
self.thread = None

self.prepare_lists()
self.initialize_table_events()

self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(
self.apply)
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Ok).setText('Apply')
self.buttonBox.button(
QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.cancel)
self.buttonBox.button(
QtWidgets.QDialogButtonBox.StandardButton.Cancel).setText('Close')
self.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(
self.reset)

Expand Down Expand Up @@ -179,9 +186,12 @@ def change_all_changed(self):
row.new_item.findText(selected_template))

self.change_all_combobox.setCurrentIndex(0)
self.clear_selection()

def table_double_click(self, row, column):
template_column = column_names.index('Current template')
current_state = self.vm_list.cellWidget(
row, column_names.index('State')).isChecked()

if column != template_column:
return
Expand All @@ -194,16 +204,13 @@ def table_double_click(self, row, column):
checkbox = self.vm_list.cellWidget(
row_number, column_names.index('State'))
if checkbox:
if row_number == row:
# this is because double click registers as a
# single click and a double click
checkbox.setChecked(False)
else:
checkbox.setChecked(True)
checkbox.setChecked(not current_state)

def table_click(self, row, column):
if column == column_names.index('New template'):
return
if column == column_names.index('Current template'):
return

checkbox = self.vm_list.cellWidget(row, column_names.index('State'))
if not checkbox:
Expand All @@ -222,14 +229,28 @@ def cancel(self):
self.close()

def apply(self):
errors = {}
for vm, row in self.rows_in_table.items():
if row.new_item and row.new_item.changed:
try:
setattr(self.qubes_app.domains[vm],
'template', row.new_item.currentText())
except Exception as ex: # pylint: disable=broad-except
errors[vm] = str(ex)
items_to_change = [
(vm, row) for vm, row in self.rows_in_table.items()
if row.new_item and row.new_item.changed]

# show a "in progress" dialog
self.dialog = QtWidgets.QProgressDialog(
"Changing templates...", None, 0, len(items_to_change), self)
self.dialog.setCancelButton(None)
self.dialog.setModal(True)
self.dialog.show()

self.thread = common_threads.ChangeTemplatesThread(self.dialog,
items_to_change,
self.qubes_app)
self.thread.finished.connect(self.finish_changes)
self.thread.start()

def finish_changes(self):
self.dialog.hide()

errors = self.thread.errors

if errors:
error_messages = [vm + ": " + error for vm, error in errors.items()]
QtWidgets.QMessageBox.warning(
Expand All @@ -238,7 +259,14 @@ def apply(self):
self.tr(
"Errors encountered on template change in the following "
"qubes: <br> {}.").format("<br> ".join(error_messages)))
self.close()

for vm, row in self.rows_in_table.items():
if row.new_item and row.new_item.changed:
vm_object = self.qubes_app.domains[vm]

if vm_object.template.name == row.new_item.currentText():
row.new_item.reset_start_value()
row.current_item.reset_template_name()


class VMNameItem(QtWidgets.QTableWidgetItem):
Expand Down Expand Up @@ -288,6 +316,9 @@ def __lt__(self, other):
return self.vm.name < other.vm.name
return self.text() < other.text()

def reset_template_name(self):
self.setText(self.vm.template.name)


class NewTemplateItem(QtWidgets.QComboBox):
def __init__(self, vm, templates, table_widget):
Expand All @@ -314,6 +345,11 @@ def choice_changed(self):
def reset_choice(self):
self.setCurrentIndex(self.findText(self.start_value))

def reset_start_value(self):
self.start_value = self.currentText()
self.changed = False
self.setStyleSheet('font-weight: normal')


class VMRow:
# pylint: disable=too-few-public-methods
Expand Down

0 comments on commit fd23b57

Please sign in to comment.