From 23d1863d03ca90ddc4a22a6c043bb29d5b65be8f Mon Sep 17 00:00:00 2001 From: Florent Fourcot Date: Wed, 28 Dec 2016 22:23:01 +0100 Subject: [PATCH] Remove old qt4 files. All applications are ported to qt5 --- build.mk | 2 +- weboob/tools/application/qt/Makefile | 12 - weboob/tools/application/qt/__init__.py | 5 - weboob/tools/application/qt/backendcfg.py | 559 ---------------------- weboob/tools/application/qt/backendcfg.ui | 328 ------------- weboob/tools/application/qt/qt.py | 419 ---------------- weboob/tools/application/qt/reposdlg.ui | 51 -- 7 files changed, 1 insertion(+), 1375 deletions(-) delete mode 100644 weboob/tools/application/qt/Makefile delete mode 100644 weboob/tools/application/qt/__init__.py delete mode 100644 weboob/tools/application/qt/backendcfg.py delete mode 100644 weboob/tools/application/qt/backendcfg.ui delete mode 100644 weboob/tools/application/qt/qt.py delete mode 100644 weboob/tools/application/qt/reposdlg.ui diff --git a/build.mk b/build.mk index 090df13a76..f9c3929c40 100644 --- a/build.mk +++ b/build.mk @@ -1,4 +1,4 @@ -core := weboob/tools/application/qt weboob/tools/application/qt5 +core := weboob/tools/application/qt5 applications := qboobmsg qhavedate qwebcontentedit qflatboob qcineoob qcookboob qhandjoob qbooblyrics ifeq ($(WIN32),) applications += qvideoob diff --git a/weboob/tools/application/qt/Makefile b/weboob/tools/application/qt/Makefile deleted file mode 100644 index 9ec35f9a33..0000000000 --- a/weboob/tools/application/qt/Makefile +++ /dev/null @@ -1,12 +0,0 @@ -UI_FILES = $(wildcard *.ui) -UI_PY_FILES = $(UI_FILES:%.ui=%_ui.py) -PYUIC = pyuic4 - -all: $(UI_PY_FILES) - -%_ui.py: %.ui - $(PYUIC) -o $@ $^ - -clean: - rm -f *.pyc - rm -f $(UI_PY_FILES) diff --git a/weboob/tools/application/qt/__init__.py b/weboob/tools/application/qt/__init__.py deleted file mode 100644 index af213a8c2f..0000000000 --- a/weboob/tools/application/qt/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -from .qt import QtApplication, QtMainWindow, QtDo, HTMLDelegate -from .backendcfg import BackendCfg - -__all__ = ['QtApplication', 'QtMainWindow', 'QtDo', 'HTMLDelegate', - 'BackendCfg'] diff --git a/weboob/tools/application/qt/backendcfg.py b/weboob/tools/application/qt/backendcfg.py deleted file mode 100644 index 5f19696bc6..0000000000 --- a/weboob/tools/application/qt/backendcfg.py +++ /dev/null @@ -1,559 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright(C) 2010-2012 Romain Bignon -# -# This file is part of weboob. -# -# weboob is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# weboob is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with weboob. If not, see . - - -from PyQt4.QtGui import QDialog, QTreeWidgetItem, QLabel, QFormLayout, \ - QMessageBox, QPixmap, QImage, QIcon, QHeaderView, \ - QListWidgetItem, QTextDocument, QVBoxLayout, \ - QDialogButtonBox, QProgressDialog -from PyQt4.QtCore import Qt, QVariant, QUrl, QThread -from PyQt4.QtCore import pyqtSignal as Signal, pyqtSlot as Slot - -import re -import os -from logging import warning - -from weboob.core.repositories import IProgress -from weboob.core.backendscfg import BackendAlreadyExists -from weboob.capabilities.account import CapAccount, Account, AccountRegisterError -from weboob.exceptions import ModuleInstallError, ModuleLoadError -from .backendcfg_ui import Ui_BackendCfg -from .reposdlg_ui import Ui_RepositoriesDlg -from weboob.tools.ordereddict import OrderedDict -from weboob.tools.misc import to_unicode -from .qt import QtValue - - -class RepositoriesDialog(QDialog): - def __init__(self, filename, parent=None): - QDialog.__init__(self, parent) - self.filename = filename - self.ui = Ui_RepositoriesDlg() - self.ui.setupUi(self) - - self.ui.buttonBox.accepted.connect(self.save) - - with open(self.filename, 'r') as fp: - self.ui.reposEdit.setPlainText(fp.read()) - - @Slot() - def save(self): - with open(self.filename, 'w') as fp: - fp.write(self.ui.reposEdit.toPlainText()) - self.accept() - - -class IconFetcher(QThread): - retrieved = Signal() - - def __init__(self, weboob, item, minfo): - QThread.__init__(self) - self.weboob = weboob - self.items = [item] - self.minfo = minfo - - def run(self): - self.weboob.repositories.retrieve_icon(self.minfo) - self.retrieved.emit() - - -class ProgressDialog(IProgress, QProgressDialog): - def __init__(self, *args, **kwargs): - QProgressDialog.__init__(self, *args, **kwargs) - - def progress(self, percent, message): - self.setValue(int(percent * 100)) - self.setLabelText(message) - - def error(self, message): - QMessageBox.critical(self, self.tr('Error'), '%s' % message, QMessageBox.Ok) - - def prompt(self, message): - reply = QMessageBox.question(self, '', unicode(message), QMessageBox.Yes|QMessageBox.No) - - return reply == QMessageBox.Yes - - -class BackendCfg(QDialog): - def __init__(self, weboob, caps=None, parent=None): - QDialog.__init__(self, parent) - self.ui = Ui_BackendCfg() - self.ui.setupUi(self) - - self.ui.backendsList.sortByColumn(0, Qt.AscendingOrder) - - self.to_unload = set() - self.to_load = set() - - self.weboob = weboob - self.caps = caps - self.config_widgets = {} - - # This attribute is set when itemChanged it called, because when - # a backend is enabled/disabled, we don't want to display its config - # frame, and the itemClicked event is always emit just after a - # itemChanged event. - # is_enabling is a counter to prevent race conditions. - self.is_enabling = 0 - - self.ui.backendsList.header().setResizeMode(QHeaderView.ResizeToContents) - self.ui.configFrame.hide() - - self.icon_cache = {} - self.icon_threads = {} - - self.loadModules() - self.loadBackendsList() - - self.ui.updateButton.clicked.connect(self.updateModules) - self.ui.repositoriesButton.clicked.connect(self.editRepositories) - self.ui.backendsList.itemClicked.connect(self.backendClicked) - self.ui.backendsList.itemChanged.connect(self.backendEnabled) - self.ui.modulesList.itemSelectionChanged.connect(self.moduleSelectionChanged) - self.ui.proxyBox.toggled.connect(self.proxyEditEnabled) - self.ui.addButton.clicked.connect(self.addEvent) - self.ui.removeButton.clicked.connect(self.removeEvent) - self.ui.registerButton.clicked.connect(self.registerEvent) - self.ui.configButtonBox.accepted.connect(self.acceptBackend) - self.ui.configButtonBox.rejected.connect(self.rejectBackend) - - def get_icon_cache(self, path): - if path not in self.icon_cache: - img = QImage(path) - self.icon_cache[path] = QIcon(QPixmap.fromImage(img)) - return self.icon_cache[path] - - def set_icon(self, item, minfo): - icon_path = self.weboob.repositories.get_module_icon_path(minfo) - - icon = self.icon_cache.get(icon_path, None) - if icon is None and not os.path.exists(icon_path): - if minfo.name in self.icon_threads: - self.icon_threads[minfo.name].items.append(item) - else: - thread = IconFetcher(self.weboob, item, minfo) - thread.retrieved.connect(self._set_icon_slot) - self.icon_threads[minfo.name] = thread - thread.start() - return - - self._set_icon([item], minfo) - - @Slot() - def _set_icon_slot(self): - thread = self.sender() - self._set_icon(thread.items, thread.minfo) - - def _set_icon(self, items, minfo): - icon_path = self.weboob.repositories.get_module_icon_path(minfo) - icon = self.get_icon_cache(icon_path) - - if icon is None: - return - - for item in items: - try: - item.setIcon(icon) - except TypeError: - item.setIcon(0, icon) - - self.icon_threads.pop(minfo.name, None) - - @Slot() - def updateModules(self): - self.ui.configFrame.hide() - pd = ProgressDialog('Update of modules', "Cancel", 0, 100, self) - pd.setWindowModality(Qt.WindowModal) - try: - self.weboob.repositories.update(pd) - except ModuleInstallError as err: - QMessageBox.critical(self, self.tr('Update error'), - unicode(self.tr('Unable to update modules: %s' % (err))), - QMessageBox.Ok) - pd.setValue(100) - self.loadModules() - QMessageBox.information(self, self.tr('Update of modules'), - self.tr('Modules updated!'), QMessageBox.Ok) - - @Slot() - def editRepositories(self): - if RepositoriesDialog(self.weboob.repositories.sources_list).exec_(): - self.updateModules() - - def loadModules(self): - self.ui.modulesList.clear() - for name, module in sorted(self.weboob.repositories.get_all_modules_info(self.caps).iteritems()): - item = QListWidgetItem(name.capitalize()) - self.set_icon(item, module) - self.ui.modulesList.addItem(item) - - def askInstallModule(self, minfo): - reply = QMessageBox.question(self, self.tr('Install a module'), - unicode(self.tr("Module %s is not installed. Do you want to install it?")) % minfo.name, - QMessageBox.Yes|QMessageBox.No) - - if reply != QMessageBox.Yes: - return False - - return self.installModule(minfo) - - def installModule(self, minfo): - pd = ProgressDialog('Installation of %s' % minfo.name, "Cancel", 0, 100, self) - pd.setWindowModality(Qt.WindowModal) - - try: - self.weboob.repositories.install(minfo, pd) - except ModuleInstallError as err: - QMessageBox.critical(self, self.tr('Install error'), - unicode(self.tr('Unable to install module %s: %s' % (minfo.name, err))), - QMessageBox.Ok) - pd.setValue(100) - return True - - def loadBackendsList(self): - self.ui.backendsList.clear() - for backend_name, module_name, params in self.weboob.backends_config.iter_backends(): - info = self.weboob.repositories.get_module_info(module_name) - if not info or (self.caps and not info.has_caps(self.caps)): - continue - - item = QTreeWidgetItem(None, [backend_name, module_name]) - item.setCheckState(0, Qt.Checked if params.get('_enabled', '1').lower() in ('1', 'y', 'true', 'on', 'yes') - else Qt.Unchecked) - - self.set_icon(item, info) - - self.ui.backendsList.addTopLevelItem(item) - - @Slot(object, object) - def backendEnabled(self, item, col): - self.is_enabling += 1 - - backend_name = unicode(item.text(0)) - module_name = unicode(item.text(1)) - if item.checkState(0) == Qt.Checked: - self.to_load.add(backend_name) - enabled = 'true' - else: - self.to_unload.add(backend_name) - try: - self.to_load.remove(backend_name) - except KeyError: - pass - enabled = 'false' - - self.weboob.backends_config.edit_backend(backend_name, module_name, {'_enabled': enabled}) - - @Slot(object, object) - def backendClicked(self, item, col): - if self.is_enabling: - self.is_enabling -= 1 - return - - backend_name = unicode(item.text(0)) - - self.editBackend(backend_name) - - @Slot() - def addEvent(self): - self.editBackend() - - @Slot() - def removeEvent(self): - item = self.ui.backendsList.currentItem() - if not item: - return - - backend_name = unicode(item.text(0)) - reply = QMessageBox.question(self, self.tr('Remove a backend'), - unicode(self.tr("Are you sure you want to remove the backend '%s'?")) % backend_name, - QMessageBox.Yes|QMessageBox.No) - - if reply != QMessageBox.Yes: - return - - self.weboob.backends_config.remove_backend(backend_name) - self.to_unload.add(backend_name) - try: - self.to_load.remove(backend_name) - except KeyError: - pass - self.ui.configFrame.hide() - self.loadBackendsList() - - def editBackend(self, backend_name=None): - self.ui.registerButton.hide() - self.ui.configFrame.show() - - if backend_name is not None: - module_name, params = self.weboob.backends_config.get_backend(backend_name) - - items = self.ui.modulesList.findItems(module_name, Qt.MatchFixedString) - if not items: - warning('Backend not found') - else: - self.ui.modulesList.setCurrentItem(items[0]) - self.ui.modulesList.setEnabled(False) - - self.ui.nameEdit.setText(backend_name) - self.ui.nameEdit.setEnabled(False) - - if '_proxy' in params: - self.ui.proxyBox.setChecked(True) - self.ui.proxyEdit.setText(params.pop('_proxy')) - else: - self.ui.proxyBox.setChecked(False) - self.ui.proxyEdit.clear() - - params.pop('_enabled', None) - - info = self.weboob.repositories.get_module_info(module_name) - if info and (info.is_installed() or self.installModule(info)): - module = self.weboob.modules_loader.get_or_load_module(module_name) - for key, value in module.config.load(self.weboob, module_name, backend_name, params, nofail=True).iteritems(): - try: - l, widget = self.config_widgets[key] - except KeyError: - warning('Key "%s" is not found' % key) - else: - # Do not prompt user for value (for example a password if it is empty). - value.noprompt = True - widget.set_value(value) - return - - self.ui.nameEdit.clear() - self.ui.nameEdit.setEnabled(True) - self.ui.proxyBox.setChecked(False) - self.ui.proxyEdit.clear() - self.ui.modulesList.setEnabled(True) - self.ui.modulesList.setCurrentRow(-1) - - @Slot() - def moduleSelectionChanged(self): - for key, (label, value) in self.config_widgets.iteritems(): - label.hide() - value.hide() - self.ui.configLayout.removeWidget(label) - self.ui.configLayout.removeWidget(value) - label.deleteLater() - value.deleteLater() - self.config_widgets = {} - self.ui.moduleInfo.clear() - - selection = self.ui.modulesList.selectedItems() - if not selection: - return - - minfo = self.weboob.repositories.get_module_info(unicode(selection[0].text()).lower()) - if not minfo: - warning('Module not found') - return - - if not minfo.is_installed() and not self.installModule(minfo): - self.editBackend(None) - return - - module = self.weboob.modules_loader.get_or_load_module(minfo.name) - - icon_path = os.path.join(self.weboob.repositories.icons_dir, '%s.png' % minfo.name) - img = QImage(icon_path) - self.ui.moduleInfo.document().addResource(QTextDocument.ImageResource, QUrl('mydata://logo.png'), - QVariant(img)) - - if module.name not in [n for n, ign, ign2 in self.weboob.backends_config.iter_backends()]: - self.ui.nameEdit.setText(module.name) - else: - self.ui.nameEdit.setText('') - - self.ui.moduleInfo.setText(to_unicode(self.tr( - u'

