substatus | confirmation dialog component

This commit is contained in:
Vinicius Moreira
2019-08-21 17:54:20 -03:00
parent f46745f472
commit 035b8e6775
7 changed files with 221 additions and 9 deletions

View File

@@ -83,4 +83,5 @@ manage_window.bt_about.tooltip=About
warning.no_managers=There are no installed extensions. It will not be possible to intall and manage applications.
confirmation=confirmation
and=and
error=error
error=error
action.cancelled=operation cancelled by the user

View File

@@ -85,4 +85,5 @@ manage_window.bt_about.tooltip=Sobre
warning.no_managers=No hay extensiones instaladas. No será posible instalar y administrar aplicaciones.
confirmation=confirmación
and=y
error=error
error=error
action.cancelled=operación cancelada por el usuario

View File

@@ -85,4 +85,5 @@ manage_window.bt_about.tooltip=Sobre
warning.no_managers=Não há nenhuma extensão instalada. Não será possível instalar e gerenciar aplicações.
confirmation=confirmação
and=e
error=erro
error=erro
action.cancelled=operação cancelada pelo usuário

137
bauh/view/qt/components.py Normal file
View File

@@ -0,0 +1,137 @@
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import QRadioButton, QFormLayout, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \
QVBoxLayout, QLabel
from bauh_api.abstract.view import SingleSelectComponent, SelectOption, MultipleSelectComponent, SelectViewType
class RadioButtonQt(QRadioButton):
def __init__(self, model: SelectOption, model_parent: SingleSelectComponent):
super(RadioButtonQt, self).__init__()
self.model = model
self.model_parent = model_parent
self.toggled.connect(self._set_checked)
def _set_checked(self, checked: bool):
if checked:
self.model_parent.value = self.model
class CheckboxQt(QCheckBox):
def __init__(self, model: SelectOption, model_parent: MultipleSelectComponent):
super(CheckboxQt, self).__init__()
self.model = model
self.model_parent = model_parent
self.stateChanged.connect(self._set_checked)
def _set_checked(self, state):
if state == 2:
self.model_parent.values.add(self.model)
else:
if self.model in self.model_parent.values:
self.model_parent.values.remove(self.model)
class ComboBoxQt(QComboBox):
def __init__(self, model: SingleSelectComponent):
super(ComboBoxQt, self).__init__()
self.model = model
for idx, op in enumerate(self.model.options):
self.addItem(op.label, op.value)
if model.value and model.value == op: # default
self.setCurrentIndex(idx)
self.currentIndexChanged.connect(self._set_selected)
def _set_selected(self, idx: int):
self.model.value = self.model.options[idx]
class RadioSelectQt(QGroupBox):
def __init__(self, model: SingleSelectComponent):
super(RadioSelectQt, self).__init__(model.label + ' :')
self.model = model
self.setStyleSheet("QGroupBox { font-weight: bold }")
grid = QGridLayout()
self.setLayout(grid)
line, col = 0, 0
for op in model.options:
comp = RadioButtonQt(op, model)
comp.setText(op.label)
comp.setToolTip(op.tooltip)
if model.value and model.value == op:
self.value = comp
comp.setChecked(True)
grid.addWidget(comp, line, col)
if col + 1 == self.model.max_per_line:
line += 1
col = 0
else:
col += 1
class ComboSelectQt(QGroupBox):
def __init__(self, model: SingleSelectComponent):
super(ComboSelectQt, self).__init__()
self.model = model
self.setLayout(QGridLayout())
self.setStyleSheet('QGridLayout {margin-left: 0} QLabel { font-weight: bold}')
self.layout().addWidget(QLabel(model.label + ' :'), 0, 0)
self.layout().addWidget(ComboBoxQt(model), 0, 1)
# class ComboSelectQt(QGroupBox):
#
# def __init__(self, model: SingleSelectComponent):
# super(ComboSelectQt, self).__init__(model.label + ' :')
# self.model = model
# self.setLayout(QGridLayout())
# self.setStyleSheet('QGridLayout {margin-left: 0} QLabel { font-weight: bold}')
# self.layout().addWidget(ComboBoxQt(model), 0, 1)
class MultipleSelectQt(QGroupBox):
def __init__(self, model: MultipleSelectComponent):
super(MultipleSelectQt, self).__init__(model.label + ' :')
self.setStyleSheet("QGroupBox { font-weight: bold }")
self.model = model
self._layout = QGridLayout()
self.setLayout(self._layout)
line, col = 0, 0
for op in model.options:
comp = CheckboxQt(op, model)
comp.setText(op.label)
comp.setToolTip(op.tooltip)
if model.values and op in model.values:
self.value = comp
comp.setChecked(True)
self._layout.addWidget(comp, line, col)
if col + 1 == self.model.max_per_line:
line += 1
col = 0
else:
col += 1
def new_single_select(model: SingleSelectComponent):
if model.type == SelectViewType.RADIO:
return RadioSelectQt(model)
elif model.type == SelectViewType.COMBO:
return ComboSelectQt(model)
else:
raise Exception("Unsupported type {}".format(model.type))

