diff --git a/Makefile b/Makefile
index 1abbd976..3be19ce5 100644
--- a/Makefile
+++ b/Makefile
@@ -20,15 +20,15 @@ rpms-dom0:
rpm --addsign $(RPMS_DIR)/x86_64/qubes-manager*$(VERSION)*.rpm
qubesmanager/ui_%.py: ui/%.ui
- pyuic4 --from-imports -o $@ $<
+ pyuic5 --from-imports -o $@ $<
ui: $(patsubst ui/%.ui,qubesmanager/ui_%.py,$(wildcard ui/*.ui))
res:
- pyrcc4 -py3 -o qubesmanager/resources_rc.py resources.qrc
+ pyrcc5 -o qubesmanager/resources_rc.py resources.qrc
translations:
- lrelease-qt4 qubesmanager.pro
+ lrelease-qt5 qubesmanager.pro
python:
$(PYTHON) ./setup.py build
@@ -37,7 +37,7 @@ python_install:
$(PYTHON) ./setup.py install -O1 --skip-build --root $(DESTDIR)
update_ts: res
- pylupdate4 qubesmanager.pro
+ pylupdate5 qubesmanager.pro
update-repo-current:
ln -f $(RPMS_DIR)/x86_64/qubes-manager-*$(VERSION)*.rpm ../yum/current-release/current/dom0/rpm/
diff --git a/build-deps.list b/build-deps.list
index 32fd60c2..262823d4 100644
--- a/build-deps.list
+++ b/build-deps.list
@@ -1 +1 @@
-PyQt4-devel
+PyQt5-devel
diff --git a/qubesmanager/about.py b/qubesmanager/about.py
index da54508d..49670b6c 100644
--- a/qubesmanager/about.py
+++ b/qubesmanager/about.py
@@ -20,7 +20,8 @@
# with this program; if not, see .
#
#
-from PyQt4.QtGui import QDialog, QIcon # pylint: disable=import-error
+from PyQt5.QtWidgets import QDialog # pylint: disable=import-error
+from PyQt5.QtGui import QIcon # pylint: disable=import-error
from qubesmanager.releasenotes import ReleaseNotesDialog
from qubesmanager.informationnotes import InformationNotesDialog
@@ -42,10 +43,12 @@ def __init__(self):
self.releaseNotes.clicked.connect(on_release_notes_clicked)
self.informationNotes.clicked.connect(on_information_notes_clicked)
+
def on_release_notes_clicked():
release_notes_dialog = ReleaseNotesDialog()
release_notes_dialog.exec_()
+
def on_information_notes_clicked():
information_notes_dialog = InformationNotesDialog()
information_notes_dialog.exec_()
diff --git a/qubesmanager/appmenu_select.py b/qubesmanager/appmenu_select.py
index f042011a..196dc638 100755
--- a/qubesmanager/appmenu_select.py
+++ b/qubesmanager/appmenu_select.py
@@ -20,13 +20,13 @@
#
import subprocess
+import PyQt5.QtWidgets # pylint: disable=import-error
-import PyQt4.QtGui # pylint: disable=import-error
# TODO description in tooltip
# TODO icon
# pylint: disable=too-few-public-methods
-class AppListWidgetItem(PyQt4.QtGui.QListWidgetItem):
+class AppListWidgetItem(PyQt5.QtWidgets.QListWidgetItem):
def __init__(self, name, ident, parent=None):
super(AppListWidgetItem, self).__init__(name, parent)
# self.setToolTip(command)
@@ -58,9 +58,10 @@ def fill_apps_list(self):
self.app_list.clear()
available_appmenus = [AppListWidgetItem.from_line(line)
- for line in subprocess.check_output(['qvm-appmenus',
- '--get-available', '--i-understand-format-is-unstable',
- self.vm.name]).decode().splitlines()]
+ for line in subprocess.check_output(
+ ['qvm-appmenus',
+ '--get-available', '--i-understand-format-is-unstable',
+ self.vm.name]).decode().splitlines()]
for app in available_appmenus:
if app.ident in self.whitelisted:
@@ -73,7 +74,7 @@ def fill_apps_list(self):
def save_appmenu_select_changes(self):
new_whitelisted = [self.app_list.selected_list.item(i).ident
- for i in range(self.app_list.selected_list.count())]
+ for i in range(self.app_list.selected_list.count())]
if set(new_whitelisted) == set(self.whitelisted):
return False
diff --git a/qubesmanager/backup.py b/qubesmanager/backup.py
index 455500e8..03356485 100644
--- a/qubesmanager/backup.py
+++ b/qubesmanager/backup.py
@@ -30,8 +30,8 @@
from qubesadmin import events
from qubes.storage.file import get_disk_usage
-from PyQt4 import QtCore # pylint: disable=import-error
-from PyQt4 import QtGui # pylint: disable=import-error
+from PyQt5 import QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets # pylint: disable=import-error
from . import ui_backupdlg # pylint: disable=no-name-in-module
from . import multiselectwidget
@@ -45,6 +45,7 @@
import asyncio
from contextlib import suppress
+
# pylint: disable=too-few-public-methods
class BackupThread(QtCore.QThread):
def __init__(self, vm):
@@ -67,7 +68,7 @@ def run(self):
self.msg = '\n'.join(msg)
-class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
+class BackupVMsWindow(ui_backupdlg.Ui_Backup, QtWidgets.QWizard):
def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
super(BackupVMsWindow, self).__init__(parent)
@@ -86,34 +87,21 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.select_vms_widget = multiselectwidget.MultiSelectWidget(self)
self.verticalLayout.insertWidget(1, self.select_vms_widget)
- self.connect(self, QtCore.SIGNAL("currentIdChanged(int)"),
- self.current_page_changed)
- self.connect(self.select_vms_widget,
- QtCore.SIGNAL("items_removed(PyQt_PyObject)"),
- self.vms_removed)
- self.connect(self.select_vms_widget,
- QtCore.SIGNAL("items_added(PyQt_PyObject)"),
- self.vms_added)
- self.dir_line_edit.connect(self.dir_line_edit,
- QtCore.SIGNAL("textChanged(QString)"),
- self.backup_location_changed)
+ self.currentIdChanged.connect(self.current_page_changed)
+ self.select_vms_widget.itemsRemoved.connect(self.vms_removed)
+ self.select_vms_widget.itemsAdded.connect(self.vms_added)
+ self.dir_line_edit.textChanged.connect(self.backup_location_changed)
self.select_vms_page.isComplete = self.has_selected_vms
self.select_dir_page.isComplete = self.has_selected_dir_and_pass
# FIXME
# this causes to run isComplete() twice, I don't know why
- self.select_vms_page.connect(
- self.select_vms_widget,
- QtCore.SIGNAL("selected_changed()"),
- QtCore.SIGNAL("completeChanged()"))
- self.passphrase_line_edit.connect(
- self.passphrase_line_edit,
- QtCore.SIGNAL("textChanged(QString)"),
- self.backup_location_changed)
- self.passphrase_line_edit_verify.connect(
- self.passphrase_line_edit_verify,
- QtCore.SIGNAL("textChanged(QString)"),
- self.backup_location_changed)
+ self.select_vms_widget.selectedChanged.connect(
+ self.select_vms_page.completeChanged.emit)
+ self.passphrase_line_edit.textChanged.connect(
+ self.backup_location_changed)
+ self.passphrase_line_edit_verify.textChanged.connect(
+ self.backup_location_changed)
self.total_size = 0
@@ -173,8 +161,8 @@ def load_settings(self):
except FileNotFoundError:
return
except exc.QubesException:
- QtGui.QMessageBox.information(
- None, self.tr("Error loading backup profile"),
+ QtWidgets.QMessageBox.information(
+ self, self.tr("Error loading backup profile"),
self.tr("Unable to load saved backup profile."))
return
if not profile_data:
@@ -216,7 +204,7 @@ def save_settings(self, use_temp):
backup_utils.write_backup_profile(settings, use_temp)
- class VmListItem(QtGui.QListWidgetItem):
+ class VmListItem(QtWidgets.QListWidgetItem):
# pylint: disable=too-few-public-methods
def __init__(self, vm):
self.vm = vm
@@ -276,33 +264,32 @@ def validateCurrentPage(self):
elif self.currentPage() is self.select_dir_page:
backup_location = str(self.dir_line_edit.text())
if not backup_location:
- QtGui.QMessageBox.information(
- None, self.tr("Wait!"),
+ QtWidgets.QMessageBox.information(
+ self, self.tr("Wait!"),
self.tr("Enter backup target location first."))
return False
if self.appvm_combobox.currentText() == "dom0" \
and not os.path.isdir(backup_location):
- QtGui.QMessageBox.information(
- None, self.tr("Wait!"),
+ QtWidgets.QMessageBox.information(
+ self, self.tr("Wait!"),
self.tr("Selected directory do not exists or "
"not a directory (%s).") % backup_location)
return False
if not self.passphrase_line_edit.text():
- QtGui.QMessageBox.information(
- None, self.tr("Wait!"),
+ QtWidgets.QMessageBox.information(
+ self, self.tr("Wait!"),
self.tr("Enter passphrase for backup "
"encryption/verification first."))
return False
if self.passphrase_line_edit.text() !=\
self.passphrase_line_edit_verify.text():
- QtGui.QMessageBox.information(
- None, self.tr("Wait!"),
+ QtWidgets.QMessageBox.information(
+ self, self.tr("Wait!"),
self.tr("Enter the same passphrase in both fields."))
return False
return True
-
@staticmethod
def cleanup_temporary_files():
try:
@@ -310,7 +297,7 @@ def cleanup_temporary_files():
except FileNotFoundError:
pass
- def current_page_changed(self, page_id): # pylint: disable=unused-argument
+ def current_page_changed(self, page_id): # pylint: disable=unused-argument
old_sigchld_handler = signal.signal(signal.SIGCHLD, signal.SIG_DFL)
if self.currentPage() is self.confirm_page:
@@ -347,7 +334,7 @@ def current_page_changed(self, page_id): # pylint: disable=unused-argument
def backup_finished(self):
if self.thread.msg:
self.progress_status.setText(self.tr("Backup error."))
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self, self.tr("Backup error!"),
self.tr("ERROR: {}").format(
self.thread.msg))
@@ -383,7 +370,7 @@ def reject(self):
'dom0', 'admin.backup.Cancel',
backup_utils.get_profile_name(True))
self.thread.wait()
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self, self.tr("Backup aborted!"),
self.tr("ERROR: {}").format("Aborted!"))
@@ -403,7 +390,7 @@ def has_selected_dir_and_pass(self):
def backup_location_changed(self, new_dir=None):
# pylint: disable=unused-argument
- self.select_dir_page.emit(QtCore.SIGNAL("completeChanged()"))
+ self.select_dir_page.completeChanged.emit()
# Bases on the original code by:
@@ -414,7 +401,7 @@ def handle_exception(exc_type, exc_value, exc_traceback):
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
- QtGui.QMessageBox.critical(
+ QtWidgets.QMessageBox.critical(
None,
"Houston, we have a problem...",
"Whoops. A critical error has occured. This is most likely a bug "
@@ -422,6 +409,7 @@ def handle_exception(exc_type, exc_value, exc_traceback):
error + "at line %d of file %s.
"
% (line, filename))
+
def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
@@ -430,7 +418,7 @@ def loop_shutdown():
def main():
- qt_app = QtGui.QApplication(sys.argv)
+ qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qubes Backup VMs")
@@ -452,7 +440,7 @@ def main():
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
- except Exception: # pylint: disable=broad-except
+ except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
diff --git a/qubesmanager/backup_utils.py b/qubesmanager/backup_utils.py
index 7dfb8fd4..6d38274a 100644
--- a/qubesmanager/backup_utils.py
+++ b/qubesmanager/backup_utils.py
@@ -21,8 +21,7 @@
import re
import socket
-from PyQt4 import QtGui # pylint: disable=import-error
-from PyQt4 import QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets # pylint: disable=import-error
import subprocess
from . import utils
@@ -76,7 +75,7 @@ def select_path_button_clicked(dialog, select_file=False, read_only=False):
vm = dialog.qubes_app.domains[new_appvm]
try:
if vm.name == socket.gethostname():
- file_dialog = QtGui.QFileDialog()
+ file_dialog = QtWidgets.QFileDialog()
file_dialog.setReadOnly(True)
if select_file:
@@ -94,8 +93,8 @@ def select_path_button_clicked(dialog, select_file=False, read_only=False):
else "qubes.SelectDirectory")
except subprocess.CalledProcessError:
if not read_only:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ dialog,
dialog.tr("Nothing selected!"),
dialog.tr("No file or directory selected."))
else:
@@ -105,7 +104,7 @@ def select_path_button_clicked(dialog, select_file=False, read_only=False):
dialog.dir_line_edit.setText(new_path)
if new_path and backup_location and not read_only:
- dialog.select_dir_page.emit(QtCore.SIGNAL("completeChanged()"))
+ dialog.select_dir_page.completeChanged.emit()
def get_profile_name(use_temp):
diff --git a/qubesmanager/bootfromdevice.py b/qubesmanager/bootfromdevice.py
index 2849db2c..82ea5f55 100644
--- a/qubesmanager/bootfromdevice.py
+++ b/qubesmanager/bootfromdevice.py
@@ -21,12 +21,13 @@
import subprocess
from . import utils
from . import ui_bootfromdevice # pylint: disable=no-name-in-module
-from PyQt4 import QtGui, QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets # pylint: disable=import-error
from qubesadmin import tools
from qubesadmin.tools import qvm_start
-class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog, QtGui.QDialog):
+class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog,
+ QtWidgets.QDialog):
def __init__(self, vm, qapp, parent=None):
super(VMBootFromDeviceWindow, self).__init__(parent)
@@ -37,11 +38,8 @@ def __init__(self, vm, qapp, parent=None):
self.setWindowTitle(
self.tr("Boot {vm} from device").format(vm=self.vm.name))
- self.connect(
- self.buttonBox,
- QtCore.SIGNAL("accepted()"),
- self.save_and_apply)
- self.connect(self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
+ self.buttonBox.accepted.connect(self.save_and_apply)
+ self.buttonBox.rejected.connect(self.reject)
# populate buttons and such
self.__init_buttons__()
@@ -59,8 +57,8 @@ def save_and_apply(self):
self.vm_list[self.fileVM.currentIndex()]) + \
":" + self.pathText.text()
else:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("ERROR!"),
self.tr("No file or block device selected; please select one."))
return
@@ -74,8 +72,8 @@ def save_and_apply(self):
def __warn_if_running__(self):
if self.vm.is_running():
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Warning!"),
self.tr("Qube must be turned off before booting it from "
"device. Please turn off the qube.")
@@ -102,7 +100,7 @@ def __init_buttons__(self):
self.vm,
None,
[device for domain in self.vm.app.domains
- for device in domain.devices["block"]],
+ for device in domain.devices["block"]],
None,
None,
allow_default=False, allow_none=False
@@ -134,7 +132,7 @@ def main(args=None):
args = parser.parse_args(args)
vm = args.domains.pop()
- qapp = QtGui.QApplication(sys.argv)
+ qapp = QtWidgets.QApplication(sys.argv)
qapp.setOrganizationName('Invisible Things Lab')
qapp.setOrganizationDomain("https://www.qubes-os.org/")
qapp.setApplicationName("Boot Qube From Device")
@@ -148,5 +146,6 @@ def main(args=None):
qapp.exec_()
qapp.exit()
+
if __name__ == "__main__":
main()
diff --git a/qubesmanager/clipboard.py b/qubesmanager/clipboard.py
index f4c57854..277e42fa 100644
--- a/qubesmanager/clipboard.py
+++ b/qubesmanager/clipboard.py
@@ -1,5 +1,4 @@
-#!/usr/bin/python2
-# pylint: skip-file
+#!/usr/bin/python3
#
# The Qubes OS Project, http://www.qubes-os.org
#
@@ -26,51 +25,63 @@
import fcntl
from math import log
-from PyQt4.QtGui import QApplication
+# pylint: disable=import-error
+from PyQt5.QtWidgets import QApplication, QMessageBox
APPVIEWER_LOCK = "/var/run/qubes/appviewer.lock"
CLIPBOARD_CONTENTS = "/var/run/qubes/qubes-clipboard.bin"
CLIPBOARD_SOURCE = CLIPBOARD_CONTENTS + ".source"
+
def do_dom0_copy():
copy_text_to_qubes_clipboard(QApplication.clipboard().text())
+
def copy_text_to_qubes_clipboard(text):
- #inter-appviewer lock
+ # inter-appviewer lock
try:
- fd = os.open(APPVIEWER_LOCK, os.O_RDWR|os.O_CREAT, 0o0666)
- except:
- QMessageBox.warning(None, "Warning!", "Error while accessing Qubes clipboard!")
+ file = os.open(APPVIEWER_LOCK, os.O_RDWR | os.O_CREAT, 0o0666)
+ except Exception: # pylint: disable=broad-except
+ QMessageBox.warning(None, "Warning!",
+ "Error while accessing Qubes clipboard!")
else:
try:
- fcntl.flock(fd, fcntl.LOCK_EX)
- except:
- QMessageBox.warning(None, "Warning!", "Error while locking Qubes clipboard!")
+ fcntl.flock(file, fcntl.LOCK_EX)
+ except Exception: # pylint: disable=broad-except
+ QMessageBox.warning(None, "Warning!",
+ "Error while locking Qubes clipboard!")
else:
try:
with open(CLIPBOARD_CONTENTS, "w") as contents:
contents.write(text)
with open(CLIPBOARD_SOURCE, "w") as source:
source.write("dom0")
- except:
- QMessageBox.warning(None, "Warning!", "Error while writing to Qubes clipboard!")
- fcntl.flock(fd, fcntl.LOCK_UN)
- os.close(fd)
+ except Exception: # pylint: disable=broad-except
+ QMessageBox.warning(None, "Warning!",
+ "Error while writing to Qubes clipboard!")
+ fcntl.flock(file, fcntl.LOCK_UN)
+ os.close(file)
+
+# pylint: disable=invalid-name
def get_qubes_clipboard_formatted_size():
units = ['B', 'KiB', 'MiB', 'GiB']
try:
file_size = os.path.getsize(CLIPBOARD_CONTENTS)
- except:
- QMessageBox.warning(None, "Warning!", "Error while accessing Qubes clipboard!")
+ except Exception: # pylint: disable=broad-except
+ QMessageBox.warning(None, "Warning!",
+ "Error while accessing Qubes clipboard!")
else:
- formatted_bytes = '1 byte' if file_size == 1 else str(file_size) + ' bytes'
+ formatted_bytes = '1 byte' if file_size == 1 \
+ else str(file_size) + ' bytes'
if file_size > 0:
magnitude = min(int(log(file_size)/log(2)*0.1), len(units)-1)
if magnitude > 0:
- return '%s (%.1f %s)' % (formatted_bytes, file_size/(2.0**(10*magnitude)), units[magnitude])
- return '%s' % (formatted_bytes)
+ return '%s (%.1f %s)' % (formatted_bytes,
+ file_size/(2.0**(10*magnitude)),
+ units[magnitude])
+ return '%s' % formatted_bytes
return '? bytes'
diff --git a/qubesmanager/common_threads.py b/qubesmanager/common_threads.py
index 75adc08d..e2bf9e5f 100644
--- a/qubesmanager/common_threads.py
+++ b/qubesmanager/common_threads.py
@@ -20,7 +20,7 @@
#
-from PyQt4 import QtCore, QtGui # pylint: disable=import-error
+from PyQt5 import QtCore, QtWidgets # pylint: disable=import-error
from contextlib import contextmanager
from qubesadmin import exc
@@ -29,10 +29,10 @@
@contextmanager
def busy_cursor():
try:
- QtGui.QApplication.setOverrideCursor(QtCore.Qt.BusyCursor)
+ QtWidgets.QApplication.setOverrideCursor(QtCore.Qt.BusyCursor)
yield
finally:
- QtGui.QApplication.restoreOverrideCursor()
+ QtWidgets.QApplication.restoreOverrideCursor()
# pylint: disable=too-few-public-methods
diff --git a/qubesmanager/create_new_vm.py b/qubesmanager/create_new_vm.py
index 0c82fb8e..442a6374 100644
--- a/qubesmanager/create_new_vm.py
+++ b/qubesmanager/create_new_vm.py
@@ -24,7 +24,7 @@
import sys
import subprocess
-from PyQt4 import QtCore, QtGui # pylint: disable=import-error
+from PyQt5 import QtCore, QtWidgets, QtGui # pylint: disable=import-error
import qubesadmin
import qubesadmin.tools
@@ -34,6 +34,7 @@
from .ui_newappvmdlg import Ui_NewVMDlg # pylint: disable=import-error
+
# pylint: disable=too-few-public-methods
class CreateVMThread(QtCore.QThread):
def __init__(self, app, vmclass, name, label, template, properties):
@@ -59,8 +60,9 @@ def run(self):
for k, v in self.properties.items():
setattr(vm, k, v)
else:
- vm = self.app.add_new_vm(self.vmclass,
- name=self.name, label=self.label, template=self.template)
+ vm = self.app.add_new_vm(
+ self.vmclass, name=self.name,
+ label=self.label, template=self.template)
for k, v in self.properties.items():
setattr(vm, k, v)
@@ -70,7 +72,7 @@ def run(self):
self.msg = repr(ex)
-class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
+class NewVmDlg(QtWidgets.QDialog, Ui_NewVMDlg):
def __init__(self, qtapp, app, parent=None):
super(NewVmDlg, self).__init__(parent)
self.setupUi(self)
@@ -111,7 +113,8 @@ def __init__(self, qtapp, app, parent=None):
self.name.setFocus()
if not self.template_list:
- QtGui.QMessageBox.warning(None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr('No template available!'),
self.tr('Cannot create a qube when no template exists.'))
@@ -140,7 +143,8 @@ def accept(self):
except LookupError:
pass
else:
- QtGui.QMessageBox.warning(None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr('Incorrect qube name!'),
self.tr('A qube with the name {} already exists in the '
'system!').format(name))
@@ -153,20 +157,19 @@ def accept(self):
else:
template = self.template_list[self.template_vm.currentIndex()]
- properties = {}
- properties['provides_network'] = self.provides_network.isChecked()
+ properties = {'provides_network': self.provides_network.isChecked()}
if self.netvm.currentIndex() != 0:
properties['netvm'] = self.netvm_list[self.netvm.currentIndex()]
if self.install_system.isChecked():
properties['virt_mode'] = 'hvm'
properties['kernel'] = None
- self.thread = CreateVMThread(self.app, vmclass, name, label,
- template, properties)
+ self.thread = CreateVMThread(
+ self.app, vmclass, name, label, template, properties)
self.thread.finished.connect(self.create_finished)
self.thread.start()
- self.progress = QtGui.QProgressDialog(
+ self.progress = QtWidgets.QProgressDialog(
self.tr("Creating new qube {}...").format(name), "", 0, 0)
self.progress.setCancelButton(None)
self.progress.setModal(True)
@@ -176,7 +179,8 @@ def create_finished(self):
self.progress.hide()
if self.thread.msg:
- QtGui.QMessageBox.warning(None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Error creating the qube!"),
self.tr("ERROR: {}").format(self.thread.msg))
@@ -185,12 +189,11 @@ def create_finished(self):
if not self.thread.msg:
if self.launch_settings.isChecked():
subprocess.check_call(['qubes-vm-settings',
- str(self.name.text())])
+ str(self.name.text())])
if self.install_system.isChecked():
subprocess.check_call(
['qubes-vm-boot-from-device', str(self.name.text())])
-
def type_change(self):
# AppVM
if self.vm_type.currentIndex() == 0:
@@ -221,12 +224,14 @@ def settings_change(self):
if self.launch_settings.isChecked() and self.install_system.isEnabled():
self.install_system.setChecked(False)
+
parser = qubesadmin.tools.QubesArgumentParser()
+
def main(args=None):
args = parser.parse_args(args)
- qtapp = QtGui.QApplication(sys.argv)
+ qtapp = QtWidgets.QApplication(sys.argv)
qtapp.setOrganizationName('Invisible Things Lab')
qtapp.setOrganizationDomain('https://www.qubes-os.org/')
qtapp.setApplicationName('Create qube')
diff --git a/qubesmanager/device_list.py b/qubesmanager/device_list.py
index a739b063..80a4b250 100644
--- a/qubesmanager/device_list.py
+++ b/qubesmanager/device_list.py
@@ -18,10 +18,10 @@
#
from . import ui_devicelist # pylint: disable=no-name-in-module
-from PyQt4 import QtGui, QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets # pylint: disable=import-error
-class PCIDeviceListWindow(ui_devicelist.Ui_Dialog, QtGui.QDialog):
+class PCIDeviceListWindow(ui_devicelist.Ui_Dialog, QtWidgets.QDialog):
def __init__(self, vm, qapp, dev_list, no_strict_reset_list, parent=None):
super(PCIDeviceListWindow, self).__init__(parent)
@@ -32,10 +32,8 @@ def __init__(self, vm, qapp, dev_list, no_strict_reset_list, parent=None):
self.setupUi(self)
- self.connect(
- self.buttonBox, QtCore.SIGNAL("accepted()"), self.save_and_apply)
- self.connect(
- self.buttonBox, QtCore.SIGNAL("rejected()"), self.reject)
+ self.buttonBox.accepted.connect(self.save_and_apply)
+ self.buttonBox.rejected.connect(self.reject)
self.ident_list = {}
self.fill_device_list()
diff --git a/qubesmanager/firewall.py b/qubesmanager/firewall.py
index 8e2f8f27..c1e595ed 100644
--- a/qubesmanager/firewall.py
+++ b/qubesmanager/firewall.py
@@ -21,7 +21,7 @@
import datetime
import re
-from PyQt4 import QtCore, QtGui # pylint: disable=import-error
+from PyQt5 import QtCore, QtGui, QtWidgets # pylint: disable=import-error
import qubesadmin.firewall
from . import ui_newfwruledlg # pylint: disable=no-name-in-module
@@ -30,6 +30,7 @@
class FirewallModifiedOutsideError(ValueError):
pass
+
class QIPAddressValidator(QtGui.QValidator):
# pylint: disable=too-few-public-methods
def __init__(self, parent=None):
@@ -40,10 +41,10 @@ def validate(self, input_string, pos):
hostname = str(input_string)
if len(hostname) > 255 or not hostname:
- return (QtGui.QValidator.Intermediate, input_string, pos)
+ return QtGui.QValidator.Intermediate, input_string, pos
if hostname == "*":
- return (QtGui.QValidator.Acceptable, input_string, pos)
+ return QtGui.QValidator.Acceptable, input_string, pos
unmask = hostname.split("/", 1)
if len(unmask) == 2:
@@ -51,27 +52,28 @@ def validate(self, input_string, pos):
mask = unmask[1]
if mask.isdigit() or mask == "":
if re.match(r"^([0-9]{1,3}\.){3}[0-9]{1,3}$", hostname) is None:
- return (QtGui.QValidator.Invalid, input_string, pos)
+ return QtGui.QValidator.Invalid, input_string, pos
if mask != "":
mask = int(unmask[1])
if mask < 0 or mask > 32:
- return (QtGui.QValidator.Invalid, input_string, pos)
+ return QtGui.QValidator.Invalid, input_string, pos
else:
- return (QtGui.QValidator.Invalid, input_string, pos)
+ return QtGui.QValidator.Invalid, input_string, pos
if hostname[-1:] == ".":
hostname = hostname[:-1]
if hostname[-1:] == "-":
- return (QtGui.QValidator.Intermediate, input_string, pos)
+ return QtGui.QValidator.Intermediate, input_string, pos
allowed = re.compile(r"(?!-)[A-Z\d-]{1,63}(?
@@ -307,7 +303,7 @@ def handle_exception(exc_type, exc_value, exc_traceback):
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
- QtGui.QMessageBox.critical(
+ QtWidgets.QMessageBox.critical(
None,
"Houston, we have a problem...",
"Whoops. A critical error has occured. This is most likely a bug "
@@ -317,7 +313,7 @@ def handle_exception(exc_type, exc_value, exc_traceback):
def main():
- qtapp = QtGui.QApplication(sys.argv)
+ qtapp = QtWidgets.QApplication(sys.argv)
qtapp.setOrganizationName("The Qubes Project")
qtapp.setOrganizationDomain("http://qubes-os.org")
qtapp.setApplicationName("Qubes Global Settings")
@@ -333,5 +329,6 @@ def main():
qtapp.exec_()
qtapp.exit()
+
if __name__ == "__main__":
main()
diff --git a/qubesmanager/informationnotes.py b/qubesmanager/informationnotes.py
index b512d3f8..b5adc326 100644
--- a/qubesmanager/informationnotes.py
+++ b/qubesmanager/informationnotes.py
@@ -20,7 +20,7 @@
# with this program; if not, see .
#
#
-from PyQt4.QtGui import QDialog # pylint: disable=import-error
+from PyQt5.QtWidgets import QDialog # pylint: disable=import-error
from . import ui_informationnotes # pylint: disable=no-name-in-module
import subprocess
diff --git a/qubesmanager/log_dialog.py b/qubesmanager/log_dialog.py
index 98ca5d8a..e0e999c8 100644
--- a/qubesmanager/log_dialog.py
+++ b/qubesmanager/log_dialog.py
@@ -20,8 +20,7 @@
#
#
import sys
-from PyQt4 import QtCore # pylint: disable=import-error
-from PyQt4 import QtGui # pylint: disable=import-error
+from PyQt5 import QtWidgets # pylint: disable=import-error
from . import ui_logdlg # pylint: disable=no-name-in-module
from . import clipboard
@@ -33,7 +32,7 @@
LOG_DISPLAY_SIZE = 1024*1024
-class LogDialog(ui_logdlg.Ui_LogDialog, QtGui.QDialog):
+class LogDialog(ui_logdlg.Ui_LogDialog, QtWidgets.QDialog):
# pylint: disable=too-few-public-methods
def __init__(self, app, log_path, parent=None):
@@ -45,9 +44,10 @@ def __init__(self, app, log_path, parent=None):
self.setupUi(self)
self.setWindowTitle(log_path)
- self.connect(self.copy_to_qubes_clipboard,
- QtCore.SIGNAL("clicked()"),
- self.copy_to_clipboard_triggered)
+ self.copy_to_qubes_clipboard.clicked.connect(
+ self.copy_to_clipboard_triggered)
+ self.copy_to_qubes_clipboard.clicked.connect(
+ self.copy_to_clipboard_triggered)
self.__init_log_text__()
@@ -64,6 +64,7 @@ def __init_log_text__(self):
self.displayed_text += log.read()
log.close()
self.log_text.setPlainText(self.displayed_text)
+ self.log_text.show()
def copy_to_clipboard_triggered(self):
clipboard.copy_text_to_qubes_clipboard(self.displayed_text)
@@ -71,7 +72,7 @@ def copy_to_clipboard_triggered(self):
def main():
qubes_app = Qubes()
- qt_app = QtGui.QApplication(sys.argv)
+ qt_app = QtWidgets.QApplication(sys.argv)
log_window = LogDialog(qubes_app, sys.argv[1])
log_window.show()
diff --git a/qubesmanager/multiselectwidget.py b/qubesmanager/multiselectwidget.py
index c7338898..bad80053 100644
--- a/qubesmanager/multiselectwidget.py
+++ b/qubesmanager/multiselectwidget.py
@@ -1,12 +1,13 @@
-from PyQt4 import QtCore, QtGui # pylint: disable=import-error
-from . import ui_multiselectwidget # pylint: disable=no-name-in-module
+from PyQt5 import QtCore, QtWidgets # pylint: disable=import-error
+from . import ui_multiselectwidget # pylint: disable=no-name-in-module
+
class MultiSelectWidget(
- ui_multiselectwidget.Ui_MultiSelectWidget, QtGui.QWidget):
+ ui_multiselectwidget.Ui_MultiSelectWidget, QtWidgets.QWidget):
- __pyqtSignals__ = ("selected_changed()",)
- __pyqtSignals__ = ("items_added(PyQt_PyObject)",)
- __pyqtSignals__ = ("items_removed(PyQt_PyObject)",)
+ selectedChanged = QtCore.pyqtSignal()
+ itemsAdded = QtCore.pyqtSignal(list)
+ itemsRemoved = QtCore.pyqtSignal(list)
def __init__(self, parent=None):
super(MultiSelectWidget, self).__init__(parent)
@@ -16,9 +17,9 @@ def __init__(self, parent=None):
self.remove_selected_button.clicked.connect(self.remove_selected)
self.remove_all_button.clicked.connect(self.remove_all)
self.available_list.setSelectionMode(
- QtGui.QAbstractItemView.ExtendedSelection)
+ QtWidgets.QAbstractItemView.ExtendedSelection)
self.selected_list.setSelectionMode(
- QtGui.QAbstractItemView.ExtendedSelection)
+ QtWidgets.QAbstractItemView.ExtendedSelection)
def switch_selected(self, src, dst):
selected = src.selectedItems()
@@ -30,11 +31,11 @@ def switch_selected(self, src, dst):
dst.addItem(item)
items.append(item)
dst.sortItems()
- self.emit(QtCore.SIGNAL("selected_changed()"))
+ self.selectedChanged.emit()
if src is self.selected_list:
- self.emit(QtCore.SIGNAL("items_removed(PyQt_PyObject)"), items)
+ self.itemsRemoved.emit(items)
else:
- self.emit(QtCore.SIGNAL("items_added(PyQt_PyObject)"), items)
+ self.itemsAdded.emit(items)
def add_selected(self):
self.switch_selected(self.available_list, self.selected_list)
@@ -49,12 +50,11 @@ def move_all(self, src, dst):
dst.addItem(item)
items.append(item)
dst.sortItems()
- self.emit(QtCore.SIGNAL("selected_changed()"))
+ self.selectedChanged.emit()
if src is self.selected_list:
- self.emit(QtCore.SIGNAL("items_removed(PyQt_PyObject)"), items)
+ self.itemsRemoved.emit(items)
else:
- self.emit(QtCore.SIGNAL("items_added(PyQt_PyObject)"), items)
-
+ self.itemsAdded.emit(items)
def add_all(self):
self.move_all(self.available_list, self.selected_list)
diff --git a/qubesmanager/qube_manager.py b/qubesmanager/qube_manager.py
index 015bac8f..e957981c 100644
--- a/qubesmanager/qube_manager.py
+++ b/qubesmanager/qube_manager.py
@@ -37,8 +37,7 @@
from qubesadmin import utils
from qubesadmin import events
-from PyQt4 import QtGui # pylint: disable=import-error
-from PyQt4 import QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets, QtCore, QtGui # pylint: disable=import-error
from qubesmanager.about import AboutDialog
@@ -54,7 +53,7 @@
from . import common_threads
-class SearchBox(QtGui.QLineEdit):
+class SearchBox(QtWidgets.QLineEdit):
def __init__(self, parent=None):
super(SearchBox, self).__init__(parent)
self.focusing = False
@@ -184,7 +183,7 @@ def update(self, update_size_on_disk=False, event=None):
# AdminAPI
pass
- #force re-sorting
+ # force re-sorting
self.table.setSortingEnabled(True)
@@ -229,16 +228,25 @@ def check_if_vm_has_shutdown(self):
if vm_is_running and vm_start_time \
and vm_start_time < self.shutdown_started:
if self.timeout_reached():
- reply = QtGui.QMessageBox.question(
- None, self.tr("Qube Shutdown"),
- self.tr(
+
+ msgbox = QtWidgets.QMessageBox(self.caller)
+ msgbox.setIcon(QtWidgets.QMessageBox.Question)
+ msgbox.setWindowTitle(self.tr("Qube Shutdown"))
+ msgbox.setText(self.tr(
"The Qube '{0}' hasn't shutdown within the last "
"{1} seconds, do you want to kill it?
").format(
- vm.name, self.shutdown_time / 1000),
- self.tr("Kill it!"),
+ vm.name, self.shutdown_time / 1000))
+ kill_button = msgbox.addButton(
+ self.tr("Kill it!"), QtWidgets.QMessageBox.YesRole)
+ wait_button = msgbox.addButton(
self.tr("Wait another {0} seconds...").format(
- self.shutdown_time / 1000))
- if reply == 0:
+ self.shutdown_time / 1000),
+ QtWidgets.QMessageBox.NoRole)
+ msgbox.setDefaultButton(wait_button)
+ msgbox.exec_()
+ msgbox.deleteLater()
+
+ if msgbox.clickedButton() is kill_button:
try:
vm.kill()
except exc.QubesVMNotStartedError:
@@ -290,8 +298,9 @@ def run(self):
user="root",
input=dsa4371update.read())
if stdout == b'changed=yes\n':
- subprocess.call(['notify-send', '-i', 'dialog-information',
- 'Debian DSA-4371 fix installed in {}'.format(
+ subprocess.call(
+ ['notify-send', '-i', 'dialog-information',
+ 'Debian DSA-4371 fix installed in {}'.format(
self.vm.name)])
elif stdout == b'changed=no\n':
pass
@@ -299,8 +308,8 @@ def run(self):
raise exc.QubesException(
"Failed to apply DSA-4371 fix: {}".format(
stderr.decode('ascii')))
- self.vm.run_service("qubes.InstallUpdatesGUI",\
- user="root", wait=False)
+ self.vm.run_service("qubes.InstallUpdatesGUI",
+ user="root", wait=False)
except (ChildProcessError, exc.QubesException) as ex:
self.msg = ("Error on qube update!", str(ex))
@@ -318,7 +327,7 @@ def run(self):
self.msg = ("Error while running command!", str(ex))
-class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
+class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtWidgets.QMainWindow):
# pylint: disable=too-many-instance-attributes
row_height = 30
column_width = 200
@@ -337,8 +346,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
"Include in backups": 9,
"Last backup": 10,
"Default DispVM": 11,
- "Is DVM Template": 12
- }
+ "Is DVM Template": 12}
def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
# pylint: disable=unused-argument
@@ -355,8 +363,7 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
QtCore.QRegExp("[a-zA-Z0-9_-]*", QtCore.Qt.CaseInsensitive), None))
self.searchContainer.addWidget(self.searchbox)
- self.connect(self.table, QtCore.SIGNAL("itemSelectionChanged()"),
- self.table_selection_changed)
+ self.table.itemSelectionChanged.connect(self.table_selection_changed)
self.table.setColumnWidth(0, self.column_width)
@@ -393,12 +400,12 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.table.setColumnWidth(self.columns_indices["Label"], 40)
self.table.setColumnWidth(self.columns_indices["Type"], 40)
- self.table.horizontalHeader().setResizeMode(
- QtGui.QHeaderView.Interactive)
+ self.table.horizontalHeader().setSectionResizeMode(
+ QtWidgets.QHeaderView.Interactive)
self.table.horizontalHeader().setStretchLastSection(True)
self.table.horizontalHeader().setMinimumSectionSize(40)
- self.context_menu = QtGui.QMenu(self)
+ self.context_menu = QtWidgets.QMenu(self)
self.context_menu.addAction(self.action_settings)
self.context_menu.addAction(self.action_editfwrules)
@@ -423,11 +430,11 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.context_menu.addMenu(self.logs_menu)
self.context_menu.addSeparator()
- self.tools_context_menu = QtGui.QMenu(self)
+ self.tools_context_menu = QtWidgets.QMenu(self)
self.tools_context_menu.addAction(self.action_toolbar)
self.tools_context_menu.addAction(self.action_menubar)
- self.dom0_context_menu = QtGui.QMenu(self)
+ self.dom0_context_menu = QtWidgets.QMenu(self)
self.dom0_context_menu.addAction(self.action_global_settings)
self.dom0_context_menu.addAction(self.action_updatevm)
self.dom0_context_menu.addSeparator()
@@ -435,42 +442,29 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.dom0_context_menu.addMenu(self.logs_menu)
self.dom0_context_menu.addSeparator()
- self.connect(
- self.table.horizontalHeader(),
- QtCore.SIGNAL("sortIndicatorChanged(int, Qt::SortOrder)"),
+ self.table.horizontalHeader().sortIndicatorChanged.connect(
self.sort_indicator_changed)
- self.connect(self.table,
- QtCore.SIGNAL("customContextMenuRequested(const QPoint&)"),
- self.open_context_menu)
- self.connect(self.menubar,
- QtCore.SIGNAL("customContextMenuRequested(const QPoint&)"),
- lambda pos: self.open_tools_context_menu(self.menubar,
- pos))
- self.connect(self.toolbar,
- QtCore.SIGNAL("customContextMenuRequested(const QPoint&)"),
- lambda pos: self.open_tools_context_menu(self.toolbar,
- pos))
- self.connect(self.logs_menu, QtCore.SIGNAL("triggered(QAction *)"),
- self.show_log)
-
- self.connect(self.searchbox,
- QtCore.SIGNAL("textChanged(const QString&)"),
- self.do_search)
+ self.table.customContextMenuRequested.connect(self.open_context_menu)
+ self.menubar.customContextMenuRequested.connect(
+ lambda pos: self.open_tools_context_menu(self.menubar, pos))
+ self.toolbar.customContextMenuRequested.connect(
+ lambda pos: self.open_tools_context_menu(self.toolbar, pos))
+ self.logs_menu.triggered.connect(self.show_log)
+
+ self.searchbox.textChanged.connect(self.do_search)
self.table.setContentsMargins(0, 0, 0, 0)
self.centralwidget.layout().setContentsMargins(0, 0, 0, 0)
self.layout().setContentsMargins(0, 0, 0, 0)
- self.connect(self.action_menubar, QtCore.SIGNAL("toggled(bool)"),
- self.showhide_menubar)
- self.connect(self.action_toolbar, QtCore.SIGNAL("toggled(bool)"),
- self.showhide_toolbar)
+ self.action_menubar.toggled.connect(self.showhide_menubar)
+ self.action_toolbar.toggled.connect(self.showhide_toolbar)
try:
self.load_manager_settings()
except Exception as ex: # pylint: disable=broad-except
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Manager settings unreadable"),
self.tr("Qube Manager settings cannot be parsed. Previously "
"saved display settings may not be restored "
@@ -492,7 +486,7 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.on_domain_status_changed)
dispatcher.add_handler('domain-stopped', self.on_domain_status_changed)
dispatcher.add_handler('domain-pre-shutdown',
- self.on_domain_status_changed)
+ self.on_domain_status_changed)
dispatcher.add_handler('domain-shutdown', self.on_domain_status_changed)
dispatcher.add_handler('domain-paused', self.on_domain_status_changed)
dispatcher.add_handler('domain-unpaused', self.on_domain_status_changed)
@@ -517,6 +511,10 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
timer.start(1000 * 30) # 30s
self.check_updates()
+ # select the first row of the table to make sure menu actions are
+ # correctly initialized
+ self.table.selectRow(0)
+
def keyPressEvent(self, event): # pylint: disable=invalid-name
if event.key() == QtCore.Qt.Key_Escape:
self.searchbox.clear()
@@ -532,13 +530,13 @@ def clear_threads(self):
if thread.msg:
(title, msg) = thread.msg
if thread.msg_is_success:
- QtGui.QMessageBox.information(
- None,
+ QtWidgets.QMessageBox.information(
+ self,
self.tr(title),
self.tr(msg))
else:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr(title),
self.tr(msg))
@@ -586,7 +584,7 @@ def on_domain_removed(self, _submitter, _event, **kwargs):
row_to_delete = row
qid_to_delete = qid
if not row_to_delete:
- return # for some reason, the VM was removed in some other way
+ return # for some reason, the VM was removed in some other way
del self.vms_in_table[qid_to_delete]
self.table.removeRow(row_to_delete.name_widget.row())
@@ -663,7 +661,7 @@ def fill_table(self):
self.table.setRowCount(len(vms_list))
- progress = QtGui.QProgressDialog(
+ progress = QtWidgets.QProgressDialog(
self.tr(
"Loading Qube Manager..."), "", 0, len(vms_list))
progress.setWindowTitle(self.tr("Qube Manager"))
@@ -806,7 +804,7 @@ def action_removevm_triggered(self):
manager_utils.format_dependencies_list(dependencies) + \
"
"
- info_dialog = QtGui.QMessageBox(self)
+ info_dialog = QtWidgets.QMessageBox(self)
info_dialog.setWindowTitle(self.tr("Warning!"))
info_dialog.setText(
self.tr("This qube cannot be removed. It is used as:"
@@ -818,8 +816,8 @@ def action_removevm_triggered(self):
return
- (requested_name, ok) = QtGui.QInputDialog.getText(
- None, self.tr("Qube Removal Confirmation"),
+ (requested_name, ok) = QtWidgets.QInputDialog.getText(
+ self, self.tr("Qube Removal Confirmation"),
self.tr("Are you sure you want to remove the Qube '{0}'"
"?
All data on this Qube's private storage will be "
"lost!
Type the name of the Qube ({1}) below "
@@ -831,8 +829,8 @@ def action_removevm_triggered(self):
if requested_name != vm.name:
# name did not match
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Qube removal confirmation failed"),
self.tr(
"Entered name did not match! Not removing "
@@ -856,7 +854,7 @@ def action_clonevm_triggered(self):
while name_format % name_number in self.qubes_app.domains.keys():
name_number += 1
- (clone_name, ok) = QtGui.QInputDialog.getText(
+ (clone_name, ok) = QtWidgets.QInputDialog.getText(
self, self.tr('Qubes clone Qube'),
self.tr('Enter name for Qube {} clone:').format(vm.name),
text=(name_format % name_number))
@@ -866,13 +864,13 @@ def action_clonevm_triggered(self):
name_in_use = clone_name in self.qubes_app.domains
if name_in_use:
- QtGui.QMessageBox.warning(
- None, self.tr("Name already in use!"),
+ QtWidgets.QMessageBox.warning(
+ self, self.tr("Name already in use!"),
self.tr("There already exists a qube called '{}'. "
"Cloning aborted.").format(clone_name))
return
- self.progress = QtGui.QProgressDialog(
+ self.progress = QtWidgets.QProgressDialog(
self.tr(
"Cloning Qube..."), "", 0, 0)
self.progress.setCancelButton(None)
@@ -894,8 +892,8 @@ def action_resumevm_triggered(self):
try:
vm.unpause()
except exc.QubesException as ex:
- QtGui.QMessageBox.warning(
- None, self.tr("Error unpausing Qube!"),
+ QtWidgets.QMessageBox.warning(
+ self, self.tr("Error unpausing Qube!"),
self.tr("ERROR: {0}").format(ex))
return
@@ -923,8 +921,8 @@ def action_pausevm_triggered(self):
try:
vm.pause()
except exc.QubesException as ex:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Error pausing Qube!"),
self.tr("ERROR: {0}").format(ex))
return
@@ -934,14 +932,15 @@ def action_pausevm_triggered(self):
def action_shutdownvm_triggered(self):
vm = self.get_selected_vm()
- reply = QtGui.QMessageBox.question(
- None, self.tr("Qube Shutdown Confirmation"),
+ reply = QtWidgets.QMessageBox.question(
+ self, self.tr("Qube Shutdown Confirmation"),
self.tr("Are you sure you want to power down the Qube"
" '{0}'?
This will shutdown all the "
"running applications within this Qube.").format(
- vm.name), QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
+ vm.name),
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
- if reply == QtGui.QMessageBox.Yes:
+ if reply == QtWidgets.QMessageBox.Yes:
self.shutdown_vm(vm)
def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout,
@@ -949,8 +948,8 @@ def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout,
try:
vm.shutdown()
except exc.QubesException as ex:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Error shutting down Qube!"),
self.tr("ERROR: {0}").format(ex))
return
@@ -967,14 +966,14 @@ def shutdown_vm(self, vm, shutdown_time=vm_shutdown_timeout,
def action_restartvm_triggered(self):
vm = self.get_selected_vm()
- reply = QtGui.QMessageBox.question(
- None, self.tr("Qube Restart Confirmation"),
+ reply = QtWidgets.QMessageBox.question(
+ self, self.tr("Qube Restart Confirmation"),
self.tr("Are you sure you want to restart the Qube '{0}'?"
"
This will shutdown all the running "
"applications within this Qube.").format(vm.name),
- QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
- if reply == QtGui.QMessageBox.Yes:
+ if reply == QtWidgets.QMessageBox.Yes:
# in case the user shut down the VM in the meantime
if vm.is_running():
self.shutdown_vm(vm, and_restart=True)
@@ -997,17 +996,17 @@ def action_killvm_triggered(self):
"shutdown!) all the running applications within "
"this Qube.").format(vm.name)
- reply = QtGui.QMessageBox.question(
- None, self.tr("Qube Kill Confirmation"), info,
- QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel,
- QtGui.QMessageBox.Cancel)
+ reply = QtWidgets.QMessageBox.question(
+ self, self.tr("Qube Kill Confirmation"), info,
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel,
+ QtWidgets.QMessageBox.Cancel)
- if reply == QtGui.QMessageBox.Yes:
+ if reply == QtWidgets.QMessageBox.Yes:
try:
vm.kill()
except exc.QubesException as ex:
- QtGui.QMessageBox.critical(
- None, self.tr("Error while killing Qube!"),
+ QtWidgets.QMessageBox.critical(
+ self, self.tr("Error while killing Qube!"),
self.tr(
"An exception ocurred while killing {0}.
"
"ERROR: {1}").format(vm.name, ex))
@@ -1057,13 +1056,13 @@ def action_updatevm_triggered(self):
vm = self.get_selected_vm()
if not vm.is_running():
- reply = QtGui.QMessageBox.question(
- None, self.tr("Qube Update Confirmation"),
+ reply = QtWidgets.QMessageBox.question(
+ self, self.tr("Qube Update Confirmation"),
self.tr(
"{0}
The Qube has to be running to be updated."
"
Do you want to start it?
").format(vm.name),
- QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
- if reply != QtGui.QMessageBox.Yes:
+ QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
+ if reply != QtWidgets.QMessageBox.Yes:
return
thread = UpdateVMThread(vm)
@@ -1071,14 +1070,13 @@ def action_updatevm_triggered(self):
thread.finished.connect(self.clear_threads)
thread.start()
-
# noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_run_command_in_vm_triggered')
def action_run_command_in_vm_triggered(self):
# pylint: disable=invalid-name
vm = self.get_selected_vm()
- (command_to_run, ok) = QtGui.QInputDialog.getText(
+ (command_to_run, ok) = QtWidgets.QInputDialog.getText(
self, self.tr('Qubes command entry'),
self.tr('Run command in {}:').format(vm.name))
if not ok or command_to_run == "":
@@ -1101,8 +1099,8 @@ def action_set_keyboard_layout_triggered(self):
def action_editfwrules_triggered(self):
with common_threads.busy_cursor():
vm = self.get_selected_vm()
- settings_window = settings.VMSettingsWindow(vm, self.qt_app,\
- "firewall")
+ settings_window = settings.VMSettingsWindow(vm, self.qt_app,
+ "firewall")
settings_window.exec_()
# noinspection PyArgumentList
@@ -1132,16 +1130,16 @@ def action_show_network_triggered(self):
@QtCore.pyqtSlot(name='on_action_restore_triggered')
def action_restore_triggered(self):
with common_threads.busy_cursor():
- restore_window = restore.RestoreVMsWindow(self.qt_app,\
- self.qubes_app)
+ restore_window = restore.RestoreVMsWindow(self.qt_app,
+ self.qubes_app)
restore_window.exec_()
# noinspection PyArgumentList
@QtCore.pyqtSlot(name='on_action_backup_triggered')
def action_backup_triggered(self):
with common_threads.busy_cursor():
- backup_window = backup.BackupVMsWindow(self.qt_app, self.qubes_app,
- self.dispatcher, self)
+ backup_window = backup.BackupVMsWindow(
+ self.qt_app, self.qubes_app, self.dispatcher, self)
backup_window.show()
# noinspection PyArgumentList
@@ -1227,7 +1225,7 @@ def action_about_qubes_triggered(self): # pylint: disable=no-self-use
about.exec_()
def createPopupMenu(self): # pylint: disable=invalid-name
- menu = QtGui.QMenu()
+ menu = QtWidgets.QMenu()
menu.addAction(self.action_toolbar)
menu.addAction(self.action_menubar)
return menu
@@ -1302,9 +1300,9 @@ def handle_exception(exc_type, exc_value, exc_traceback):
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
- msg_box = QtGui.QMessageBox()
+ msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
- msg_box.setIcon(QtGui.QMessageBox.Critical)
+ msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.
"
@@ -1323,7 +1321,7 @@ def loop_shutdown():
def main():
- qt_app = QtGui.QApplication(sys.argv)
+ qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qube Manager")
diff --git a/qubesmanager/releasenotes.py b/qubesmanager/releasenotes.py
index fd781d5d..7ac3a7c1 100644
--- a/qubesmanager/releasenotes.py
+++ b/qubesmanager/releasenotes.py
@@ -20,7 +20,7 @@
# with this program; if not, see .
#
#
-from PyQt4.QtGui import QDialog # pylint: disable=import-error
+from PyQt5.QtWidgets import QDialog # pylint: disable=import-error
from . import ui_releasenotes # pylint: disable=no-name-in-module
diff --git a/qubesmanager/restore.py b/qubesmanager/restore.py
index d8a4a276..a38f46f2 100644
--- a/qubesmanager/restore.py
+++ b/qubesmanager/restore.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python2
+#!/usr/bin/python3
#
# The Qubes OS Project, http://www.qubes-os.org
#
@@ -21,8 +21,7 @@
#
import sys
-from PyQt4 import QtCore # pylint: disable=import-error
-from PyQt4 import QtGui # pylint: disable=import-error
+from PyQt5 import QtCore, QtWidgets # pylint: disable=import-error
import os
import os.path
import traceback
@@ -36,7 +35,7 @@
from . import backup_utils
from multiprocessing import Queue
-from multiprocessing.queues import Empty
+from queue import Empty
from qubesadmin import Qubes, exc
from qubesadmin.backup import restore
@@ -72,7 +71,7 @@ def run(self):
self.tr("Finished successfully!"))
-class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
+class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtWidgets.QWizard):
def __init__(self, qt_app, qubes_app, parent=None):
super(RestoreVMsWindow, self).__init__(parent)
@@ -101,22 +100,16 @@ def __init__(self, qt_app, qubes_app, parent=None):
self.select_vms_widget = multiselectwidget.MultiSelectWidget(self)
self.select_vms_layout.insertWidget(1, self.select_vms_widget)
- self.connect(self,
- QtCore.SIGNAL("currentIdChanged(int)"),
- self.current_page_changed)
- self.dir_line_edit.connect(self.dir_line_edit,
- QtCore.SIGNAL("textChanged(QString)"),
- self.backup_location_changed)
+ self.currentIdChanged.connect(self.current_page_changed)
+ self.dir_line_edit.textChanged.connect(self.backup_location_changed)
self.select_dir_page.isComplete = self.has_selected_dir
self.select_vms_page.isComplete = self.has_selected_vms
self.confirm_page.isComplete = self.all_vms_good
# FIXME
# this causes to run isComplete() twice, I don't know why
- self.select_vms_page.connect(
- self.select_vms_widget,
- QtCore.SIGNAL("selected_changed()"),
- QtCore.SIGNAL("completeChanged()"))
+ self.select_vms_widget.selectedChanged.connect(
+ self.select_vms_page.completeChanged.emit)
backup_utils.fill_appvms_list(self)
@@ -169,7 +162,8 @@ def __fill_vms_list__(self):
continue
self.select_vms_widget.available_list.addItem(vmname)
except exc.QubesException as ex:
- QtGui.QMessageBox.warning(None, self.tr("Restore error!"), str(ex))
+ QtWidgets.QMessageBox.warning(
+ self, self.tr("Restore error!"), str(ex))
self.restart()
def append_output(self, text):
@@ -201,7 +195,7 @@ def current_page_changed(self, page_id): # pylint: disable=unused-argument
self.confirm_text_edit.setFontFamily("Monospace")
self.confirm_text_edit.setText(self.func_output)
- self.confirm_page.emit(QtCore.SIGNAL("completeChanged()"))
+ self.confirm_page.completeChanged.emit()
elif self.currentPage() is self.commit_page:
self.button(self.FinishButton).setDisabled(True)
@@ -226,8 +220,8 @@ def thread_finished(self):
self.progress_bar.setValue(100)
if self.thread.msg:
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr("Restore qubes"),
self.tr(self.thread.msg))
@@ -260,7 +254,6 @@ def update_log(self):
except Empty:
pass
-
def all_vms_good(self):
for vm_info in self.vms_to_restore.values():
if not vm_info.vm:
@@ -296,7 +289,7 @@ def has_selected_vms(self):
def backup_location_changed(self, new_dir=None):
# pylint: disable=unused-argument
- self.select_dir_page.emit(QtCore.SIGNAL("completeChanged()"))
+ self.select_dir_page.completeChanged.emit()
# Bases on the original code by:
@@ -308,18 +301,16 @@ def handle_exception(exc_type, exc_value, exc_traceback):
filename = os.path.basename(filename)
error = "%s: %s" % (exc_type.__name__, exc_value)
- QtGui.QMessageBox.critical(None, "Houston, we have a problem...",
- "Whoops. A critical error has occured. "
- "This is most likely a bug "
- "in Qubes Restore VMs application.
"
- "%s" % error +
- "at line %d of file %s.
"
- % (line, filename))
+ QtWidgets.QMessageBox.critical(
+ None, "Houston, we have a problem...",
+ "Whoops. A critical error has occured. This is most likely a bug "
+ "in Qubes Restore VMs application.
%s" % error +
+ "at line %d of file %s.
" % (line, filename))
def main():
- qt_app = QtGui.QApplication(sys.argv)
+ qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qubes Restore VMs")
diff --git a/qubesmanager/settings.py b/qubesmanager/settings.py
index 40ec22b3..df83cc41 100644
--- a/qubesmanager/settings.py
+++ b/qubesmanager/settings.py
@@ -41,10 +41,11 @@
from .appmenu_select import AppmenuSelectManager
from . import firewall
-from PyQt4 import QtCore, QtGui # pylint: disable=import-error
+from PyQt5 import QtCore, QtWidgets, QtGui # pylint: disable=import-error
from . import ui_settingsdlg # pylint: disable=no-name-in-module
+
# pylint: disable=too-few-public-methods
class RenameVMThread(QtCore.QThread):
def __init__(self, vm, new_vm_name, dependencies):
@@ -121,7 +122,7 @@ def run(self):
# pylint: disable=too-many-instance-attributes
-class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
+class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtWidgets.QDialog):
tabs_indices = collections.OrderedDict((
('basic', 0),
('advanced', 1),
@@ -151,7 +152,7 @@ def __init__(self, vm, qapp, init_page="basic", parent=None):
assert idx in range(self.tabWidget.count())
self.tabWidget.setCurrentIndex(idx)
- self.buttonBox.button(QtGui.QDialogButtonBox.Apply).clicked.connect(
+ self.buttonBox.button(QtWidgets.QDialogButtonBox.Apply).clicked.connect(
self.apply)
self.tabWidget.currentChanged.connect(self.current_tab_changed)
@@ -177,12 +178,8 @@ def __init__(self, vm, qapp, init_page="basic", parent=None):
self.__init_advanced_tab__()
self.include_in_balancing.stateChanged.connect(
self.include_in_balancing_changed)
- self.connect(self.init_mem,
- QtCore.SIGNAL("editingFinished()"),
- self.check_mem_changes)
- self.connect(self.max_mem_size,
- QtCore.SIGNAL("editingFinished()"),
- self.check_mem_changes)
+ self.init_mem.editingFinished.connect(self.check_mem_changes)
+ self.max_mem_size.editingFinished.connect(self.check_mem_changes)
self.boot_from_device_button.clicked.connect(
self.boot_from_cdrom_button_pressed)
@@ -207,9 +204,7 @@ def __init__(self, vm, qapp, init_page="basic", parent=None):
####### devices tab
self.__init_devices_tab__()
- self.connect(self.dev_list,
- QtCore.SIGNAL("selected_changed()"),
- self.devices_selection_changed)
+ self.dev_list.selectedChanged.connect(self.devices_selection_changed)
self.no_strict_reset_button.clicked.connect(
self.strict_reset_button_pressed)
self.current_strict_reset_list = []
@@ -240,8 +235,8 @@ def clear_threads(self):
if thread.msg:
(title, msg) = thread.msg
- QtGui.QMessageBox.warning(
- None,
+ QtWidgets.QMessageBox.warning(
+ self,
self.tr(title),
self.tr(msg))
@@ -268,10 +263,10 @@ def save_changes(self):
error = self.__save_changes__()
if error:
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
- self.tr("Error while changing settings for {0}!"\
- ).format(self.vm.name),\
+ self.tr("Error while changing settings for {0}!"
+ ).format(self.vm.name),
self.tr("ERROR: {0}").format('\n'.join(error)))
def apply(self):
@@ -331,7 +326,7 @@ def check_network_availability(self):
netvm is not None and
not netvm.features.check_with_template('qubes-firewall', False))
if netvm is None:
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Qube configuration problem!"),
self.tr('This qube has networking disabled '
@@ -340,17 +335,17 @@ def check_network_availability(self):
'please enable networking.')
)
if netvm is not None and \
- not netvm.features.check_with_template(\
+ not netvm.features.check_with_template(
'qubes-firewall', False):
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Qube configuration problem!"),
- self.tr("The '{vm}' qube is network connected to "\
- "'{netvm}', which does not support firewall!
"\
- "You may edit the '{vm}' qube firewall rules, but "\
- "these will not take any effect until you connect it "\
- "to a working Firewall qube.").format(\
- vm=self.vm.name, netvm=netvm.name))
+ self.tr("The '{vm}' qube is network connected to "
+ "'{netvm}', which does not support firewall!
"
+ "You may edit the '{vm}' qube firewall rules, but "
+ "these will not take any effect until you connect it "
+ "to a working Firewall qube.").format(
+ vm=self.vm.name, netvm=netvm.name))
def current_tab_changed(self, idx):
if idx == self.tabs_indices["firewall"]:
@@ -536,7 +531,7 @@ def __apply_basic_tab__(self):
def check_mem_changes(self):
if self.max_mem_size.value() < self.init_mem.value():
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Warning!"),
self.tr("Max memory can not be less than initial memory.
"
@@ -546,7 +541,7 @@ def check_mem_changes(self):
# max_mem_size/10.79 in order to allow scaling up to
# max_mem_size (or else "add_memory() failed: -17" problem)
if self.init_mem.value() * 10 < self.max_mem_size.value():
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Warning!"),
self.tr("Initial memory can not be less than one tenth "
@@ -579,7 +574,6 @@ def check_warn_dispvmnetvm(self):
else:
self.warn_netvm_dispvm.setVisible(False)
-
def rename_vm(self):
dependencies = admin_utils.vm_dependencies(self.vm.app, self.vm)
@@ -589,7 +583,7 @@ def rename_vm(self):
and vm.is_running()]
if running_dependencies:
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Qube cannot be renamed!"),
self.tr(
@@ -599,7 +593,7 @@ def rename_vm(self):
", ".join(running_dependencies)))
return
- new_vm_name, ok = QtGui.QInputDialog.getText(
+ new_vm_name, ok = QtWidgets.QInputDialog.getText(
self,
self.tr('Rename qube'),
self.tr('New name: (WARNING: all other changes will be discarded)'))
@@ -609,7 +603,7 @@ def rename_vm(self):
self.threads_list.append(thread)
thread.finished.connect(self.clear_threads)
- self.progress = QtGui.QProgressDialog(
+ self.progress = QtWidgets.QProgressDialog(
self.tr(
"Renaming Qube..."), "", 0, 0)
self.progress.setCancelButton(None)
@@ -625,7 +619,7 @@ def remove_vm(self):
if dependencies:
list_text = utils.format_dependencies_list(dependencies)
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Qube cannot be removed!"),
self.tr("This qube cannot be removed. It is used as:"
@@ -635,8 +629,7 @@ def remove_vm(self):
return
-
- answer, ok = QtGui.QInputDialog.getText(
+ answer, ok = QtWidgets.QInputDialog.getText(
self,
self.tr('Delete qube'),
self.tr('Are you absolutely sure you want to delete this qube? '
@@ -650,14 +643,14 @@ def remove_vm(self):
self.done(0)
elif ok:
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Removal cancelled"),
self.tr("The qube will not be removed."))
def clone_vm(self):
- cloned_vm_name, ok = QtGui.QInputDialog.getText(
+ cloned_vm_name, ok = QtWidgets.QInputDialog.getText(
self,
self.tr('Clone qube'),
self.tr('Name for the cloned qube:'))
@@ -667,7 +660,7 @@ def clone_vm(self):
thread.finished.connect(self.clear_threads)
self.threads_list.append(thread)
- self.progress = QtGui.QProgressDialog(
+ self.progress = QtWidgets.QProgressDialog(
self.tr(
"Cloning Qube..."), "", 0, 0)
self.progress.setCancelButton(None)
@@ -867,9 +860,9 @@ def update_virt_mode_list(self):
self.virt_mode.clear()
- self.virt_mode_list, self.virt_mode_idx = utils.prepare_choice(\
- self.virt_mode, self.vm, 'virt_mode', choices, None,\
- allow_default=True, transform=(lambda x: str(x).upper()))
+ self.virt_mode_list, self.virt_mode_idx = utils.prepare_choice(
+ self.virt_mode, self.vm, 'virt_mode', choices, None,
+ allow_default=True, transform=(lambda x: str(x).upper()))
if old_mode is not None:
self.virt_mode.setCurrentIndex(self.virt_mode_list.index(old_mode))
@@ -924,7 +917,7 @@ def __init_devices_tab__(self):
attached_devs = list(self.vm.devices['pci'].persistent())
# pylint: disable=too-few-public-methods
- class DevListWidgetItem(QtGui.QListWidgetItem):
+ class DevListWidgetItem(QtWidgets.QListWidgetItem):
def __init__(self, dev, unknown=False, parent=None):
super(DevListWidgetItem, self).__init__(parent)
name = dev.ident.replace('_', ":") + ' ' + dev.description
@@ -1070,7 +1063,7 @@ def __init_services_tab__(self):
if not feature.startswith('service.'):
continue
service = feature[len('service.'):]
- item = QtGui.QListWidgetItem(service)
+ item = QtWidgets.QListWidgetItem(service)
item.setCheckState(ui_settingsdlg.QtCore.Qt.Checked
if self.vm.features[feature]
else ui_settingsdlg.QtCore.Qt.Unchecked)
@@ -1097,12 +1090,12 @@ def __add_service__(self):
srv = str(self.service_line_edit.currentText()).strip()
if srv != "":
if srv in self.new_srv_dict:
- QtGui.QMessageBox.information(
+ QtWidgets.QMessageBox.information(
self,
'',
self.tr('Service already on the list!'))
else:
- item = QtGui.QListWidgetItem(srv)
+ item = QtWidgets.QListWidgetItem(srv)
item.setCheckState(ui_settingsdlg.QtCore.Qt.Checked)
self.services_list.addItem(item)
self.new_srv_dict[srv] = True
@@ -1146,9 +1139,10 @@ def __apply_services_tab__(self):
def set_fw_model(self, model):
self.fw_model = model
self.rulesTreeView.setModel(model)
- self.rulesTreeView.header().setResizeMode(
- QtGui.QHeaderView.ResizeToContents)
- self.rulesTreeView.header().setResizeMode(0, QtGui.QHeaderView.Stretch)
+ self.rulesTreeView.header().setSectionResizeMode(
+ QtWidgets.QHeaderView.ResizeToContents)
+ self.rulesTreeView.header().setSectionResizeMode(
+ 0, QtWidgets.QHeaderView.Stretch)
self.set_allow(model.allow)
if model.temp_full_access_expire_time:
self.temp_full_access.setChecked(True)
@@ -1226,9 +1220,9 @@ def handle_exception(exc_type, exc_value, exc_traceback):
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
- msg_box = QtGui.QMessageBox()
+ msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
- msg_box.setIcon(QtGui.QMessageBox.Critical)
+ msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.
"
@@ -1254,7 +1248,7 @@ def main(args=None):
args = parser.parse_args(args)
vm = args.domains.pop()
- qapp = QtGui.QApplication(sys.argv)
+ qapp = QtWidgets.QApplication(sys.argv)
qapp.setOrganizationName('Invisible Things Lab')
qapp.setOrganizationDomain("https://www.qubes-os.org/")
qapp.setApplicationName("Qube Settings")
diff --git a/qubesmanager/table_widgets.py b/qubesmanager/table_widgets.py
index 438dba62..9ec9c1d0 100644
--- a/qubesmanager/table_widgets.py
+++ b/qubesmanager/table_widgets.py
@@ -20,8 +20,7 @@
# with this program; if not, see .
import datetime
-from PyQt4 import QtGui # pylint: disable=import-error
-from PyQt4 import QtCore # pylint: disable=import-error
+from PyQt5 import QtWidgets, QtCore, QtGui # pylint: disable=import-error
# pylint: disable=too-few-public-methods
power_order = QtCore.Qt.DescendingOrder
@@ -31,7 +30,7 @@
row_height = 30
-class VmIconWidget(QtGui.QWidget):
+class VmIconWidget(QtWidgets.QWidget):
def __init__(self, icon_path, enabled=True, size_multiplier=0.7,
tooltip=None, parent=None,
icon_sz=(32, 32)): # pylint: disable=unused-argument
@@ -39,13 +38,13 @@ def __init__(self, icon_path, enabled=True, size_multiplier=0.7,
self.enabled = enabled
self.size_multiplier = size_multiplier
- self.label_icon = QtGui.QLabel()
+ self.label_icon = QtWidgets.QLabel()
self.set_icon(icon_path)
if tooltip is not None:
self.label_icon.setToolTip(tooltip)
- layout = QtGui.QHBoxLayout()
+ layout = QtWidgets.QHBoxLayout()
layout.addWidget(self.label_icon)
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)
@@ -72,7 +71,7 @@ def set_icon(self, icon_path):
class VmTypeWidget(VmIconWidget):
- class VmTypeItem(QtGui.QTableWidgetItem):
+ class VmTypeItem(QtWidgets.QTableWidgetItem):
def __init__(self, value, vm):
super(VmTypeWidget.VmTypeItem, self).__init__()
self.value = value
@@ -82,7 +81,7 @@ def __init__(self, value, vm):
def set_value(self, value):
self.value = value
- #pylint: disable=too-many-return-statements
+ # pylint: disable=too-many-return-statements
def __lt__(self, other):
if self.qid == 0:
return True
@@ -120,7 +119,7 @@ def get_vm_icon(self, vm):
class VmLabelWidget(VmIconWidget):
- class VmLabelItem(QtGui.QTableWidgetItem):
+ class VmLabelItem(QtWidgets.QTableWidgetItem):
def __init__(self, value, vm):
super(VmLabelWidget.VmLabelItem, self).__init__()
self.value = value
@@ -130,7 +129,7 @@ def __init__(self, value, vm):
def set_value(self, value):
self.value = value
- #pylint: disable=too-many-return-statements
+ # pylint: disable=too-many-return-statements
def __lt__(self, other):
if self.qid == 0:
return True
@@ -159,10 +158,11 @@ def update(self):
self.set_icon(icon_path)
-class VmStatusIcon(QtGui.QLabel):
+class VmStatusIcon(QtWidgets.QLabel):
def __init__(self, vm, parent=None):
super(VmStatusIcon, self).__init__(parent)
self.vm = vm
+ self.status = None
self.set_on_icon()
self.previous_power_state = self.vm.get_power_state()
@@ -191,8 +191,8 @@ def set_on_icon(self):
self.setFixedSize(icon_sz)
-class VmInfoWidget(QtGui.QWidget):
- class VmInfoItem(QtGui.QTableWidgetItem):
+class VmInfoWidget(QtWidgets.QWidget):
+ class VmInfoItem(QtWidgets.QTableWidgetItem):
def __init__(self, on_icon, upd_info_item, vm):
super(VmInfoWidget.VmInfoItem, self).__init__()
self.on_icon = on_icon
@@ -232,7 +232,7 @@ def __lt__(self, other):
def __init__(self, vm, parent=None):
super(VmInfoWidget, self).__init__(parent)
self.vm = vm
- layout = QtGui.QHBoxLayout()
+ layout = QtWidgets.QHBoxLayout()
self.on_icon = VmStatusIcon(vm)
self.upd_info = VmUpdateInfoWidget(vm, show_text=False)
@@ -243,9 +243,9 @@ def __init__(self, vm, parent=None):
layout.addWidget(self.on_icon)
layout.addWidget(self.upd_info)
layout.addWidget(self.error_icon)
- layout.addItem(QtGui.QSpacerItem(0, 10,
- QtGui.QSizePolicy.Expanding,
- QtGui.QSizePolicy.Expanding))
+ layout.addItem(QtWidgets.QSpacerItem(0, 10,
+ QtWidgets.QSizePolicy.Expanding,
+ QtWidgets.QSizePolicy.Expanding))
layout.addWidget(self.blk_icon)
layout.addWidget(self.rec_icon)
@@ -256,15 +256,15 @@ def __init__(self, vm, parent=None):
self.blk_icon.setVisible(False)
self.error_icon.setVisible(False)
- self.table_item = self.VmInfoItem(self.on_icon,\
- self.upd_info.table_item, vm)
+ self.table_item = self.VmInfoItem(self.on_icon,
+ self.upd_info.table_item, vm)
def update_vm_state(self):
self.on_icon.update()
self.upd_info.update_outdated()
-class VMPropertyItem(QtGui.QTableWidgetItem):
+class VMPropertyItem(QtWidgets.QTableWidgetItem):
def __init__(self, vm, property_name, empty_function=(lambda x: False),
check_default=False):
"""
@@ -327,7 +327,7 @@ def update(self):
font = QtGui.QFont()
font.setStyle(QtGui.QFont.StyleItalic)
self.setFont(font)
- self.setTextColor(QtGui.QColor("gray"))
+ self.setForeground(QtGui.QBrush(QtGui.QColor("gray")))
self.setText(self.vm.klass)
@@ -342,8 +342,8 @@ def update(self):
# features man qvm-features
-class VmUpdateInfoWidget(QtGui.QWidget):
- class VmUpdateInfoItem(QtGui.QTableWidgetItem):
+class VmUpdateInfoWidget(QtWidgets.QWidget):
+ class VmUpdateInfoItem(QtWidgets.QTableWidgetItem):
def __init__(self, value, vm):
super(VmUpdateInfoWidget.VmUpdateInfoItem, self).__init__()
self.value = 0
@@ -371,13 +371,13 @@ def __lt__(self, other):
def __init__(self, vm, show_text=True, parent=None):
super(VmUpdateInfoWidget, self).__init__(parent)
- layout = QtGui.QHBoxLayout()
+ layout = QtWidgets.QHBoxLayout()
self.show_text = show_text
if self.show_text:
- self.label = QtGui.QLabel("")
+ self.label = QtWidgets.QLabel("")
layout.addWidget(self.label, alignment=QtCore.Qt.AlignCenter)
else:
- self.icon = QtGui.QLabel("")
+ self.icon = QtWidgets.QLabel("")
layout.addWidget(self.icon, alignment=QtCore.Qt.AlignCenter)
self.setLayout(layout)
@@ -432,6 +432,8 @@ def update_status_widget(self, state):
"The Template must be stopped before changes from its "
"current session can be picked up by this qube.")
else:
+ label_text = None
+ tooltip_text = None
icon_path = None
if hasattr(self, 'icon'):
@@ -445,12 +447,12 @@ def update_status_widget(self, state):
if icon_path is not None:
self.icon = VmIconWidget(icon_path, True, 0.7)
self.icon.setToolTip(tooltip_text)
- self.layout().addWidget(self.icon,\
- alignment=QtCore.Qt.AlignCenter)
+ self.layout().addWidget(self.icon,
+ alignment=QtCore.Qt.AlignCenter)
self.icon.setVisible(True)
-class VmSizeOnDiskItem(QtGui.QTableWidgetItem):
+class VmSizeOnDiskItem(QtWidgets.QTableWidgetItem):
def __init__(self, vm):
super(VmSizeOnDiskItem, self).__init__()
self.setFlags(QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEnabled)
diff --git a/qubesmanager/template_manager.py b/qubesmanager/template_manager.py
index 88e1a082..31ff0a98 100644
--- a/qubesmanager/template_manager.py
+++ b/qubesmanager/template_manager.py
@@ -32,10 +32,7 @@
from qubesadmin import exc
from qubesadmin import events
-from PyQt4 import QtGui # pylint: disable=import-error
-from PyQt4 import QtCore # pylint: disable=import-error
-from PyQt4 import Qt # pylint: disable=import-error
-
+from PyQt5 import QtWidgets, QtGui, QtCore # pylint: disable=import-error
from . import ui_templatemanager # pylint: disable=no-name-in-module
@@ -43,7 +40,7 @@
class TemplateManagerWindow(
- ui_templatemanager.Ui_MainWindow, QtGui.QMainWindow):
+ ui_templatemanager.Ui_MainWindow, QtWidgets.QMainWindow):
def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
# pylint: disable=unused-argument
@@ -61,11 +58,11 @@ def __init__(self, qt_app, qubes_app, dispatcher, parent=None):
self.prepare_lists()
self.initialize_table_events()
- self.buttonBox.button(QtGui.QDialogButtonBox.Ok).clicked.connect(
+ self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok).clicked.connect(
self.apply)
- self.buttonBox.button(QtGui.QDialogButtonBox.Cancel).clicked.connect(
- self.cancel)
- self.buttonBox.button(QtGui.QDialogButtonBox.Reset).clicked.connect(
+ self.buttonBox.button(
+ QtWidgets.QDialogButtonBox.Cancel).clicked.connect(self.cancel)
+ self.buttonBox.button(QtWidgets.QDialogButtonBox.Reset).clicked.connect(
self.reset)
self.change_all_combobox.currentIndexChanged.connect(
@@ -118,7 +115,7 @@ def initialize_table_events(self):
def vm_added(self, _submitter, _event, vm, **_kwargs):
# unfortunately, a VM just in the moment of creation may not have
# a template it will have in a second - e.g., when cloning
- timer = Qt.QTimer()
+ timer = QtCore.QTimer()
timer.setSingleShot(True)
timer.timeout.connect(lambda: self._vm_added(vm, timer))
self.timers.append(timer)
@@ -239,7 +236,7 @@ def apply(self):
errors[vm] = str(ex)
if errors:
error_messages = [vm + ": " + errors[vm] for vm in errors]
- QtGui.QMessageBox.warning(
+ QtWidgets.QMessageBox.warning(
self,
self.tr("Errors encountered!"),
self.tr(
@@ -248,7 +245,7 @@ def apply(self):
self.close()
-class VMNameItem(QtGui.QTableWidgetItem):
+class VMNameItem(QtWidgets.QTableWidgetItem):
# pylint: disable=too-few-public-methods
def __init__(self, vm):
super(VMNameItem, self).__init__()
@@ -258,7 +255,7 @@ def __init__(self, vm):
self.setIcon(QtGui.QIcon.fromTheme(vm.label.icon))
-class StatusItem(QtGui.QTableWidgetItem):
+class StatusItem(QtWidgets.QTableWidgetItem):
def __init__(self, vm):
super(StatusItem, self).__init__()
self.vm = vm
@@ -281,7 +278,7 @@ def __lt__(self, other):
return self.state < other.state
-class CurrentTemplateItem(QtGui.QTableWidgetItem):
+class CurrentTemplateItem(QtWidgets.QTableWidgetItem):
# pylint: disable=too-few-public-methods
def __init__(self, vm):
super(CurrentTemplateItem, self).__init__()
@@ -295,7 +292,7 @@ def __lt__(self, other):
return self.text() < other.text()
-class NewTemplateItem(QtGui.QComboBox):
+class NewTemplateItem(QtWidgets.QComboBox):
def __init__(self, vm, templates, table_widget):
super(NewTemplateItem, self).__init__()
self.vm = vm
@@ -331,7 +328,7 @@ def __init__(self, vm, row_no, table_widget, columns, templates):
# state
self.state_item = StatusItem(self.vm)
table_widget.setItem(row_no, columns.index('State'), self.state_item)
- self.checkbox = QtGui.QCheckBox()
+ self.checkbox = QtWidgets.QCheckBox()
# icon and name
self.name_item = VMNameItem(self.vm)
@@ -343,7 +340,7 @@ def __init__(self, vm, row_no, table_widget, columns, templates):
self.current_item)
# new template
- self.dummy_new_item = QtGui.QTableWidgetItem("qube is running")
+ self.dummy_new_item = QtWidgets.QTableWidgetItem("qube is running")
self.new_item = NewTemplateItem(self.vm, templates, table_widget)
table_widget.setItem(row_no, columns.index('New template'),
@@ -367,7 +364,7 @@ def vm_state_change(self, is_running, row=None):
if not is_running:
self.new_item = NewTemplateItem(self.vm, self.templates,
self.table_widget)
- self.checkbox = QtGui.QCheckBox()
+ self.checkbox = QtWidgets.QCheckBox()
self.table_widget.setCellWidget(
row, column_names.index('New template'), self.new_item)
@@ -408,9 +405,9 @@ def handle_exception(exc_type, exc_value, exc_traceback):
strace += "line no.: %d\n" % line
strace += "file: %s\n" % filename
- msg_box = QtGui.QMessageBox()
+ msg_box = QtWidgets.QMessageBox()
msg_box.setDetailedText(strace)
- msg_box.setIcon(QtGui.QMessageBox.Critical)
+ msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setWindowTitle("Houston, we have a problem...")
msg_box.setText("Whoops. A critical error has occured. "
"This is most likely a bug in Qubes Manager.
"
@@ -429,7 +426,7 @@ def loop_shutdown():
def main():
- qt_app = QtGui.QApplication(sys.argv)
+ qt_app = QtWidgets.QApplication(sys.argv)
qt_app.setOrganizationName("The Qubes Project")
qt_app.setOrganizationDomain("http://qubes-os.org")
qt_app.setApplicationName("Qube Manager")
@@ -450,7 +447,7 @@ def main():
asyncio.ensure_future(dispatcher.listen_for_events()))
except asyncio.CancelledError:
pass
- except Exception: # pylint: disable=broad-except
+ except Exception: # pylint: disable=broad-except
loop_shutdown()
exc_type, exc_value, exc_traceback = sys.exc_info()[:3]
handle_exception(exc_type, exc_value, exc_traceback)
diff --git a/qubesmanager/utils.py b/qubesmanager/utils.py
index a6a1351f..d3ae1d38 100644
--- a/qubesmanager/utils.py
+++ b/qubesmanager/utils.py
@@ -24,16 +24,18 @@
import re
import qubesadmin
-from PyQt4.QtGui import QIcon # pylint: disable=import-error
+from PyQt5.QtGui import QIcon # pylint: disable=import-error
+
def _filter_internal(vm):
return (not vm.klass == 'AdminVM'
- and not vm.features.get('internal', False))
+ and not vm.features.get('internal', False))
+
def prepare_choice(widget, holder, propname, choice, default,
- filter_function=None, *,
- icon_getter=None, allow_internal=None, allow_default=False,
- allow_none=False, transform=None):
+ filter_function=None, *,
+ icon_getter=None, allow_internal=None, allow_default=False,
+ allow_none=False, transform=None):
# for newly created vms, set propname to None
@@ -112,10 +114,13 @@ def prepare_choice(widget, holder, propname, choice, default,
return choice_list, idx
+
def prepare_kernel_choice(widget, holder, propname, default, *args, **kwargs):
# TODO get from storage API (pool 'linux-kernel') (suggested by @marmarta)
return prepare_choice(widget, holder, propname,
- os.listdir('/var/lib/qubes/vm-kernels'), default, *args, **kwargs)
+ os.listdir('/var/lib/qubes/vm-kernels'),
+ default, *args, **kwargs)
+
def prepare_label_choice(widget, holder, propname, default, *args, **kwargs):
try:
@@ -124,10 +129,12 @@ def prepare_label_choice(widget, holder, propname, default, *args, **kwargs):
app = holder
return prepare_choice(widget, holder, propname,
- sorted(app.labels.values(), key=lambda l: l.index),
- default, *args,
- icon_getter=(lambda label: QIcon.fromTheme(label.icon)),
- **kwargs)
+ sorted(app.labels.values(), key=lambda l: l.index),
+ default, *args,
+ icon_getter=(lambda label:
+ QIcon.fromTheme(label.icon)),
+ **kwargs)
+
def prepare_vm_choice(widget, holder, propname, default, *args, **kwargs):
try:
@@ -136,11 +143,13 @@ def prepare_vm_choice(widget, holder, propname, default, *args, **kwargs):
app = holder
return prepare_choice(widget, holder, propname, app.domains, default,
- *args, **kwargs)
+ *args, **kwargs)
+
def is_debug():
return os.getenv('QUBES_MANAGER_DEBUG', '') not in ('', '0')
+
def debug(*args, **kwargs):
if not is_debug():
return
diff --git a/rpm_spec/qmgr.spec.in b/rpm_spec/qmgr.spec.in
index 49a3d59a..5b363c46 100644
--- a/rpm_spec/qmgr.spec.in
+++ b/rpm_spec/qmgr.spec.in
@@ -8,7 +8,7 @@ Vendor: Invisible Things Lab
License: GPL
URL: http://fixme
Requires: python3
-Requires: python3-PyQt4
+Requires: python3-PyQt5
Requires: python3-inotify
Requires: python3-qubesadmin >= 4.0.19
Requires: python3-Quamash
@@ -17,9 +17,10 @@ Requires: qubes-artwork
Requires: pmount
Requires: cryptsetup
Requires: wmctrl
-BuildRequires: python3-PyQt4-devel
+BuildRequires: python3-PyQt5-devel
BuildRequires: python3-devel
-BuildRequires: qt-devel
+BuildRequires: qt5-devel
+BuildRequires: qt5-linguist
AutoReq: 0
Source0: %{name}-%{version}.tar.gz
diff --git a/ui/restoredlg.ui b/ui/restoredlg.ui
index bb3df0a5..517df942 100644
--- a/ui/restoredlg.ui
+++ b/ui/restoredlg.ui
@@ -6,8 +6,8 @@
0
0
- 700
- 399
+ 756
+ 440
@@ -214,7 +214,7 @@
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
p, li { white-space: pre-wrap; }
-</style></head><body style=" font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;">
+</style></head><body style=" font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;">
<p style="-qt-paragraph-type:empty; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px; font-family:'Sans Serif'; font-size:9pt;"><br /></p></body></html>