%s Module %s

' - 'Version: %s
' - 'Maintainer: %s
' - 'License: %s
' - '%s' - 'Description: %s
' - 'Capabilities: %s
')) - % ('', - module.name.capitalize(), - module.version, - to_unicode(module.maintainer).replace(u'&', u'&').replace(u'<', u'<').replace(u'>', u'>'), - module.license, - (unicode(self.tr('Website: %s
')) % module.website) if module.website else '', - module.description, - ', '.join(sorted(cap.__name__.replace('Cap', '') for cap in module.iter_caps())))) - - if module.has_caps(CapAccount) and self.ui.nameEdit.isEnabled() and \ - module.klass.ACCOUNT_REGISTER_PROPERTIES is not None: - self.ui.registerButton.show() - else: - self.ui.registerButton.hide() - - for key, field in module.config.iteritems(): - label = QLabel(u'%s:' % field.label) - qvalue = QtValue(field) - self.ui.configLayout.addRow(label, qvalue) - self.config_widgets[key] = (label, qvalue) - - @Slot(object) - def proxyEditEnabled(self, state): - self.ui.proxyEdit.setEnabled(state) - - @Slot() - def acceptBackend(self): - backend_name = unicode(self.ui.nameEdit.text()) - selection = self.ui.modulesList.selectedItems() - - if not selection: - QMessageBox.critical(self, self.tr('Unable to add a backend'), - self.tr('Please select a module')) - return - - try: - module = self.weboob.modules_loader.get_or_load_module(unicode(selection[0].text()).lower()) - except ModuleLoadError: - module = None - - if not module: - QMessageBox.critical(self, self.tr('Unable to add a backend'), - self.tr('The selected module does not exist.')) - return - - params = {} - - if not backend_name: - QMessageBox.critical(self, self.tr('Missing field'), self.tr('Please specify a backend name')) - return - - if self.ui.nameEdit.isEnabled(): - if not re.match(r'^[\w\-_]+$', backend_name): - QMessageBox.critical(self, self.tr('Invalid value'), - self.tr('The backend name can only contain letters and digits')) - return - if self.weboob.backends_config.backend_exists(backend_name): - QMessageBox.critical(self, self.tr('Unable to create backend'), - unicode(self.tr('Unable to create backend "%s": it already exists')) % backend_name) - return - - if self.ui.proxyBox.isChecked(): - params['_proxy'] = unicode(self.ui.proxyEdit.text()) - if not params['_proxy']: - QMessageBox.critical(self, self.tr('Missing field'), self.tr('Please specify a proxy URL')) - return - - config = module.config.load(self.weboob, module.name, backend_name, {}, nofail=True) - for key, field in config.iteritems(): - label, qtvalue = self.config_widgets[key] - - try: - value = qtvalue.get_value() - except ValueError as e: - QMessageBox.critical(self, self.tr('Invalid value'), - unicode(self.tr('Invalid value for field "%s":

