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

* origin/pr/178:
  Update Qt version used in qubesmanager to Qt5
This commit is contained in:
Marek Marczykowski-Górecki 2019-08-28 15:19:26 +02:00
commit 990e4abbbf
No known key found for this signature in database
GPG Key ID: 063938BA42CFA724
25 changed files with 449 additions and 456 deletions

View File

@ -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/

View File

@ -1 +1 @@
PyQt4-devel
PyQt5-devel

View File

@ -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
@ -42,10 +43,12 @@ class AboutDialog(ui_about.Ui_AboutDialog, QDialog):
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_()

View File

@ -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 @@ class AppmenuSelectManager:
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 @@ class AppmenuSelectManager:
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

View File

@ -30,8 +30,8 @@ from qubesadmin import utils as admin_utils
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 os
import asyncio
from contextlib import suppress
# pylint: disable=too-few-public-methods
class BackupThread(QtCore.QThread):
def __init__(self, vm):
@ -67,7 +68,7 @@ class BackupThread(QtCore.QThread):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
'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 @@ class BackupVMsWindow(ui_backupdlg.Ui_Backup, multiselectwidget.QtGui.QWizard):
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 <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:
@ -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)

View File

@ -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):

View File

@ -21,12 +21,13 @@ import sys
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 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog, QtGui.QDialog):
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 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog, QtGui.QDialog):
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 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog, QtGui.QDialog):
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 @@ class VMBootFromDeviceWindow(ui_bootfromdevice.Ui_BootDialog, QtGui.QDialog):
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
@ -149,7 +147,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")
@ -163,5 +161,6 @@ def main(args=None):
qapp.exec_()
qapp.exit()
if __name__ == "__main__":
main()

View File

@ -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 os
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'

View File

@ -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 @@ from qubesadmin import exc
@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

View File

@ -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 . import utils
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 @@ class CreateVMThread(QtCore.QThread):
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 @@ class CreateVMThread(QtCore.QThread):
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 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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.'))
@ -137,8 +140,8 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
name = str(self.name.text())
if name in self.app.domains:
QtGui.QMessageBox.warning(
None,
QtWidgets.QMessageBox.warning(
self,
self.tr('Incorrect qube name!'),
self.tr('A qube with the name <b>{}</b> already exists in the '
'system!').format(name))
@ -151,9 +154,7 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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()]
@ -162,12 +163,12 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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 <b>{}</b>...").format(name), "", 0, 0)
self.progress.setCancelButton(None)
self.progress.setModal(True)
@ -177,7 +178,8 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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))
@ -186,12 +188,11 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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:
@ -222,12 +223,14 @@ class NewVmDlg(QtGui.QDialog, Ui_NewVMDlg):
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')

View File

@ -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 @@ class PCIDeviceListWindow(ui_devicelist.Ui_Dialog, QtGui.QDialog):
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()

View File