View File

@@ -0,0 +1,44 @@
from typing import List
from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget
from bauh_api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent
from bauh.view.qt.components import MultipleSelectQt, new_single_select
class ConfirmationDialog(QMessageBox):
def __init__(self, title: str, body: str, locale_keys: dict, components: List[ViewComponent] = None):
super(ConfirmationDialog, self).__init__()
self.setWindowTitle(title)
self.setStyleSheet('QLabel { margin-right: 25px; }')
self.bt_yes = self.addButton(locale_keys['popup.button.yes'], QMessageBox.YesRole)
self.addButton(locale_keys['popup.button.no'], QMessageBox.NoRole)
if body:
if components:
self.layout().addWidget(QLabel(body), 0, 1)
else:
self.setIcon(QMessageBox.Question)
self.setText(body)
if components:
comps_container = QWidget(parent=self)
comps_container.setLayout(QVBoxLayout())
for idx, comp in enumerate(components):
if isinstance(comp, SingleSelectComponent):
inst = new_single_select(comp)
elif isinstance(comp, MultipleSelectComponent):
inst = MultipleSelectQt(comp)
else:
raise Exception("Cannot render instances of " + comp.__class__.__name__)
comps_container.layout().addWidget(inst)
self.layout().addWidget(comps_container, 1, 1)
self.exec_()
def is_confirmed(self):
return self.clickedButton() == self.bt_yes

View File

@@ -7,6 +7,7 @@ from PyQt5.QtCore import QThread, pyqtSignal
from bauh_api.abstract.controller import ApplicationManager
from bauh_api.abstract.handler import ProcessWatcher
from bauh_api.abstract.model import ApplicationStatus
from bauh_api.abstract.view import InputViewComponent
from bauh_api.exception import NoInternetException
from bauh_api.util.cache import Cache
@@ -20,20 +21,21 @@ class AsyncAction(QThread, ProcessWatcher):
signal_finished = pyqtSignal(object) # informs the main window that the action has finished
signal_error = pyqtSignal(dict) # asks the GUI to show an error popup
signal_status = pyqtSignal(str) # changes the GUI status message
signal_substatus = pyqtSignal(str) # changes the GUI substatus message
def __init__(self):
super(AsyncAction, self).__init__()
self.wait_confirmation = False
self.confirmation_res = None
def request_confirmation(self, title: str, body: str, options: dict) -> dict:
def request_confirmation(self, title: str, body: str, options: List[InputViewComponent] = None) -> bool:
self.wait_confirmation = True
self.signal_confirmation.emit({'title': title, 'body': body, 'options': options})
self.wait_user()
return self.confirmation_res
def confirm(self, msg: dict):
self.confirmation_res = msg
def confirm(self, res: bool):
self.confirmation_res = res
self.wait_confirmation = False
def wait_user(self):
@@ -53,6 +55,9 @@ class AsyncAction(QThread, ProcessWatcher):
def change_status(self, status: str):
self.signal_status.emit(status)
def change_substatus(self, substatus: str):
self.signal_substatus.emit(substatus)
class UpdateSelectedApps(AsyncAction):