%s')) % (field.label, e)) - return - - field.set(value.get()) - - try: - config.save(edit=not self.ui.nameEdit.isEnabled(), params=params) - except BackendAlreadyExists: - QMessageBox.critical(self, self.tr('Unable to create backend'), - unicode(self.tr('Unable to create backend "%s": it already exists')) % backend_name) - return - - self.to_load.add(backend_name) - self.ui.configFrame.hide() - - self.loadBackendsList() - - @Slot() - def rejectBackend(self): - self.ui.configFrame.hide() - - @Slot() - def registerEvent(self): - selection = self.ui.modulesList.selectedItems() - if not selection: - return - - try: - module = self.weboob.modules_loader.get_or_load_module(unicode(selection[0].text()).lower()) - except ModuleLoadError: - module = None - - if not module: - return - - dialog = QDialog(self) - vbox = QVBoxLayout(dialog) - if module.website: - website = 'on the website %s' % module.website - else: - website = 'with the module %s' % module.name - vbox.addWidget(QLabel('To create an account %s, please provide this information:' % website)) - formlayout = QFormLayout() - props_widgets = OrderedDict() - for key, prop in module.klass.ACCOUNT_REGISTER_PROPERTIES.iteritems(): - widget = QtValue(prop) - formlayout.addRow(QLabel(u'%s:' % prop.label), widget) - props_widgets[prop.id] = widget - - vbox.addLayout(formlayout) - buttonBox = QDialogButtonBox(dialog) - buttonBox.setStandardButtons(QDialogButtonBox.Ok|QDialogButtonBox.Cancel) - buttonBox.accepted.connect(dialog.accept) - buttonBox.rejected.connect(dialog.reject) - vbox.addWidget(buttonBox) - - end = False - while not end: - end = True - if dialog.exec_(): - account = Account() - account.properties = {} - for key, widget in props_widgets.iteritems(): - try: - v = widget.get_value() - except ValueError as e: - QMessageBox.critical(self, self.tr('Invalid value'), - unicode(self.tr('Invalid value for field "%s":