@ -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 @@ from . import ui_newfwruledlg # pylint: disable=no-name-in-module
class FirewallModifiedOutsideError(ValueError):
pass
class QIPAddressValidator(QtGui.QValidator):
# pylint: disable=too-few-public-methods
def __init__(self, parent=None):
@ -40,10 +41,10 @@ class QIPAddressValidator(QtGui.QValidator):
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 @@ class QIPAddressValidator(QtGui.QValidator):
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}(?<!-)$", re.IGNORECASE)
if all(allowed.match(x) for x in hostname.split(".")):
return (QtGui.QValidator.Acceptable, input_string, pos)
return QtGui.QValidator.Acceptable, input_string, pos
return (QtGui.QValidator.Invalid, input_string, pos)
return QtGui.QValidator.Invalid, input_string, pos
class NewFwRuleDlg(QtGui.QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
class NewFwRuleDlg(QtWidgets.QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
def __init__(self, parent=None):
super(NewFwRuleDlg, self).__init__(parent)
self.setupUi(self)
@ -84,19 +86,20 @@ class NewFwRuleDlg(QtGui.QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
QtCore.QRegExp("[a-z][a-z0-9-]+|[0-9]+(-[0-9]+)?",
QtCore.Qt.CaseInsensitive), None))
self.serviceComboBox.setEnabled(False)
self.serviceComboBox.setInsertPolicy(QtGui.QComboBox.InsertAtBottom)
self.serviceComboBox.setInsertPolicy(QtWidgets.QComboBox.InsertAtBottom)
self.populate_combos()
self.serviceComboBox.setInsertPolicy(QtGui.QComboBox.InsertAtTop)
self.serviceComboBox.setInsertPolicy(QtWidgets.QComboBox.InsertAtTop)
def accept(self):
if self.tcp_radio.isChecked() or self.udp_radio.isChecked():
if not self.serviceComboBox.currentText():
msg = QtGui.QMessageBox()
msg.warning(self, self.tr("Firewall rule"),
msg = QtWidgets.QMessageBox()
msg.warning(
self, self.tr("Firewall rule"),
self.tr("You need to fill service "
"name/port for TCP/UDP rule"))
return
QtGui.QDialog.accept(self)
super().accept()
def populate_combos(self):
example_addresses = [
@ -121,7 +124,7 @@ class NewFwRuleDlg(QtGui.QDialog, ui_newfwruledlg.Ui_NewFwRuleDlg):
self.set_ok_state(True)
def set_ok_state(self, ok_state):
ok_button = self.buttonBox.button(QtGui.QDialogButtonBox.Ok)
ok_button = self.buttonBox.button(QtWidgets.QDialogButtonBox.Ok)
if ok_button is not None:
ok_button.setEnabled(ok_state)
@ -161,10 +164,10 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
(service["name"], int(service["port"]),))
self.fw_changed = False
self.allow = None # is the default policy allow or deny
self.temp_full_access_expire_time = None # temporary full access time
self.__vm = None # VM that the model applies to
self.__children = None # list of rules in the FW
self.allow = None # is the default policy allow or deny
self.temp_full_access_expire_time = None # temporary full access time
self.__vm = None # VM that the model applies to
self.__children = None # list of rules in the FW
def sort(self, idx, order):
rev = (order == QtCore.Qt.AscendingOrder)
@ -175,7 +178,6 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
index2 = self.createIndex(len(self) - 1, len(self.__column_names) - 1)
self.dataChanged.emit(index1, index2)
def get_service_name(self, port):
for service in self.__services:
if str(service[1]) == str(port):
@ -289,19 +291,19 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
rules.append(rule)
if not conf['allow']:
rules.append(qubesadmin.firewall.Rule(None,
action='accept', specialtarget='dns'))
rules.append(qubesadmin.firewall.Rule(
None, action='accept', specialtarget='dns'))
if not conf['allow']:
rules.append(qubesadmin.firewall.Rule(None,
action='accept', proto='icmp'))
rules.append(qubesadmin.firewall.Rule(
None, action='accept', proto='icmp'))
if conf['allow']:
rules.append(qubesadmin.firewall.Rule(None,
action='accept'))
rules.append(qubesadmin.firewall.Rule(
None, action='accept'))
else:
rules.append(qubesadmin.firewall.Rule(None,
action='drop'))
rules.append(qubesadmin.firewall.Rule(
None, action='drop'))
vm.firewall.rules = rules
@ -332,7 +334,7 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
conf = {"allow": allow,
"rules": list()
}
}
conf['rules'].extend(self.children)
@ -375,7 +377,8 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
try:
rule.dsthost = address
except ValueError:
QtGui.QMessageBox.warning(None, self.tr("Invalid address"),
QtWidgets.QMessageBox.warning(
dialog, self.tr("Invalid address"),
self.tr("Address '{0}' is invalid.").format(address))
return
@ -388,11 +391,11 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
try:
rule.dstports = service
except ValueError:
QtGui.QMessageBox.warning(
None,
QtWidgets.QMessageBox.warning(
dialog,
self.tr("Invalid port or service"),
self.tr("Port number or service '{0}' is invalid.")
.format(service))
self.tr("Port number or service '{0}' is "
"invalid.").format(service))
return
elif service:
if self.service_port_pattern.fullmatch(service):
@ -407,10 +410,12 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
if self.get_service_port(parsed_service) is not None:
rule.dstports = self.get_service_port(parsed_service)
else:
QtGui.QMessageBox.warning(None,
QtWidgets.QMessageBox.warning(
dialog,
self.tr("Invalid port or service"),
self.tr("Port number or service '{0}' is invalid.")
.format(parsed_service))
self.tr(
"Port number or service '{0}' is "
"invalid.".format(parsed_service)))
return
if row is not None:
@ -424,7 +429,7 @@ class QubesFirewallRulesModel(QtCore.QAbstractItemModel):
return self.createIndex(row, column, self.children[row])
def parent(self, child): # pylint: disable=unused-argument,no-self-use
def parent(self, child): # pylint: disable=unused-argument,no-self-use
return QtCore.QModelIndex()
# pylint: disable=invalid-name,unused-argument

View File

@ -24,7 +24,7 @@ import sys
import os
import os.path
import traceback
from PyQt4 import QtCore, QtGui # pylint: disable=import-error
from PyQt5 import QtWidgets # pylint: disable=import-error
from qubesadmin import Qubes
from qubesadmin.utils import parse_size
@ -36,9 +36,10 @@ from configparser import ConfigParser
qmemman_config_path = '/etc/qubes/qmemman.conf'
# pylint: disable=too-many-instance-attributes
class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
QtGui.QDialog):
QtWidgets.QDialog):
def __init__(self, app, qvm_collection, parent=None):
super(GlobalSettingsWindow, self).__init__(parent)
@ -48,11 +49,8 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
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.__init_system_defaults__()
self.__init_kernel_defaults__()
@ -154,10 +152,10 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.kernels_list[self.default_kernel_combo.currentIndex()]
def __init_mem_defaults__(self):
#qmemman settings
# qmemman settings
self.qmemman_config = ConfigParser()
self.vm_min_mem_val = '200MiB' #str(qmemman_algo.MIN_PREFMEM)
self.dom0_mem_boost_val = '350MiB' #str(qmemman_algo.DOM0_MEM_BOOST)
self.vm_min_mem_val = '200MiB' # str(qmemman_algo.MIN_PREFMEM)
self.dom0_mem_boost_val = '350MiB' # str(qmemman_algo.DOM0_MEM_BOOST)
self.qmemman_config.read(qmemman_config_path)
if self.qmemman_config.has_section('global'):
@ -172,10 +170,9 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.min_vm_mem.setValue(self.vm_min_mem_val/1024/1024)
self.dom0_mem_boost.setValue(self.dom0_mem_boost_val/1024/1024)
def __apply_mem_defaults__(self):
#qmemman settings
# qmemman settings
current_min_vm_mem = self.min_vm_mem.value()
current_dom0_mem_boost = self.dom0_mem_boost.value()
@ -186,7 +183,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
current_dom0_mem_boost = str(current_dom0_mem_boost)+'MiB'
if not self.qmemman_config.has_section('global'):
#add the whole section
# add the whole section
self.qmemman_config.add_section('global')
self.qmemman_config.set(
'global', 'vm-min-mem', current_min_vm_mem)
@ -201,7 +198,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
qmemman_config_file.close()
else:
#If there already is a 'global' section, we don't use
# If there already is a 'global' section, we don't use
# SafeConfigParser.write() - it would get rid of
# all the comments...
@ -209,7 +206,7 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
lines_to_add['vm-min-mem'] = \
"vm-min-mem = " + current_min_vm_mem + "\n"
lines_to_add['dom0-mem-boost'] = \
"dom0-mem-boost = " + current_dom0_mem_boost +"\n"
"dom0-mem-boost = " + current_dom0_mem_boost + "\n"
config_lines = []
@ -252,23 +249,23 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.disable_updates_all.clicked.connect(self.__disable_updates_all)
def __enable_updates_all(self):
reply = QtGui.QMessageBox.question(
reply = QtWidgets.QMessageBox.question(
self, self.tr("Change state of all qubes"),
self.tr("Are you sure you want to set all qubes to check "
"for updates?"),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
if reply == QtGui.QMessageBox.Cancel:
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
if reply == QtWidgets.QMessageBox.Cancel:
return
self.__set_updates_all(True)
def __disable_updates_all(self):
reply = QtGui.QMessageBox.question(
reply = QtWidgets.QMessageBox.question(
self, self.tr("Change state of all qubes"),
self.tr("Are you sure you want to set all qubes to not check "
"for updates?"),
QtGui.QMessageBox.Yes | QtGui.QMessageBox.Cancel)
if reply == QtGui.QMessageBox.Cancel:
QtWidgets.QMessageBox.Yes | QtWidgets.QMessageBox.Cancel)
if reply == QtWidgets.QMessageBox.Cancel:
return
self.__set_updates_all(False)
@ -298,7 +295,6 @@ class GlobalSettingsWindow(ui_globalsettingsdlg.Ui_GlobalSettings,
self.__apply_updates__()
# Bases on the original code by:
# Copyright (c) 2002-2007 Pascal Varet <p.varet@gmail.com>
@ -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()

View File

@ -20,7 +20,7 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
#
#
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

View File

@ -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 @@ from qubesadmin import Qubes
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 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtGui.QDialog):
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 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtGui.QDialog):
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 @@ class LogDialog(ui_logdlg.Ui_LogDialog, QtGui.QDialog):
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()

View File

@ -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 @@ class MultiSelectWidget(
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 @@ class MultiSelectWidget(
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 @@ class MultiSelectWidget(
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)

View File

@ -37,8 +37,7 @@ from qubesadmin import exc
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 utils as manager_utils
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 @@ class VmRowInTable:
# AdminAPI
pass
#force re-sorting
# force re-sorting
self.table.setSortingEnabled(True)
@ -229,16 +228,25 @@ class VmShutdownMonitor(QtCore.QObject):
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 <b>'{0}'</b> hasn't shutdown within the last "
"{1} seconds, do you want to kill it?<br>").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 @@ class UpdateVMThread(common_threads.QubesThread):
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 @@ class UpdateVMThread(common_threads.QubesThread):
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 @@ class RunCommandThread(common_threads.QubesThread):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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.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.connect(self.searchbox,
QtCore.SIGNAL("textChanged(const QString&)"),
self.do_search)
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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))
@ -665,7 +663,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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"))
@ -808,7 +806,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
manager_utils.format_dependencies_list(dependencies) + \
"<br>"
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:"
@ -820,8 +818,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 <b>'{0}'</b>"
"?<br> All data on this Qube's private storage will be "
"lost!<br><br>Type the name of the Qube (<b>{1}</b>) below "
@ -833,8 +831,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 "
@ -858,7 +856,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 <b>{}</b> clone:').format(vm.name),
text=(name_format % name_number))
@ -868,13 +866,13 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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)
@ -896,8 +894,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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
@ -925,8 +923,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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
@ -936,14 +934,15 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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"
" <b>'{0}'</b>?<br><small>This will shutdown all the "
"running applications within this Qube.</small>").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,
@ -951,8 +950,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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
@ -969,14 +968,14 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 <b>'{0}'</b>?"
"<br><small>This will shutdown all the running "
"applications within this Qube.</small>").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)
@ -999,17 +998,17 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
"shutdown!)</b> all the running applications within "
"this Qube.</small>").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(
"<b>An exception ocurred while killing {0}.</b><br>"
"ERROR: {1}").format(vm.name, ex))
@ -1059,13 +1058,13 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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(
"<b>{0}</b><br>The Qube has to be running to be updated."
"<br>Do you want to start it?<br>").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)
@ -1073,14 +1072,13 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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 <b>{}</b>:').format(vm.name))
if not ok or command_to_run == "":
@ -1103,8 +1101,8 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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
@ -1134,16 +1132,16 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
@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
@ -1229,7 +1227,7 @@ class VmManagerWindow(ui_qubemanager.Ui_VmManagerWindow, QtGui.QMainWindow):
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
@ -1304,9 +1302,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.<br><br>"
@ -1325,7 +1323,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")

