[view] FormComponent

This commit is contained in:
Vinícius Moreira
2019-12-13 13:28:23 -03:00
parent 4f360bf8ba
commit 7a3df32471
6 changed files with 80 additions and 16 deletions

View File

@@ -114,3 +114,11 @@ class TextInputComponent(ViewComponent):
return self.value.strip() return self.value.strip()
else: else:
return '' return ''
class FormComponent(ViewComponent):
def __init__(self, components: List[ViewComponent], label: str = None, id_: str = None):
super(FormComponent, self).__init__(id_=id_)
self.label = label
self.components = components

View File

@@ -17,7 +17,7 @@ from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher from bauh.api.abstract.handler import ProcessWatcher
from bauh.api.abstract.model import SoftwarePackage, PackageAction, PackageSuggestion, PackageUpdate, PackageHistory from bauh.api.abstract.model import SoftwarePackage, PackageAction, PackageSuggestion, PackageUpdate, PackageHistory
from bauh.api.abstract.view import MessageType, MultipleSelectComponent, InputOption, SingleSelectComponent, \ from bauh.api.abstract.view import MessageType, MultipleSelectComponent, InputOption, SingleSelectComponent, \
SelectViewType, TextInputComponent SelectViewType, TextInputComponent, FormComponent
from bauh.commons.html import bold from bauh.commons.html import bold
from bauh.commons.system import ProcessHandler, get_dir_size, get_human_size_str from bauh.commons.system import ProcessHandler, get_dir_size, get_human_size_str
from bauh.gems.web import INSTALLED_PATH, nativefier, DESKTOP_ENTRY_PATH_PATTERN, URL_FIX_PATTERN from bauh.gems.web import INSTALLED_PATH, nativefier, DESKTOP_ENTRY_PATH_PATTERN, URL_FIX_PATTERN
@@ -215,6 +215,17 @@ class WebApplicationManager(SoftwareManager):
watcher.change_substatus(self.i18n['web.install.substatus.options']) watcher.change_substatus(self.i18n['web.install.substatus.options'])
inp_name = TextInputComponent(label=self.i18n['name'], value=app.name) inp_name = TextInputComponent(label=self.i18n['name'], value=app.name)
inp_desc = TextInputComponent(label=self.i18n['description'], value=app.description)
tray_op_off = InputOption(label=self.i18n['web.install.option.tray.off.label'], value=0, tooltip=self.i18n['web.install.option.tray.off.tip'])
tray_op_default = InputOption(label=self.i18n['web.install.option.tray.default.label'], value='--tray', tooltip=self.i18n['web.install.option.tray.default.tip'])
tray_op_min = InputOption(label=self.i18n['web.install.option.tray.min.label'], value='--tray=start-in-tray', tooltip=self.i18n['web.install.option.tray.min.tip'])
inp_tray = SingleSelectComponent(type_=SelectViewType.COMBO,
options=[tray_op_off, tray_op_default, tray_op_min],
label=self.i18n['web.install.option.tray.label'])
form_1 = FormComponent(components=[inp_name, inp_desc, inp_tray])
op_single = InputOption(id_='single', label=self.i18n['web.install.option.single.label'], value="--single-instance", tooltip=self.i18n['web.install.option.single.tip']) op_single = InputOption(id_='single', label=self.i18n['web.install.option.single.label'], value="--single-instance", tooltip=self.i18n['web.install.option.single.tip'])
op_max = InputOption(id_='max', label=self.i18n['web.install.option.max.label'], value="--maximize", tooltip=self.i18n['web.install.option.max.tip']) op_max = InputOption(id_='max', label=self.i18n['web.install.option.max.label'], value="--maximize", tooltip=self.i18n['web.install.option.max.tip'])
@@ -225,17 +236,12 @@ class WebApplicationManager(SoftwareManager):
op_insecure = InputOption(id_='insecure', label=self.i18n['web.install.option.insecure.label'], value="--insecure", tooltip=self.i18n['web.install.option.insecure.tip']) op_insecure = InputOption(id_='insecure', label=self.i18n['web.install.option.insecure.label'], value="--insecure", tooltip=self.i18n['web.install.option.insecure.tip'])
op_igcert = InputOption(id_='ignore_certs', label=self.i18n['web.install.option.ignore_certificate.label'], value="--ignore-certificate", tooltip=self.i18n['web.install.option.ignore_certificate.tip']) op_igcert = InputOption(id_='ignore_certs', label=self.i18n['web.install.option.ignore_certificate.label'], value="--ignore-certificate", tooltip=self.i18n['web.install.option.ignore_certificate.tip'])
tray_op_off = InputOption(label=self.i18n['web.install.option.tray.off.label'], value=0, tooltip=self.i18n['web.install.option.tray.off.tip'])
tray_op_default = InputOption(label=self.i18n['web.install.option.tray.default.label'], value='--tray', tooltip=self.i18n['web.install.option.tray.default.tip'])
tray_op_min = InputOption(label=self.i18n['web.install.option.tray.min.label'], value='--tray=start-in-tray', tooltip=self.i18n['web.install.option.tray.min.tip'])
check_options = MultipleSelectComponent(options=[op_single, op_allow_urls, op_max, op_fs, op_nframe, op_ncache, op_insecure, op_igcert], default_options={op_single}, label='') check_options = MultipleSelectComponent(options=[op_single, op_allow_urls, op_max, op_fs, op_nframe, op_ncache, op_insecure, op_igcert], default_options={op_single}, label='')
input_tray = SingleSelectComponent(type_=SelectViewType.COMBO, options=[tray_op_off, tray_op_default, tray_op_min], label=self.i18n['web.install.option.tray.label'])
bt_continue = self.i18n['continue'].capitalize() bt_continue = self.i18n['continue'].capitalize()
res = watcher.request_confirmation(title=self.i18n['web.install.options_dialog.title'], res = watcher.request_confirmation(title=self.i18n['web.install.options_dialog.title'],
body=self.i18n['web.install.options_dialog.body'].format(bold(bt_continue)), body=self.i18n['web.install.options_dialog.body'].format(bold(bt_continue)),
components=[inp_name, check_options, input_tray], components=[form_1, check_options],
confirmation_label=bt_continue, confirmation_label=bt_continue,
deny_label=self.i18n['cancel'].capitalize()) deny_label=self.i18n['cancel'].capitalize())
@@ -245,7 +251,7 @@ class WebApplicationManager(SoftwareManager):
if check_options.values: if check_options.values:
selected.extend(check_options.get_selected_values()) selected.extend(check_options.get_selected_values())
tray_mode = input_tray.get_selected_value() tray_mode = inp_tray.get_selected_value()
if tray_mode is not None and tray_mode != 0: if tray_mode is not None and tray_mode != 0:
selected.append(tray_mode) selected.append(tray_mode)
@@ -254,6 +260,11 @@ class WebApplicationManager(SoftwareManager):
if custom_name: if custom_name:
app.name = custom_name app.name = custom_name
custom_desc = inp_desc.get_value()
if custom_desc:
app.description = inp_desc.get_value()
return res, selected return res, selected
return False, [] return False, []