%s')) % (key, e)) - end = False - break - else: - account.properties[key] = v - if end: - try: - module.klass.register_account(account) - except AccountRegisterError as e: - QMessageBox.critical(self, self.tr('Error during register'), - unicode(self.tr('Unable to register account %s:

%s')) % (website, e)) - end = False - else: - for key, value in account.properties.iteritems(): - if key in self.config_widgets: - self.config_widgets[key][1].set_value(value) - - def run(self): - self.exec_() - - ret = (len(self.to_load) > 0 or len(self.to_unload) > 0) - - self.weboob.unload_backends(self.to_unload) - self.weboob.load_backends(names=self.to_load) - - return ret diff --git a/weboob/tools/application/qt/backendcfg.ui b/weboob/tools/application/qt/backendcfg.ui deleted file mode 100644 index 09122b8be1..0000000000 --- a/weboob/tools/application/qt/backendcfg.ui +++ /dev/null @@ -1,328 +0,0 @@ - - - BackendCfg - - - - 0 - 0 - 622 - 516 - - - - Backends configuration - - - - 6 - - - 4 - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - 4 - - - - - Update modules - - - - - - - Repositories - - - - - - - Qt::Horizontal - - - - 40 - 20 - - - - - - - - - - - Qt::Vertical - - - - - - - QAbstractItemView::NoEditTriggers - - - - 24 - 24 - - - - false - - - false - - - false - - - true - - - true - - - false - - - false - - - false - - - true - - - - Name - - - - - Module - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - Add - - - - - - - Remove - - - - - - - Qt::Vertical - - - - 20 - 40 - - - - - - - - - - - - QFrame::StyledPanel - - - QFrame::Raised - - - - - - - - Available modules: - - - - - - - - 0 - 0 - - - - - 24 - 24 - - - - 1 - - - true - - - - - - - - - - 1 - 0 - - - - QFrame::NoFrame - - - QFrame::Plain - - - - - - - 0 - 0 - - - - true - - - - - - - QFormLayout::ExpandingFieldsGrow - - - - - - - - Proxy: - - - - - - - false - - - - - - - Register an account... - - - - - - - Name: - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - - - - - - QDialogButtonBox::Close - - - - - - - backendsList - addButton - removeButton - modulesList - moduleInfo - nameEdit - proxyBox - proxyEdit - registerButton - configButtonBox - buttonBox - - - - - buttonBox - clicked(QAbstractButton*) - BackendCfg - accept() - - - 312 - 591 - - - 312 - 306 - - - - - diff --git a/weboob/tools/application/qt/qt.py b/weboob/tools/application/qt/qt.py deleted file mode 100644 index b18a30f813..0000000000 --- a/weboob/tools/application/qt/qt.py +++ /dev/null @@ -1,419 +0,0 @@ -# -*- coding: utf-8 -*- - -# Copyright(C) 2010-2011 Romain Bignon -# -# This file is part of weboob. -# -# weboob is free software: you can redistribute it and/or modify -# it under the terms of the GNU Affero General Public License as published by -# the Free Software Foundation, either version 3 of the License, or -# (at your option) any later version. -# -# weboob is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU Affero General Public License for more details. -# -# You should have received a copy of the GNU Affero General Public License -# along with weboob. If not, see . - -from __future__ import print_function - -import sys -import logging -import re -from threading import Event -from copy import copy -from PyQt4.QtCore import QTimer, QObject, QString, QSize, QVariant, QMutex, Qt -from PyQt4.QtCore import pyqtSignal as Signal, pyqtSlot as Slot -from PyQt4.QtGui import QMainWindow, QApplication, QStyledItemDelegate, \ - QStyleOptionViewItemV4, QTextDocument, QStyle, \ - QAbstractTextDocumentLayout, QPalette, QMessageBox, \ - QSpinBox, QLineEdit, QComboBox, QCheckBox, QInputDialog - -from weboob.core.ouiboube import Weboob, VersionsMismatchError -from weboob.core.scheduler import IScheduler -from weboob.tools.config.iconfig import ConfigError -from weboob.exceptions import BrowserUnavailable, BrowserIncorrectPassword, BrowserForbidden, ModuleInstallError -from weboob.tools.value import ValueInt, ValueBool, ValueBackendPassword -from weboob.tools.misc import to_unicode -from weboob.capabilities import UserError - -from ..base import Application, MoreResultsAvailable - - -__all__ = ['QtApplication', 'QtMainWindow', 'QtDo', 'HTMLDelegate'] - - -class QtScheduler(QObject, IScheduler): - def __init__(self, app): - QObject.__init__(self) - self.app = app - self.params = {} - - def schedule(self, interval, function, *args): - timer = QTimer() - timer.setInterval(interval * 1000) - timer.setSingleShot(True) - - self.params[timer] = (None, function, args) - - timer.start() - timer.timeout.connect(self.timeout) - - def repeat(self, interval, function, *args): - timer = QTimer() - timer.setSingleShot(False) - - self.params[timer] = (interval, function, args) - - timer.start(0) - timer.timeout.connect(self.timeout) - - @Slot() - def timeout(self): - timer = self.sender() - interval, function, args = self.params[timer] - - function(*args) - if interval is None: - self.params.pop(timer) - else: - timer.setInterval(interval * 1000) - - def want_stop(self): - self.app.quit() - - def run(self): - self.app.exec_() - - -class QCallbacksManager(QObject): - class Request(object): - def __init__(self): - self.event = Event() - self.answer = None - - def __call__(self): - raise NotImplementedError() - - class LoginRequest(Request): - def __init__(self, backend_name, value): - QCallbacksManager.Request.__init__(self) - self.backend_name = backend_name - self.value = value - - def __call__(self): - password, ok = QInputDialog.getText(None, - '%s request' % self.value.label, - 'Please enter %s for %s' % (self.value.label, - self.backend_name), - QLineEdit.Password) - return password - - new_request = Signal() - - def __init__(self, weboob, parent=None): - QObject.__init__(self, parent) - self.weboob = weboob - self.weboob.requests.register('login', self.callback(self.LoginRequest)) - self.mutex = QMutex() - self.requests = [] - self.new_request.connect(self.do_request) - - def callback(self, klass): - def cb(*args, **kwargs): - return self.add_request(klass(*args, **kwargs)) - return cb - - @Slot() - def do_request(self): - self.mutex.lock() - request = self.requests.pop() - request.answer = request() - request.event.set() - self.mutex.unlock() - - def add_request(self, request): - self.mutex.lock() - self.requests.append(request) - self.mutex.unlock() - self.new_request.emit() - request.event.wait() - return request.answer - - -class QtApplication(QApplication, Application): - def __init__(self): - QApplication.__init__(self, sys.argv) - self.setApplicationName(self.APPNAME) - - Application.__init__(self) - self.cbmanager = QCallbacksManager(self.weboob, self) - - def create_weboob(self): - return Weboob(scheduler=QtScheduler(self)) - - def load_backends(self, *args, **kwargs): - while True: - try: - return Application.load_backends(self, *args, **kwargs) - except VersionsMismatchError as e: - msg = 'Versions of modules mismatch with version of weboob.' - except ConfigError as e: - msg = unicode(e) - - res = QMessageBox.question(None, 'Configuration error', u'%s\n\nDo you want to update repositories?' % msg, QMessageBox.Yes|QMessageBox.No) - if res == QMessageBox.No: - raise e - - # Do not import it globally, it causes circular imports - from .backendcfg import ProgressDialog - pd = ProgressDialog('Update of repositories', "Cancel", 0, 100) - pd.setWindowModality(Qt.WindowModal) - try: - self.weboob.update(pd) - except ModuleInstallError as err: - QMessageBox.critical(None, self.tr('Update error'), - unicode(self.tr('Unable to update repositories: %s' % err)), - QMessageBox.Ok) - pd.setValue(100) - QMessageBox.information(None, self.tr('Update of repositories'), - self.tr('Repositories updated!'), QMessageBox.Ok) - - -class QtMainWindow(QMainWindow): - def __init__(self, parent=None): - QMainWindow.__init__(self, parent) - - -class QtDo(QObject): - gotResponse = Signal(object) - gotError = Signal(object, object, object) - finished = Signal() - - def __init__(self, weboob, cb, eb=None, fb=None): - QObject.__init__(self) - - if not eb: - eb = self.default_eb - - self.weboob = weboob - self.process = None - self.cb = cb - self.eb = eb - self.fb = fb - - self.gotResponse.connect(self.local_cb) - self.gotError.connect(self.local_eb) - self.finished.connect(self.local_fb) - - def stop(self, wait=False): - if self.process is not None: - self.process.stop(wait) - - def do(self, *args, **kwargs): - self.process = self.weboob.do(*args, **kwargs) - self.process.callback_thread(self.thread_cb, self.thread_eb, self.thread_fb) - - @Slot(object, object, object) - def default_eb(self, backend, error, backtrace): - if isinstance(error, MoreResultsAvailable): - # This is not an error, ignore. - return - - msg = unicode(error) - if isinstance(error, BrowserIncorrectPassword): - if not msg: - msg = 'Invalid login/password.' - elif isinstance(error, BrowserUnavailable): - if not msg: - msg = 'Website is unavailable.' - elif isinstance(error, BrowserForbidden): - if not msg: - msg = 'This action is forbidden.' - elif isinstance(error, NotImplementedError): - msg = u'This feature is not supported by this backend.\n\n' \ - u'To help the maintainer of this backend implement this feature, please contact: %s <%s>' % (backend.MAINTAINER, backend.EMAIL) - elif isinstance(error, UserError): - if not msg: - msg = type(error).__name__ - elif logging.root.level <= logging.DEBUG: - msg += u'
' - ul_opened = False - for line in backtrace.split('\n'): - m = re.match(' File (.*)', line) - if m: - if not ul_opened: - msg += u'
    ' - ul_opened = True - else: - msg += u'' - msg += u'
  • %s' % m.group(1) - else: - msg += u'
    %s' % to_unicode(line) - if ul_opened: - msg += u'