View File

@ -20,7 +20,7 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
#
#
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

View File

@ -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 multiselectwidget
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 @@ class RestoreThread(QtCore.QThread):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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 @@ class RestoreVMsWindow(ui_restoredlg.Ui_Restore, QtGui.QWizard):
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.<br><br>"
"<b><i>%s</i></b>" % error +
"at <b>line %d</b> of file <b>%s</b>.<br/><br/>"
% (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.<br><br><b><i>%s</i></b>" % error +
"at <b>line %d</b> of file <b>%s</b>.<br/><br/>" % (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")

View File

@ -41,7 +41,7 @@ from . import device_list
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
@ -118,7 +118,7 @@ class RefreshAppsVMThread(common_threads.QubesThread):
# 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),
@ -148,7 +148,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -174,12 +174,8 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -204,9 +200,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
####### 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 = []
@ -237,8 +231,8 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
if thread.msg:
(title, msg) = thread.msg
QtGui.QMessageBox.warning(
None,
QtWidgets.QMessageBox.warning(
self,
self.tr(title),
self.tr(msg))
@ -265,10 +259,10 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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):
@ -328,7 +322,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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 '
@ -337,17 +331,17 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
'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!<br/>"\
"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!<br/>"
"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"]:
@ -535,7 +529,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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.<br>"
@ -545,7 +539,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
# 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 "
@ -578,7 +572,6 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
else:
self.warn_netvm_dispvm.setVisible(False)
def rename_vm(self):
dependencies = admin_utils.vm_dependencies(self.vm.app, self.vm)
@ -588,7 +581,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
and vm.is_running()]
if running_dependencies:
QtGui.QMessageBox.warning(
QtWidgets.QMessageBox.warning(
self,
self.tr("Qube cannot be renamed!"),
self.tr(
@ -598,7 +591,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
", ".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)'))
@ -608,7 +601,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -624,7 +617,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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:"
@ -634,8 +627,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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? '
@ -649,14 +641,14 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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:'))
@ -666,7 +658,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -885,9 +877,9 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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))
@ -942,7 +934,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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
@ -1088,7 +1080,7 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -1115,12 +1107,12 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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
@ -1164,9 +1156,10 @@ class VMSettingsWindow(ui_settingsdlg.Ui_SettingsDialog, QtGui.QDialog):
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)
@ -1244,9 +1237,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.<br><br>"
@ -1272,7 +1265,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")

