mirror of
https://github.com/spalencsar/bearhub.git
synced 2026-07-09 16:44:15 +02:00
[ui][settings] improvements
This commit is contained in:
@@ -3,7 +3,7 @@ import os
|
|||||||
import shutil
|
import shutil
|
||||||
from abc import ABC, abstractmethod
|
from abc import ABC, abstractmethod
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Set, Type
|
from typing import List, Set, Type, Tuple
|
||||||
|
|
||||||
import yaml
|
import yaml
|
||||||
|
|
||||||
@@ -279,3 +279,9 @@ class SoftwareManager(ABC):
|
|||||||
:return: a form abstraction with all available settings
|
:return: a form abstraction with all available settings
|
||||||
"""
|
"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
def save_settings(self, component: ViewComponent) -> Tuple[bool, List[str]]:
|
||||||
|
"""
|
||||||
|
:return: a tuple with a bool informing if the settings were saved and a list of error messages
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|||||||
@@ -17,6 +17,18 @@ class ViewComponent(ABC):
|
|||||||
self.id = id_
|
self.id = id_
|
||||||
|
|
||||||
|
|
||||||
|
class PanelComponent(ViewComponent):
|
||||||
|
|
||||||
|
def __init__(self, components: List[ViewComponent], id_: str = None):
|
||||||
|
super(PanelComponent, self).__init__(id_=id_)
|
||||||
|
self.components = components
|
||||||
|
self.component_map = {c.id: c for c in components if c.id is not None} if components else None
|
||||||
|
|
||||||
|
def get_component(self, id_: str) -> ViewComponent:
|
||||||
|
if self.component_map:
|
||||||
|
return self.component_map.get(id_)
|
||||||
|
|
||||||
|
|
||||||
class InputViewComponent(ViewComponent):
|
class InputViewComponent(ViewComponent):
|
||||||
"""
|
"""
|
||||||
Represents an component which needs a user interaction to provide its value
|
Represents an component which needs a user interaction to provide its value
|
||||||
@@ -99,13 +111,14 @@ class TextComponent(ViewComponent):
|
|||||||
|
|
||||||
class TextInputComponent(ViewComponent):
|
class TextInputComponent(ViewComponent):
|
||||||
|
|
||||||
def __init__(self, label: str, value: str = '', placeholder: str = None, tooltip: str = None, read_only: bool =False, id_: str = None):
|
def __init__(self, label: str, value: str = '', placeholder: str = None, tooltip: str = None, read_only: bool =False, id_: str = None, only_int: bool = False):
|
||||||
super(TextInputComponent, self).__init__(id_=id_)
|
super(TextInputComponent, self).__init__(id_=id_)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.value = value
|
self.value = value
|
||||||
self.tooltip = tooltip
|
self.tooltip = tooltip
|
||||||
self.placeholder = placeholder
|
self.placeholder = placeholder
|
||||||
self.read_only = read_only
|
self.read_only = read_only
|
||||||
|
self.only_int = only_int
|
||||||
|
|
||||||
def get_value(self) -> str:
|
def get_value(self) -> str:
|
||||||
if self.value is not None:
|
if self.value is not None:
|
||||||
@@ -113,6 +126,11 @@ class TextInputComponent(ViewComponent):
|
|||||||
else:
|
else:
|
||||||
return ''
|
return ''
|
||||||
|
|
||||||
|
def get_int_value(self) -> int:
|
||||||
|
if self.value is not None:
|
||||||
|
return int(self.value)
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
class FormComponent(ViewComponent):
|
class FormComponent(ViewComponent):
|
||||||
|
|
||||||
@@ -120,6 +138,11 @@ class FormComponent(ViewComponent):
|
|||||||
super(FormComponent, self).__init__(id_=id_)
|
super(FormComponent, self).__init__(id_=id_)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.components = components
|
self.components = components
|
||||||
|
self.component_map = {c.id : c for c in components if c.id} if components else None
|
||||||
|
|
||||||
|
def get_component(self, id_: str) -> ViewComponent:
|
||||||
|
if self.component_map:
|
||||||
|
return self.component_map.get(id_)
|
||||||
|
|
||||||
|
|
||||||
class FileChooserComponent(ViewComponent):
|
class FileChooserComponent(ViewComponent):
|
||||||
@@ -133,14 +156,20 @@ class FileChooserComponent(ViewComponent):
|
|||||||
|
|
||||||
class TabComponent(ViewComponent):
|
class TabComponent(ViewComponent):
|
||||||
|
|
||||||
def __init__(self, label: str, content: ViewComponent, id_: str = None):
|
def __init__(self, label: str, content: ViewComponent, icon_path: str = None, id_: str = None):
|
||||||
super(TabComponent, self).__init__(id_=id_)
|
super(TabComponent, self).__init__(id_=id_)
|
||||||
self.label = label
|
self.label = label
|
||||||
self.content = content
|
self.content = content
|
||||||
|
self.icon_path = icon_path
|
||||||
|
|
||||||
|
|
||||||
class TabGroupComponent(ViewComponent):
|
class TabGroupComponent(ViewComponent):
|
||||||
|
|
||||||
def __init__(self, components: List[TabComponent], id_: str = None):
|
def __init__(self, tabs: List[TabComponent], id_: str = None):
|
||||||
super(TabGroupComponent, self).__init__(id_=id_)
|
super(TabGroupComponent, self).__init__(id_=id_)
|
||||||
self.components = components
|
self.tabs = tabs
|
||||||
|
self.tab_map = {c.id: c for c in tabs if c.id} if tabs else None
|
||||||
|
|
||||||
|
def get_tab(self, id_: str) -> TabComponent:
|
||||||
|
if self.tab_map:
|
||||||
|
return self.tab_map.get(id_)
|
||||||
|
|||||||
@@ -19,7 +19,8 @@ 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, PackageHistory, PackageUpdate, PackageSuggestion, \
|
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
|
||||||
SuggestionPriority
|
SuggestionPriority
|
||||||
from bauh.api.abstract.view import MessageType
|
from bauh.api.abstract.view import MessageType, ViewComponent, FormComponent, InputOption, SingleSelectComponent, \
|
||||||
|
SelectViewType, TextInputComponent, PanelComponent
|
||||||
from bauh.commons.html import bold
|
from bauh.commons.html import bold
|
||||||
from bauh.commons.system import SystemProcess, new_subprocess, ProcessHandler, run_cmd, SimpleProcess
|
from bauh.commons.system import SystemProcess, new_subprocess, ProcessHandler, run_cmd, SimpleProcess
|
||||||
from bauh.gems.appimage import query, INSTALLATION_PATH, LOCAL_PATH, SUGGESTIONS_FILE
|
from bauh.gems.appimage import query, INSTALLATION_PATH, LOCAL_PATH, SUGGESTIONS_FILE
|
||||||
@@ -494,5 +495,23 @@ class AppImageManager(SoftwareManager):
|
|||||||
os.remove(f)
|
os.remove(f)
|
||||||
print('{}[bauh][appimage] {} deleted{}'.format(Fore.YELLOW, f, Fore.RESET))
|
print('{}[bauh][appimage] {} deleted{}'.format(Fore.YELLOW, f, Fore.RESET))
|
||||||
except:
|
except:
|
||||||
print('{}[bauh][appimage] An exception has happened when deleting {}{}'.format(Fore.RED, Fore.RESET))
|
print('{}[bauh][appimage] An exception has happened when deleting {}{}'.format(Fore.RED, f, Fore.RESET))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def get_settings(self) -> ViewComponent:
|
||||||
|
|
||||||
|
config = read_config()
|
||||||
|
|
||||||
|
enabled_opts = [InputOption(label=self.i18n['yes'].capitalize(), value=True),
|
||||||
|
InputOption(label=self.i18n['no'].capitalize(), value=False)]
|
||||||
|
|
||||||
|
updater_opts = [
|
||||||
|
SingleSelectComponent(label='Enabled',
|
||||||
|
options=enabled_opts,
|
||||||
|
default_option=[o for o in enabled_opts if o.value == config['db_updater']['enabled']][0],
|
||||||
|
max_per_line=len(enabled_opts),
|
||||||
|
type_=SelectViewType.RADIO),
|
||||||
|
TextInputComponent(label='Interval', value=str(config['db_updater']['interval']), tooltip="Update interval in SECONDS", only_int=True)
|
||||||
|
]
|
||||||
|
|
||||||
|
return PanelComponent([FormComponent(updater_opts, 'Database updates')])
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ from bauh.api.abstract.handler import ProcessWatcher
|
|||||||
from bauh.api.abstract.model import PackageUpdate, PackageHistory, SoftwarePackage, PackageSuggestion, PackageStatus, \
|
from bauh.api.abstract.model import PackageUpdate, PackageHistory, SoftwarePackage, PackageSuggestion, PackageStatus, \
|
||||||
SuggestionPriority
|
SuggestionPriority
|
||||||
from bauh.api.abstract.view import MessageType, FormComponent, InputOption, SingleSelectComponent, SelectViewType, \
|
from bauh.api.abstract.view import MessageType, FormComponent, InputOption, SingleSelectComponent, SelectViewType, \
|
||||||
ViewComponent
|
ViewComponent, PanelComponent
|
||||||
from bauh.commons.category import CategoriesDownloader
|
from bauh.commons.category import CategoriesDownloader
|
||||||
from bauh.commons.html import bold
|
from bauh.commons.html import bold
|
||||||
from bauh.commons.system import SystemProcess, ProcessHandler, new_subprocess, run_cmd, new_root_subprocess, \
|
from bauh.commons.system import SystemProcess, ProcessHandler, new_subprocess, run_cmd, new_root_subprocess, \
|
||||||
@@ -906,4 +906,4 @@ class ArchManager(SoftwareManager):
|
|||||||
max_per_line=len(trans_check_opts),
|
max_per_line=len(trans_check_opts),
|
||||||
type_=SelectViewType.RADIO)]
|
type_=SelectViewType.RADIO)]
|
||||||
|
|
||||||
return FormComponent([FormComponent(fields, label='Installation')])
|
return PanelComponent([FormComponent(fields, label='Installation')])
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ from bauh.api.abstract.handler import ProcessWatcher
|
|||||||
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \
|
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \
|
||||||
SuggestionPriority
|
SuggestionPriority
|
||||||
from bauh.api.abstract.view import MessageType, FormComponent, SingleSelectComponent, InputOption, SelectViewType, \
|
from bauh.api.abstract.view import MessageType, FormComponent, SingleSelectComponent, InputOption, SelectViewType, \
|
||||||
ViewComponent
|
ViewComponent, PanelComponent
|
||||||
from bauh.commons import user
|
from bauh.commons import user
|
||||||
from bauh.commons.html import strip_html, bold
|
from bauh.commons.html import strip_html, bold
|
||||||
from bauh.commons.system import SystemProcess, ProcessHandler, SimpleProcess
|
from bauh.commons.system import SystemProcess, ProcessHandler, SimpleProcess
|
||||||
@@ -431,4 +431,4 @@ class FlatpakManager(SoftwareManager):
|
|||||||
max_per_line=len(install_opts),
|
max_per_line=len(install_opts),
|
||||||
type_=SelectViewType.RADIO))
|
type_=SelectViewType.RADIO))
|
||||||
|
|
||||||
return FormComponent([FormComponent(fields, 'Installation')])
|
return PanelComponent([FormComponent(fields, 'Installation')])
|
||||||
|
|||||||
@@ -12,3 +12,4 @@ def read_config(update_file: bool = False) -> dict:
|
|||||||
|
|
||||||
return read(CONFIG_FILE, default_config, update_file)
|
return read(CONFIG_FILE, default_config, update_file)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -21,13 +21,14 @@ 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, \
|
||||||
SuggestionPriority, PackageStatus
|
SuggestionPriority, PackageStatus
|
||||||
from bauh.api.abstract.view import MessageType, MultipleSelectComponent, InputOption, SingleSelectComponent, \
|
from bauh.api.abstract.view import MessageType, MultipleSelectComponent, InputOption, SingleSelectComponent, \
|
||||||
SelectViewType, TextInputComponent, FormComponent, FileChooserComponent
|
SelectViewType, TextInputComponent, FormComponent, FileChooserComponent, ViewComponent, PanelComponent
|
||||||
from bauh.api.constants import DESKTOP_ENTRIES_DIR
|
from bauh.api.constants import DESKTOP_ENTRIES_DIR
|
||||||
from bauh.commons import resource
|
from bauh.commons import resource
|
||||||
|
from bauh.commons.config import save_config
|
||||||
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, ENV_PATH, UA_CHROME, \
|
from bauh.gems.web import INSTALLED_PATH, nativefier, DESKTOP_ENTRY_PATH_PATTERN, URL_FIX_PATTERN, ENV_PATH, UA_CHROME, \
|
||||||
SEARCH_INDEX_FILE, SUGGESTIONS_CACHE_FILE, ROOT_DIR
|
SEARCH_INDEX_FILE, SUGGESTIONS_CACHE_FILE, ROOT_DIR, CONFIG_FILE
|
||||||
from bauh.gems.web.config import read_config
|
from bauh.gems.web.config import read_config
|
||||||
from bauh.gems.web.environment import EnvironmentUpdater, EnvironmentComponent
|
from bauh.gems.web.environment import EnvironmentUpdater, EnvironmentComponent
|
||||||
from bauh.gems.web.model import WebApplication
|
from bauh.gems.web.model import WebApplication
|
||||||
@@ -889,3 +890,49 @@ class WebApplicationManager(SoftwareManager):
|
|||||||
except:
|
except:
|
||||||
print('{}[bauh][web] An exception has happened when deleting {}{}'.format(Fore.RED, ENV_PATH, Fore.RESET))
|
print('{}[bauh][web] An exception has happened when deleting {}{}'.format(Fore.RED, ENV_PATH, Fore.RESET))
|
||||||
traceback.print_exc()
|
traceback.print_exc()
|
||||||
|
|
||||||
|
def get_settings(self) -> ViewComponent:
|
||||||
|
config = read_config()
|
||||||
|
|
||||||
|
input_electron = TextInputComponent(label="Custom Electron version",
|
||||||
|
value=config['environment']['electron']['version'],
|
||||||
|
tooltip="Electron version to render the applications",
|
||||||
|
id_='electron_version')
|
||||||
|
|
||||||
|
native_opts = [
|
||||||
|
InputOption(label="Environment", value=False, tooltip="If a nativefier version from the isolated environment should be used to install the applications"),
|
||||||
|
InputOption(label="System", value=True, tooltip="If a nativefier installed on your system should be used to install the applications")
|
||||||
|
]
|
||||||
|
|
||||||
|
select_nativefier = SingleSelectComponent(label="Nativefier",
|
||||||
|
options=native_opts,
|
||||||
|
default_option=[o for o in native_opts if o.value == config['environment']['system']][0],
|
||||||
|
type_=SelectViewType.COMBO,
|
||||||
|
id_='nativefier')
|
||||||
|
|
||||||
|
form_env = FormComponent(label="Environment", components=[input_electron, select_nativefier])
|
||||||
|
|
||||||
|
return PanelComponent([form_env])
|
||||||
|
|
||||||
|
def save_settings(self, component: PanelComponent) -> Tuple[bool, List[str]]:
|
||||||
|
config = read_config()
|
||||||
|
|
||||||
|
form_env = component.components[0]
|
||||||
|
|
||||||
|
config['environment']['electron']['version'] = str(form_env.get_component('electron_version').get_value()).strip()
|
||||||
|
|
||||||
|
if len(config['environment']['electron']['version']) == 0:
|
||||||
|
config['environment']['electron']['version'] = None
|
||||||
|
|
||||||
|
system_nativefier = form_env.get_component('nativefier').get_selected()
|
||||||
|
|
||||||
|
if system_nativefier and not nativefier.is_available():
|
||||||
|
return False, ['Nativefier seems not to be installed on your system']
|
||||||
|
|
||||||
|
config['environment']['system'] = system_nativefier
|
||||||
|
|
||||||
|
try:
|
||||||
|
save_config(config, CONFIG_FILE)
|
||||||
|
return True, None
|
||||||
|
except:
|
||||||
|
return False, [traceback.format_exc()]
|
||||||
|
|||||||
@@ -2,8 +2,9 @@ import re
|
|||||||
import time
|
import time
|
||||||
import traceback
|
import traceback
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from typing import List, Set, Type
|
from typing import List, Set, Type, Tuple
|
||||||
|
|
||||||
|
from bauh import ROOT_DIR
|
||||||
from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext
|
from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext
|
||||||
from bauh.api.abstract.disk import DiskCacheLoader
|
from bauh.api.abstract.disk import DiskCacheLoader
|
||||||
from bauh.api.abstract.handler import ProcessWatcher
|
from bauh.api.abstract.handler import ProcessWatcher
|
||||||
@@ -410,6 +411,30 @@ class GenericSoftwareManager(SoftwareManager):
|
|||||||
man_comp = man.get_settings()
|
man_comp = man.get_settings()
|
||||||
|
|
||||||
if man_comp:
|
if man_comp:
|
||||||
settings_forms.append(TabComponent(man.__class__.__name__, man_comp))
|
modname = man.__module__.split('.')[-2]
|
||||||
|
icon_path = "{r}/gems/{n}/resources/img/{n}.svg".format(r=ROOT_DIR, n=modname)
|
||||||
|
settings_forms.append(TabComponent(None, man_comp, icon_path, modname))
|
||||||
|
|
||||||
return TabGroupComponent(settings_forms)
|
return TabGroupComponent(settings_forms)
|
||||||
|
|
||||||
|
def save_settings(self, component: TabGroupComponent) -> Tuple[bool, List[str]]:
|
||||||
|
|
||||||
|
saved, warnings = True, []
|
||||||
|
|
||||||
|
for man in self.managers:
|
||||||
|
if man:
|
||||||
|
modname = man.__module__.split('.')[-2]
|
||||||
|
tab = component.get_tab(modname)
|
||||||
|
|
||||||
|
if not tab:
|
||||||
|
self.logger.warning("Tab for {} was not found".format(man.__class__.__name__))
|
||||||
|
else:
|
||||||
|
success, errors = man.save_settings(tab.content)
|
||||||
|
|
||||||
|
if not success:
|
||||||
|
saved = False
|
||||||
|
|
||||||
|
if errors:
|
||||||
|
warnings.extend(errors)
|
||||||
|
|
||||||
|
return saved, warnings
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ from pathlib import Path
|
|||||||
from typing import Tuple
|
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, QIntValidator
|
||||||
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, QFormLayout, QFileDialog, QTabWidget
|
QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout, QFormLayout, QFileDialog, QTabWidget, QVBoxLayout
|
||||||
|
|
||||||
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType, \
|
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType, \
|
||||||
TextInputComponent, FormComponent, FileChooserComponent, ViewComponent, TabGroupComponent
|
TextInputComponent, FormComponent, FileChooserComponent, ViewComponent, TabGroupComponent, PanelComponent
|
||||||
from bauh.view.qt import css
|
from bauh.view.qt import css
|
||||||
from bauh.view.util import resource
|
from bauh.view.util import resource
|
||||||
from bauh.view.util.translation import I18n
|
from bauh.view.util.translation import I18n
|
||||||
@@ -162,6 +162,9 @@ class TextInputQt(QGroupBox):
|
|||||||
|
|
||||||
self.text_input = QLineEdit()
|
self.text_input = QLineEdit()
|
||||||
|
|
||||||
|
if model.only_int:
|
||||||
|
self.text_input.setValidator(QIntValidator())
|
||||||
|
|
||||||
if model.placeholder:
|
if model.placeholder:
|
||||||
self.text_input.setPlaceholderText(model.placeholder)
|
self.text_input.setPlaceholderText(model.placeholder)
|
||||||
|
|
||||||
@@ -302,6 +305,20 @@ class IconButton(QWidget):
|
|||||||
self.bt.setToolTip(self.default_tootip)
|
self.bt.setToolTip(self.default_tootip)
|
||||||
|
|
||||||
|
|
||||||
|
class PanelQt(QWidget):
|
||||||
|
|
||||||
|
def __init__(self, model: PanelComponent, i18n: I18n, parent: QWidget = None):
|
||||||
|
super(PanelQt, self).__init__(parent=parent)
|
||||||
|
self.model = model
|
||||||
|
self.i18n = i18n
|
||||||
|
self.setLayout(QVBoxLayout())
|
||||||
|
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||||
|
|
||||||
|
if model.components:
|
||||||
|
for c in model.components:
|
||||||
|
self.layout().addWidget(to_widget(c, i18n))
|
||||||
|
|
||||||
|
|
||||||
class FormQt(QGroupBox):
|
class FormQt(QGroupBox):
|
||||||
|
|
||||||
def __init__(self, model: FormComponent, i18n: I18n):
|
def __init__(self, model: FormComponent, i18n: I18n):
|
||||||
@@ -334,6 +351,9 @@ class FormQt(QGroupBox):
|
|||||||
def _new_text_input(self, c: TextInputComponent) -> Tuple[QLabel, QLineEdit]:
|
def _new_text_input(self, c: TextInputComponent) -> Tuple[QLabel, QLineEdit]:
|
||||||
line_edit = QLineEdit()
|
line_edit = QLineEdit()
|
||||||
|
|
||||||
|
if c.only_int:
|
||||||
|
line_edit.setValidator(QIntValidator())
|
||||||
|
|
||||||
if c.tooltip:
|
if c.tooltip:
|
||||||
line_edit.setToolTip(c.tooltip)
|
line_edit.setToolTip(c.tooltip)
|
||||||
|
|
||||||
@@ -388,10 +408,11 @@ class TabGroupQt(QTabWidget):
|
|||||||
def __init__(self, model: TabGroupComponent, i18n: I18n, parent: QWidget = None):
|
def __init__(self, model: TabGroupComponent, i18n: I18n, parent: QWidget = None):
|
||||||
super(TabGroupQt, self).__init__(parent=parent)
|
super(TabGroupQt, self).__init__(parent=parent)
|
||||||
self.model = model
|
self.model = model
|
||||||
self.setTabPosition(QTabWidget.West)
|
self.setTabPosition(QTabWidget.North)
|
||||||
|
|
||||||
for c in model.components:
|
for c in model.tabs:
|
||||||
self.addTab(to_widget(c.content, i18n), c.label)
|
icon = QIcon(c.icon_path) if c.icon_path else None
|
||||||
|
self.addTab(to_widget(c.content, i18n), icon, c.label)
|
||||||
|
|
||||||
|
|
||||||
def new_single_select(model: SingleSelectComponent) -> QWidget:
|
def new_single_select(model: SingleSelectComponent) -> QWidget:
|
||||||
@@ -424,5 +445,7 @@ def to_widget(comp: ViewComponent, i18n: I18n, parent: QWidget = None) -> QWidge
|
|||||||
return FormQt(comp, i18n)
|
return FormQt(comp, i18n)
|
||||||
elif isinstance(comp, TabGroupComponent):
|
elif isinstance(comp, TabGroupComponent):
|
||||||
return TabGroupQt(comp, i18n, parent)
|
return TabGroupQt(comp, i18n, parent)
|
||||||
|
elif isinstance(comp, PanelComponent):
|
||||||
|
return PanelQt(comp, i18n, parent)
|
||||||
else:
|
else:
|
||||||
raise Exception("Cannot render instances of " + comp.__class__.__name__)
|
raise Exception("Cannot render instances of " + comp.__class__.__name__)
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolBar, QSizePolicy, QToolButton
|
from io import StringIO
|
||||||
|
|
||||||
|
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QToolBar, QSizePolicy, QToolButton, QPushButton
|
||||||
|
|
||||||
from bauh.api.abstract.controller import SoftwareManager
|
from bauh.api.abstract.controller import SoftwareManager
|
||||||
from bauh.view.qt.components import to_widget
|
from bauh.api.abstract.view import MessageType
|
||||||
|
from bauh.view.qt import dialog
|
||||||
|
from bauh.view.qt.components import to_widget, new_spacer
|
||||||
from bauh.view.util.translation import I18n
|
from bauh.view.util.translation import I18n
|
||||||
|
|
||||||
|
|
||||||
@@ -15,15 +19,39 @@ class SettingsWindow(QWidget):
|
|||||||
self.i18n = i18n
|
self.i18n = i18n
|
||||||
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||||
|
|
||||||
settings_model = self.manager.get_settings()
|
self.settings_model = self.manager.get_settings()
|
||||||
|
|
||||||
self.layout().addWidget(to_widget(settings_model, i18n))
|
self.layout().addWidget(to_widget(self.settings_model, i18n))
|
||||||
|
|
||||||
action_bar = QToolBar()
|
action_bar = QToolBar()
|
||||||
action_bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
action_bar.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Minimum)
|
||||||
|
|
||||||
bt_save = QToolButton()
|
bt_close = QPushButton()
|
||||||
bt_save.setText('Save')
|
bt_close.setText(self.i18n['close'].capitalize())
|
||||||
|
bt_close.clicked.connect(lambda: self.close())
|
||||||
|
action_bar.addWidget(bt_close)
|
||||||
|
|
||||||
|
action_bar.addWidget(new_spacer())
|
||||||
|
|
||||||
|
bt_save = QPushButton()
|
||||||
|
bt_save.setText(self.i18n['save'].capitalize())
|
||||||
|
bt_save.clicked.connect(self._save_settings)
|
||||||
action_bar.addWidget(bt_save)
|
action_bar.addWidget(bt_save)
|
||||||
|
|
||||||
self.layout().addWidget(action_bar)
|
self.layout().addWidget(action_bar)
|
||||||
|
|
||||||
|
def _save_settings(self):
|
||||||
|
success, warnings = self.manager.save_settings(self.settings_model)
|
||||||
|
|
||||||
|
if success:
|
||||||
|
self.close()
|
||||||
|
else:
|
||||||
|
msg = StringIO()
|
||||||
|
msg.write("It was not possible to properly the settings\n")
|
||||||
|
|
||||||
|
for w in warnings:
|
||||||
|
msg.write(w + '\n')
|
||||||
|
|
||||||
|
msg.seek(0)
|
||||||
|
|
||||||
|
dialog.show_message(title="Warning", body=msg.read(), type_=MessageType.WARNING)
|
||||||
|
|||||||
Reference in New Issue
Block a user