View File

@@ -12,14 +12,14 @@ web.install.substatus.call_nativefier=Running {}
web.install.substatus.shortcut=Generating a menu shortcut web.install.substatus.shortcut=Generating a menu shortcut
web.install.substatus.options=Waiting for the installation options web.install.substatus.options=Waiting for the installation options
web.install.substatus.checking_fixes=Checking if there are published fixes web.install.substatus.checking_fixes=Checking if there are published fixes
web.install.option.single.label=Single web.install.option.single.label=Single run
web.install.option.single.tip=It will not allow the app to be opened again if it is already opened web.install.option.single.tip=It will not allow the app to be opened again if it is already opened
web.install.option.max.label=Open maximized web.install.option.max.label=Open maximized
web.install.option.max.tip=If the app should always be opened maximized web.install.option.max.tip=If the app should always be opened maximized
web.install.option.fullscreen.label=Open in fullscreen web.install.option.fullscreen.label=Open in fullscreen
web.install.option.fullscreen.tip=If the app should always be opened in fullscreen ( the Alt key opens the upper menu ) web.install.option.fullscreen.tip=If the app should always be opened in fullscreen ( the Alt key opens the upper menu )
web.install.option.noframe.label=No frame web.install.option.noframe.label=No frame
web.install.option.noframe.tip=If the app should not have a frame around it ( like browsers have ) web.install.option.noframe.tip=If the app should not have a frame ( like browsers have )
web.install.option.nocache.label=No cache web.install.option.nocache.label=No cache
web.install.option.nocache.tip=Session data will not be stored after the app is closed web.install.option.nocache.tip=Session data will not be stored after the app is closed
web.install.option.insecure.label=Allow insecure content web.install.option.insecure.label=Allow insecure content

View File