View File

@@ -15,6 +15,7 @@ from bauh.util import util
from bauh.view.qt import dialog
from bauh.view.qt.about import AboutDialog
from bauh.view.qt.apps_table import AppsTable
from bauh.view.qt.confirmation import ConfirmationDialog
from bauh.view.qt.history import HistoryDialog
from bauh.view.qt.info import InfoDialog
from bauh.view.qt.root import is_root, ask_root_password
@@ -29,7 +30,7 @@ DARK_ORANGE = '#FF4500'
class ManageWindow(QWidget):
__BASE_HEIGHT__ = 400
signal_user_res = pyqtSignal(dict)
signal_user_res = pyqtSignal(bool)
def __init__(self, locale_keys: dict, icon_cache: Cache, manager: ApplicationManager, disk_cache: bool, download_icons: bool, screen_size, suggestions: bool, tray_icon=None):
super(ManageWindow, self).__init__()
@@ -133,6 +134,7 @@ class ManageWindow(QWidget):
self.ref_checkbox_console = toolbar_console.addWidget(self.checkbox_console)
toolbar_console.addWidget(self._new_spacer())
self.layout.addWidget(toolbar_console)
self.textarea_output = QPlainTextEdit(self)
@@ -184,6 +186,14 @@ class ManageWindow(QWidget):
self.layout.addWidget(self.toolbar_bottom)
self.toolbar_substatus = QToolBar()
self.toolbar_substatus.addWidget(self._new_spacer())
self.label_substatus = QLabel()
self.toolbar_substatus.addWidget(self.label_substatus)
self.toolbar_substatus.addWidget(self._new_spacer())
self.layout.addWidget(self.toolbar_substatus)
self._change_label_substatus('')
self.centralize()
self.filter_only_apps = True
@@ -205,13 +215,14 @@ class ManageWindow(QWidget):
action.signal_output.connect(self._update_action_output)
action.signal_error.connect(self._show_error)
action.signal_status.connect(self._change_label_status)
action.signal_substatus.connect(self._change_label_substatus)
self.signal_user_res.connect(action.confirm)
return action
def _ask_confirmation(self, msg: dict):
res = dialog.ask_confirmation(msg['title'], msg['body'], self.locale_keys)
self.signal_user_res.emit({'proceed': res, 'options': {}})
diag = ConfirmationDialog(msg['title'], msg['body'], self.locale_keys)
self.signal_user_res.emit(diag.is_confirmed())
def _show_error(self, msg: dict):
dialog.show_error(title=msg['title'], body=msg['body'])
@@ -385,6 +396,16 @@ class ManageWindow(QWidget):
def _change_label_status(self, status: str):
self.label_status.setText(status)
def _change_label_substatus(self, substatus: str):
if not substatus:
self.label_substatus.setText(substatus)
self.toolbar_substatus.hide()
else:
if not self.toolbar_substatus.isVisible():
self.toolbar_substatus.show()
self.label_substatus.setText("( {} )".format(substatus))
def apply_filters(self):
if self.apps:
visible_apps = len(self.apps)
@@ -600,6 +621,7 @@ class ManageWindow(QWidget):
self.extra_filters.setEnabled(False)
def finish_action(self):
self._change_label_substatus('')
self.ref_bt_about.setVisible(True)
self.ref_progress_bar.setVisible(False)
self.ref_label_updates.setVisible(True)
@@ -610,6 +632,7 @@ class ManageWindow(QWidget):
self.table_apps.setEnabled(True)
self.input_search.setEnabled(True)
self.label_status.setText('')
self.label_substatus.setText('')
self.ref_toolbar_search.setVisible(True)
self.ref_toolbar_search.setEnabled(True)
self.extra_filters.setEnabled(True)