' - print(error, file=sys.stderr) - print(backtrace, file=sys.stderr) - QMessageBox.critical(None, unicode(self.tr('Error with backend %s')) % backend.name, - msg, QMessageBox.Ok) - - @Slot(object) - def local_cb(self, data): - if self.cb: - self.cb(data) - - @Slot(object, object, object) - def local_eb(self, backend, error, backtrace): - if self.eb: - self.eb(backend, error, backtrace) - - @Slot() - def local_fb(self): - if self.fb: - self.fb() - - self.gotResponse.disconnect(self.local_cb) - self.gotError.disconnect(self.local_eb) - self.finished.disconnect(self.local_fb) - self.process = None - - def thread_cb(self, data): - self.gotResponse.emit(data) - - def thread_eb(self, backend, error, backtrace): - self.gotError.emit(backend, error, backtrace) - - def thread_fb(self): - self.finished.emit() - - -class HTMLDelegate(QStyledItemDelegate): - def paint(self, painter, option, index): - optionV4 = QStyleOptionViewItemV4(option) - self.initStyleOption(optionV4, index) - - style = optionV4.widget.style() if optionV4.widget else QApplication.style() - - doc = QTextDocument() - doc.setHtml(optionV4.text) - - # painting item without text - optionV4.text = QString() - style.drawControl(QStyle.CE_ItemViewItem, optionV4, painter) - - ctx = QAbstractTextDocumentLayout.PaintContext() - - # Hilight text if item is selected - if optionV4.state & QStyle.State_Selected: - ctx.palette.setColor(QPalette.Text, optionV4.palette.color(QPalette.Active, QPalette.HighlightedText)) - - textRect = style.subElementRect(QStyle.SE_ItemViewItemText, optionV4) - painter.save() - painter.translate(textRect.topLeft()) - painter.setClipRect(textRect.translated(-textRect.topLeft())) - doc.documentLayout().draw(painter, ctx) - painter.restore() - - def sizeHint(self, option, index): - optionV4 = QStyleOptionViewItemV4(option) - self.initStyleOption(optionV4, index) - - doc = QTextDocument() - doc.setHtml(optionV4.text) - doc.setTextWidth(optionV4.rect.width()) - - return QSize(doc.idealWidth(), max(doc.size().height(), optionV4.decorationSize.height())) - - -class _QtValueStr(QLineEdit): - def __init__(self, value): - QLineEdit.__init__(self) - self._value = value - if value.default: - self.setText(unicode(value.default)) - if value.masked: - self.setEchoMode(self.Password) - - def set_value(self, value): - self._value = value - self.setText(self._value.get()) - - def get_value(self): - self._value.set(unicode(self.text())) - return self._value - - -class _QtValueBackendPassword(_QtValueStr): - def get_value(self): - self._value._domain = None - return _QtValueStr.get_value(self) - - -class _QtValueBool(QCheckBox): - def __init__(self, value): - QCheckBox.__init__(self) - self._value = value - if value.default: - self.setChecked(True) - - def set_value(self, value): - self._value = value - self.setChecked(self._value.get()) - - def get_value(self): - self._value.set(self.isChecked()) - return self._value - - -class _QtValueInt(QSpinBox): - def __init__(self, value): - QSpinBox.__init__(self) - self._value = value - if value.default: - self.setValue(int(value.default)) - - def set_value(self, value): - self._value = value - self.setValue(self._value.get()) - - def get_value(self): - self._value.set(self.getValue()) - return self._value - - -class _QtValueChoices(QComboBox): - def __init__(self, value): - QComboBox.__init__(self) - self._value = value - for k, l in value.choices.iteritems(): - self.addItem(l, QVariant(k)) - if value.default == k: - self.setCurrentIndex(self.count()-1) - - def set_value(self, value): - self._value = value - for i in xrange(self.count()): - if unicode(self.itemData(i).toString()) == self._value.get(): - self.setCurrentIndex(i) - return - - def get_value(self): - self._value.set(unicode(self.itemData(self.currentIndex()).toString())) - return self._value - - -def QtValue(value): - if isinstance(value, ValueBool): - klass = _QtValueBool - elif isinstance(value, ValueInt): - klass = _QtValueInt - elif isinstance(value, ValueBackendPassword): - klass = _QtValueBackendPassword - elif value.choices is not None: - klass = _QtValueChoices - else: - klass = _QtValueStr - - return klass(copy(value)) diff --git a/weboob/tools/application/qt/reposdlg.ui b/weboob/tools/application/qt/reposdlg.ui deleted file mode 100644 index 6dc74e3264..0000000000 --- a/weboob/tools/application/qt/reposdlg.ui +++ /dev/null @@ -1,51 +0,0 @@ - - - RepositoriesDlg - - - - 0 - 0 - 400 - 300 - - - - Repositories - - - - - - - - - Qt::Horizontal - - - QDialogButtonBox::Cancel|QDialogButtonBox::Ok - - - - - - - - - buttonBox - rejected() - RepositoriesDlg - reject() - - - 316 - 260 - - - 286 - 274 - - - - - -- GitLab