@@ -12,14 +12,14 @@ web.install.substatus.call_nativefier=Executando {}
web.install.substatus.shortcut=Criando um atalho no menu web.install.substatus.shortcut=Criando um atalho no menu
web.install.substatus.options=Aguardando as opções de instalação web.install.substatus.options=Aguardando as opções de instalação
web.install.substatus.checking_fixes=Verificando se há correções publicadas web.install.substatus.checking_fixes=Verificando se há correções publicadas
web.install.option.single.label=Único web.install.option.single.label=Execução única
web.install.option.single.tip=Não permitirá que o aplicativo seja aberto novamente caso o mesmo já esteja web.install.option.single.tip=Não permitirá que o aplicativo seja aberto novamente caso o mesmo já esteja
web.install.option.max.label=Abrir maximizado web.install.option.max.label=Abrir maximizado
web.install.option.max.tip=Se o aplicativo deve sempre ser aberto maximizado web.install.option.max.tip=Se o aplicativo deve sempre ser aberto maximizado
web.install.option.fullscreen.label=Abrir em tela cheia web.install.option.fullscreen.label=Abrir em tela cheia
web.install.option.fullscreen.tip=Se o aplicativo sempre deve ser aberto em tela cheia ( a tecla Alt abre o menu superior ) web.install.option.fullscreen.tip=Se o aplicativo sempre deve ser aberto em tela cheia ( a tecla Alt abre o menu superior )
web.install.option.noframe.label=Sem moldura web.install.option.noframe.label=Sem moldura
web.install.option.noframe.tip=Se o aplicativo não deve ter uma moldura em volta ( como os navegadores têm ) web.install.option.noframe.tip=Se o aplicativo não deve ter uma moldura ( como presente nos navegadores )
web.install.option.nocache.label=Sem cache web.install.option.nocache.label=Sem cache
web.install.option.nocache.tip=Dados de sessão não serão armazenados após o aplicativo ser fechado web.install.option.nocache.tip=Dados de sessão não serão armazenados após o aplicativo ser fechado
web.install.option.insecure.label=Permitir conteúdo não confiável web.install.option.insecure.label=Permitir conteúdo não confiável

View File

@@ -1,10 +1,12 @@
from typing import Tuple
from PyQt5.QtCore import Qt from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon, QPixmap from PyQt5.QtGui import QIcon, QPixmap
from PyQt5.QtWidgets import QRadioButton, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \ from PyQt5.QtWidgets import QRadioButton, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \
QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout, QFormLayout
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType, \ from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType, \
TextInputComponent TextInputComponent, FormComponent
from bauh.view.util import resource from bauh.view.util import resource
@@ -135,6 +137,7 @@ class TextInputQt(QGroupBox):
if model.value: if model.value:
self.text_input.setText(model.value) self.text_input.setText(model.value)
self.text_input.setCursorPosition(0)
self.text_input.textChanged.connect(self._update_model) self.text_input.textChanged.connect(self._update_model)
@@ -242,6 +245,45 @@ class IconButton(QWidget):
self.setLayout(layout) self.setLayout(layout)
class FormQt(QGroupBox):
def __init__(self, model: FormComponent):
super(FormQt, self).__init__()
self.model = model
self.setLayout(QFormLayout())
self.setStyleSheet('QLabel { font-weight: bold; }')
for c in model.components:
if isinstance(c, TextInputComponent):
label, field = self._new_text_input(c)
self.layout().addRow(label, field)
elif isinstance(c, SingleSelectComponent):
label = QLabel(c.label.capitalize() + ':' if c.label else '')
field = ComboBoxQt(c)
self.layout().addRow(label, field)
else:
raise Exception('Unsupported component type {}'.format(c.__class__.__name__))
def _new_text_input(self, c: TextInputComponent) -> Tuple[QLabel, QLineEdit]:
line_edit = QLineEdit()
if c.tooltip:
line_edit.setToolTip(c.tooltip)
if c.placeholder:
line_edit.setPlaceholderText(c.placeholder)
if c.value:
line_edit.setText(c.value)
line_edit.setCursorPosition(0)
def update_model(text: str):
c.value = text
line_edit.textChanged.connect(update_model)
return QLabel(c.label.capitalize() + ':' if c.label else ''), line_edit
def new_single_select(model: SingleSelectComponent): def new_single_select(model: SingleSelectComponent):
if model.type == SelectViewType.RADIO: if model.type == SelectViewType.RADIO:
return RadioSelectQt(model) return RadioSelectQt(model)

View File

@@ -3,9 +3,10 @@ from typing import List
from PyQt5.QtCore import QSize from PyQt5.QtCore import QSize
from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget, QScrollArea, QFrame from PyQt5.QtWidgets import QMessageBox, QVBoxLayout, QLabel, QWidget, QScrollArea, QFrame
from bauh.api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent, TextInputComponent from bauh.api.abstract.view import ViewComponent, SingleSelectComponent, MultipleSelectComponent, TextInputComponent, \
FormComponent
from bauh.view.qt import css from bauh.view.qt import css
from bauh.view.qt.components import MultipleSelectQt, new_single_select, TextInputQt from bauh.view.qt.components import MultipleSelectQt, new_single_select, TextInputQt, FormQt
from bauh.view.util.translation import I18n from bauh.view.util.translation import I18n
@@ -45,6 +46,8 @@ class ConfirmationDialog(QMessageBox):
inst = MultipleSelectQt(comp, None) inst = MultipleSelectQt(comp, None)
elif isinstance(comp, TextInputComponent): elif isinstance(comp, TextInputComponent):
inst = TextInputQt(comp) inst = TextInputQt(comp)
elif isinstance(comp, FormComponent):
inst = FormQt(comp)
else: else:
raise Exception("Cannot render instances of " + comp.__class__.__name__) raise Exception("Cannot render instances of " + comp.__class__.__name__)