Skip to content

Commit

Permalink
Update Qt version used in qubesmanager to Qt5
Browse files Browse the repository at this point in the history
Fixed dependencies, places where obsolete functions stopped working,
code fragments that started throwing warnings and an .ui file that
stopped being readable after the update.
  • Loading branch information
marmarta committed May 30, 2019
1 parent 492b870 commit e79724f
Show file tree
Hide file tree
Showing 25 changed files with 456 additions and 457 deletions.
8 changes: 4 additions & 4 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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/
Expand Down
2 changes: 1 addition & 1 deletion build-deps.list
Original file line number Diff line number Diff line change
@@ -1 +1 @@
PyQt4-devel
PyQt5-devel
5 changes: 4 additions & 1 deletion qubesmanager/about.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,8 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
#
#
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

Expand All @@ -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_()
13 changes: 7 additions & 6 deletions qubesmanager/appmenu_select.py
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand All @@ -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
Expand Down
78 changes: 33 additions & 45 deletions qubesmanager/backup.py
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -45,6 +45,7 @@
import asyncio
from contextlib import suppress


# pylint: disable=too-few-public-methods
class BackupThread(QtCore.QThread):
def __init__(self, vm):
Expand All @@ -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)

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

Expand Down Expand Up @@ -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:
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -276,41 +264,40 @@ 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:
os.remove(backup_utils.get_profile_path(use_temp=True))
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:

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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!"))

Expand All @@ -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:
Expand All @@ -414,14 +401,15 @@ 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 "
"in Qubes Global Settings application.<br><br><b><i>%s</i></b>" %
error + "at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
% (line, filename))


def loop_shutdown():
pending = asyncio.Task.all_tasks()
for task in pending:
Expand All @@ -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")
Expand All @@ -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)
Expand Down
11 changes: 5 additions & 6 deletions qubesmanager/backup_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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:
Expand All @@ -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:
Expand All @@ -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):
Expand Down
Loading

0 comments on commit e79724f

Please sign in to comment.