View File

@ -20,8 +20,7 @@
# with this program; if not, see <http://www.gnu.org/licenses/>.
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 @@ update_order = QtCore.Qt.AscendingOrder
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 @@ class VmIconWidget(QtGui.QWidget):
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 @@ class VmIconWidget(QtGui.QWidget):
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 @@ class VmTypeWidget(VmIconWidget):
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 @@ class VmTypeWidget(VmIconWidget):
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 @@ class VmLabelWidget(VmIconWidget):
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 @@ class VmLabelWidget(VmIconWidget):
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 @@ class VmStatusIcon(QtGui.QLabel):
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 @@ class VmInfoWidget(QtGui.QWidget):
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 @@ class VmInfoWidget(QtGui.QWidget):
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 @@ class VmInfoWidget(QtGui.QWidget):
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 @@ class VmTemplateItem(VMPropertyItem):
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 @@ class VmInternalItem(VMPropertyItem):
# 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 @@ class VmUpdateInfoWidget(QtGui.QWidget):
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 @@ class VmUpdateInfoWidget(QtGui.QWidget):
"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 @@ class VmUpdateInfoWidget(QtGui.QWidget):
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)

View File

@ -32,10 +32,7 @@ from qubesadmin import Qubes
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 @@ column_names = ['State', 'Qube', 'Current template', 'New template']
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 @@ class TemplateManagerWindow(
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 @@ class TemplateManagerWindow(
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 @@ class TemplateManagerWindow(
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 @@ class TemplateManagerWindow(
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 @@ class VMNameItem(QtGui.QTableWidgetItem):
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 @@ class StatusItem(QtGui.QTableWidgetItem):
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 @@ class CurrentTemplateItem(QtGui.QTableWidgetItem):
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 @@ class VMRow:
# 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 @@ class VMRow:
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 @@ class VMRow:
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.<br><br>"
@ -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)

View File

@ -24,16 +24,18 @@ import os
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
@ -144,10 +146,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:
@ -156,11 +160,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

View File

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

View File

@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>700</width>
<height>399</height>
<width>756</width>
<height>440</height>
</rect>
</property>
<property name="windowTitle">
@ -214,7 +214,7 @@
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Sans'; font-size:10pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'Cantarell'; font-size:11pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot;-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;&quot;&gt;&lt;br /&gt;&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
</widget>