[api] improvement: allowing several settings views to be returned (SoftwareManager.get_settings)

This commit is contained in:
Vinicius Moreira
2022-04-11 15:09:18 -03:00
parent c91c9542d4
commit ff254db925
11 changed files with 206 additions and 158 deletions

View File

@@ -119,6 +119,29 @@ class SoftwareAction(Enum):
DOWNGRADE = 5 DOWNGRADE = 5
class SettingsController(ABC):
def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
"""
:return: a tuple with a bool informing if the settings were saved and a list of error messages
"""
pass
class SettingsView:
def __init__(self, controller: SettingsController, component: ViewComponent, label: Optional[str] = None,
icon_path: Optional[str] = None):
self.controller = controller
self.component = component
self.label = label
self.icon_path = icon_path
def save(self) -> Tuple[bool, Optional[List[str]]]:
return self.controller.save_settings(self.component)
class SoftwareManager(ABC): class SoftwareManager(ABC):
""" """
@@ -379,15 +402,9 @@ class SoftwareManager(ABC):
""" """
pass pass
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
""" """
:return: a form abstraction with all available settings :return: panel abstractions with optional icon paths associated with
"""
pass
def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]:
"""
:return: a tuple with a bool informing if the settings were saved and a list of error messages
""" """
pass pass

View File

@@ -1,6 +1,6 @@
from abc import ABC from abc import ABC
from enum import Enum from enum import Enum
from typing import List, Set, Optional, Dict from typing import List, Set, Optional, Dict, TypeVar, Type
class MessageType(Enum): class MessageType(Enum):
@@ -27,6 +27,9 @@ class ViewComponent(ABC):
self.observers.append(obs) self.observers.append(obs)
V = TypeVar('V', bound=ViewComponent)
class SpacerComponent(ViewComponent): class SpacerComponent(ViewComponent):
def __init__(self): def __init__(self):
@@ -35,7 +38,7 @@ class SpacerComponent(ViewComponent):
class InputViewComponent(ViewComponent): class InputViewComponent(ViewComponent):
""" """
Represents an component which needs a user interaction to provide its value Represents a component which needs a user interaction to provide its value
""" """
@@ -317,6 +320,15 @@ class PanelComponent(ViewComponent):
if self.component_map: if self.component_map:
return self.component_map.get(id_) return self.component_map.get(id_)
def get_component_by_idx(self, idx: int, type_: Type[V]) -> Optional[V]:
if self.components and idx < len(self.components):
c = self.components[idx]
if isinstance(c, type_):
return c
raise Exception(f"The {ViewComponent.__class__.__name__} at index {idx} is not an "
f"instance of '{type_.__name__}'")
def get_form_component(self, id_: str) -> Optional[FormComponent]: def get_form_component(self, id_: str) -> Optional[FormComponent]:
comp = self.get_component(id_) comp = self.get_component(id_)

View File

@@ -12,17 +12,17 @@ from pathlib import Path
from typing import Set, Type, List, Tuple, Optional, Iterable, Generator from typing import Set, Type, List, Tuple, Optional, Iterable, Generator
from colorama import Fore from colorama import Fore
from packaging.version import parse as parse_version
from packaging.version import LegacyVersion from packaging.version import LegacyVersion
from packaging.version import parse as parse_version
from bauh.api.abstract.context import ApplicationContext from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.controller import SoftwareManager, SearchResult, UpgradeRequirements, UpgradeRequirement, \ from bauh.api.abstract.controller import SoftwareManager, SearchResult, UpgradeRequirements, UpgradeRequirement, \
TransactionResult, SoftwareAction TransactionResult, SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \ from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
SuggestionPriority, CustomSoftwareAction SuggestionPriority, CustomSoftwareAction
from bauh.api.abstract.view import MessageType, ViewComponent, FormComponent, InputOption, SingleSelectComponent, \ from bauh.api.abstract.view import MessageType, FormComponent, InputOption, SingleSelectComponent, \
SelectViewType, TextInputComponent, PanelComponent, FileChooserComponent, ViewObserver SelectViewType, TextInputComponent, PanelComponent, FileChooserComponent, ViewObserver
from bauh.api.paths import DESKTOP_ENTRIES_DIR from bauh.api.paths import DESKTOP_ENTRIES_DIR
from bauh.commons import resource from bauh.commons import resource
@@ -67,7 +67,7 @@ class ManualInstallationFileObserver(ViewObserver):
self.version.set_value(None) self.version.set_value(None)
class AppImageManager(SoftwareManager): class AppImageManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext): def __init__(self, context: ApplicationContext):
super(AppImageManager, self).__init__(context=context) super(AppImageManager, self).__init__(context=context)
@@ -850,7 +850,7 @@ class AppImageManager(SoftwareManager):
print(f'{Fore.RED}[bauh][appimage] An exception has happened when deleting {f}{Fore.RESET}') print(f'{Fore.RED}[bauh][appimage] An exception has happened when deleting {f}{Fore.RESET}')
traceback.print_exc() traceback.print_exc()
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
appimage_config = self.configman.get_config() appimage_config = self.configman.get_config()
max_width = floor(self.context.screen_width * 0.15) max_width = floor(self.context.screen_width * 0.15)
@@ -871,12 +871,12 @@ class AppImageManager(SoftwareManager):
id_='appim_sugs_exp') id_='appim_sugs_exp')
] ]
return PanelComponent([FormComponent(components=comps, id_='form')]) yield SettingsView(self, PanelComponent([FormComponent(components=comps)]))
def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
appimage_config = self.configman.get_config() appimage_config = self.configman.get_config()
form = component.get_form_component('form') form = component.get_component_by_idx(0, FormComponent)
appimage_config['database']['expiration'] = form.get_text_input('appim_db_exp').get_int_value() appimage_config['database']['expiration'] = form.get_text_input('appim_db_exp').get_int_value()
appimage_config['suggestions']['expiration'] = form.get_text_input('appim_sugs_exp').get_int_value() appimage_config['suggestions']['expiration'] = form.get_text_input('appim_sugs_exp').get_int_value()

View File

@@ -18,7 +18,7 @@ from dateutil.parser import parse as parse_date
from bauh import __app_name__ from bauh import __app_name__
from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \
TransactionResult, SoftwareAction TransactionResult, SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import PackageUpdate, PackageHistory, SoftwarePackage, PackageSuggestion, PackageStatus, \ from bauh.api.abstract.model import PackageUpdate, PackageHistory, SoftwarePackage, PackageSuggestion, PackageStatus, \
@@ -194,7 +194,7 @@ class TransactionContext:
self.previous_change_progress = self.change_progress self.previous_change_progress = self.change_progress
class ArchManager(SoftwareManager): class ArchManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext, disk_cache_updater: Optional[ArchDiskCacheUpdater] = None): def __init__(self, context: ApplicationContext, disk_cache_updater: Optional[ArchDiskCacheUpdater] = None):
super(ArchManager, self).__init__(context=context) super(ArchManager, self).__init__(context=context)
@@ -2860,7 +2860,7 @@ class ArchManager(SoftwareManager):
id_=id_, id_=id_,
capitalize_label=capitalize_label) capitalize_label=capitalize_label)
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
arch_config = self.configman.get_config() arch_config = self.configman.get_config()
max_width = floor(self.context.screen_width * 0.25) max_width = floor(self.context.screen_width * 0.25)
@@ -3013,33 +3013,46 @@ class ArchManager(SoftwareManager):
value=arch_config['categories_exp'] if isinstance(arch_config['categories_exp'], int) else ''), value=arch_config['categories_exp'] if isinstance(arch_config['categories_exp'], int) else ''),
] ]
return PanelComponent([FormComponent(fields, spaces=False, id_='root')]) yield SettingsView(self, PanelComponent([FormComponent(fields, spaces=False)]))
def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
arch_config = self.configman.get_config() arch_config = self.configman.get_config()
form = component.get_form_component('root') form = component.get_component_by_idx(0, FormComponent)
arch_config['repositories'] = form.get_single_select_component('repos').get_selected() arch_config['repositories'] = form.get_single_select_component('repos').get_selected()
arch_config['optimize'] = form.get_single_select_component('opts').get_selected() arch_config['optimize'] = form.get_single_select_component('opts').get_selected()
arch_config['aur_rebuild_detector'] = form.get_single_select_component('rebuild_detector').get_selected() arch_config['aur_rebuild_detector'] = form.get_single_select_component('rebuild_detector').get_selected()
arch_config['aur_rebuild_detector_no_bin'] = form.get_single_select_component('rebuild_detector_no_bin').get_selected()
rebuild_no_bin = form.get_single_select_component('rebuild_detector_no_bin').get_selected()
arch_config['aur_rebuild_detector_no_bin'] = rebuild_no_bin
arch_config['sync_databases'] = form.get_single_select_component('sync_dbs').get_selected() arch_config['sync_databases'] = form.get_single_select_component('sync_dbs').get_selected()
arch_config['sync_databases_startup'] = form.get_single_select_component('sync_dbs_start').get_selected() arch_config['sync_databases_startup'] = form.get_single_select_component('sync_dbs_start').get_selected()
arch_config['clean_cached'] = form.get_single_select_component('clean_cached').get_selected() arch_config['clean_cached'] = form.get_single_select_component('clean_cached').get_selected()
arch_config['refresh_mirrors_startup'] = form.get_single_select_component('ref_mirs').get_selected() arch_config['refresh_mirrors_startup'] = form.get_single_select_component('ref_mirs').get_selected()
arch_config['mirrors_sort_limit'] = form.get_component('mirrors_sort_limit').get_int_value() arch_config['mirrors_sort_limit'] = form.get_text_input('mirrors_sort_limit').get_int_value()
arch_config['repositories_mthread_download'] = form.get_component('mthread_download').get_selected() arch_config['repositories_mthread_download'] = form.get_single_select_component('mthread_download').get_selected()
arch_config['automatch_providers'] = form.get_single_select_component('autoprovs').get_selected() arch_config['automatch_providers'] = form.get_single_select_component('autoprovs').get_selected()
arch_config['prefer_repository_provider'] = form.get_single_select_component('prefer_repo_provider').get_selected()
prefer_repo_provider = form.get_single_select_component('prefer_repo_provider').get_selected()
arch_config['prefer_repository_provider'] = prefer_repo_provider
arch_config['edit_aur_pkgbuild'] = form.get_single_select_component('edit_aur_pkgbuild').get_selected() arch_config['edit_aur_pkgbuild'] = form.get_single_select_component('edit_aur_pkgbuild').get_selected()
arch_config['aur_remove_build_dir'] = form.get_single_select_component('aur_remove_build_dir').get_selected() arch_config['aur_remove_build_dir'] = form.get_single_select_component('aur_remove_build_dir').get_selected()
arch_config['aur_build_dir'] = form.get_component('aur_build_dir').file_path arch_config['aur_build_dir'] = form.get_component('aur_build_dir').file_path
arch_config['aur_build_only_chosen'] = form.get_single_select_component('aur_build_only_chosen').get_selected() arch_config['aur_build_only_chosen'] = form.get_single_select_component('aur_build_only_chosen').get_selected()
arch_config['aur_idx_exp'] = form.get_component('aur_idx_exp').get_int_value() arch_config['aur_idx_exp'] = form.get_text_input('aur_idx_exp').get_int_value()
arch_config['check_dependency_breakage'] = form.get_single_select_component('check_dependency_breakage').get_selected()
arch_config['suggest_optdep_uninstall'] = form.get_single_select_component('suggest_optdep_uninstall').get_selected() check_dep_break = form.get_single_select_component('check_dependency_breakage').get_selected()
arch_config['suggest_unneeded_uninstall'] = form.get_single_select_component('suggest_unneeded_uninstall').get_selected() arch_config['check_dependency_breakage'] = check_dep_break
arch_config['categories_exp'] = form.get_component('arch_cats_exp').get_int_value()
sug_opt_dep_uni = form.get_single_select_component('suggest_optdep_uninstall').get_selected()
arch_config['suggest_optdep_uninstall'] = sug_opt_dep_uni
sug_unneeded_uni = form.get_single_select_component('suggest_unneeded_uninstall').get_selected()
arch_config['suggest_unneeded_uninstall'] = sug_unneeded_uni
arch_config['categories_exp'] = form.get_text_input('arch_cats_exp').get_int_value()
if not arch_config['aur_build_dir']: if not arch_config['aur_build_dir']:
arch_config['aur_build_dir'] = None arch_config['aur_build_dir'] = None

View File

@@ -10,12 +10,12 @@ from typing import List, Optional, Tuple, Set, Type, Dict, Iterable, Generator
from bauh.api.abstract.context import ApplicationContext from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.controller import SoftwareManager, SoftwareAction, TransactionResult, UpgradeRequirements, \ from bauh.api.abstract.controller import SoftwareManager, SoftwareAction, TransactionResult, UpgradeRequirements, \
SearchResult, UpgradeRequirement SearchResult, UpgradeRequirement, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import TaskManager, ProcessWatcher from bauh.api.abstract.handler import TaskManager, ProcessWatcher
from bauh.api.abstract.model import SoftwarePackage, PackageSuggestion, PackageUpdate, PackageHistory, \ from bauh.api.abstract.model import SoftwarePackage, PackageSuggestion, PackageUpdate, PackageHistory, \
CustomSoftwareAction CustomSoftwareAction
from bauh.api.abstract.view import ViewComponent, TextInputComponent, PanelComponent, FormComponent, MessageType, \ from bauh.api.abstract.view import TextInputComponent, PanelComponent, FormComponent, MessageType, \
SingleSelectComponent, InputOption, SelectViewType SingleSelectComponent, InputOption, SelectViewType
from bauh.api.paths import CONFIG_DIR from bauh.api.paths import CONFIG_DIR
from bauh.commons.html import bold from bauh.commons.html import bold
@@ -33,7 +33,7 @@ from bauh.gems.debian.suggestions import DebianSuggestionsDownloader
from bauh.gems.debian.tasks import UpdateApplicationIndex, MapApplications, SynchronizePackages from bauh.gems.debian.tasks import UpdateApplicationIndex, MapApplications, SynchronizePackages
class DebianPackageManager(SoftwareManager): class DebianPackageManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext): def __init__(self, context: ApplicationContext):
super(DebianPackageManager, self).__init__(context) super(DebianPackageManager, self).__init__(context)
@@ -568,7 +568,7 @@ class DebianPackageManager(SoftwareManager):
final_cmd = pkg.app.exe_path.replace('%U', '') final_cmd = pkg.app.exe_path.replace('%U', '')
Popen(final_cmd, shell=True) Popen(final_cmd, shell=True)
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
deb_config = self.configman.get_config() deb_config = self.configman.get_config()
comps_width = int(self.context.screen_width * 0.105) comps_width = int(self.context.screen_width * 0.105)
@@ -632,14 +632,13 @@ class DebianPackageManager(SoftwareManager):
value=str(suggestions_exp), only_int=True, value=str(suggestions_exp), only_int=True,
max_width=comps_width) max_width=comps_width)
return PanelComponent([FormComponent([input_sources, ti_sync_pkgs, ti_index_apps_exp, ti_suggestions_exp])]) panel = PanelComponent([FormComponent([input_sources, ti_sync_pkgs, ti_index_apps_exp, ti_suggestions_exp])])
yield SettingsView(self, panel)
def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
deb_config = self.configman.get_config() deb_config = self.configman.get_config()
container = component.components[0] container = component.get_component_by_idx(0, FormComponent)
if isinstance(container, FormComponent):
deb_config['pkg_sources.app'] = container.get_single_select_component('pkg_sources.app').get_selected() deb_config['pkg_sources.app'] = container.get_single_select_component('pkg_sources.app').get_selected()
deb_config['index_apps.exp'] = container.get_text_input('index_apps.exp').get_int_value() deb_config['index_apps.exp'] = container.get_text_input('index_apps.exp').get_int_value()
deb_config['sync_pkgs.time'] = container.get_text_input('sync_pkgs.time').get_int_value() deb_config['sync_pkgs.time'] = container.get_text_input('sync_pkgs.time').get_int_value()

View File

@@ -11,13 +11,13 @@ from packaging.version import Version
from bauh.api import user from bauh.api import user
from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SearchResult, SoftwareManager, ApplicationContext, UpgradeRequirements, \
UpgradeRequirement, TransactionResult, SoftwareAction UpgradeRequirement, TransactionResult, SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \ from bauh.api.abstract.model import PackageHistory, PackageUpdate, SoftwarePackage, PackageSuggestion, \
SuggestionPriority, PackageStatus, CustomSoftwareAction SuggestionPriority, PackageStatus, CustomSoftwareAction
from bauh.api.abstract.view import MessageType, FormComponent, SingleSelectComponent, InputOption, SelectViewType, \ from bauh.api.abstract.view import MessageType, FormComponent, SingleSelectComponent, InputOption, SelectViewType, \
ViewComponent, PanelComponent PanelComponent
from bauh.commons.boot import CreateConfigFile from bauh.commons.boot import CreateConfigFile
from bauh.commons.html import strip_html, bold from bauh.commons.html import strip_html, bold
from bauh.commons.system import ProcessHandler from bauh.commons.system import ProcessHandler
@@ -33,7 +33,7 @@ DATE_FORMAT = '%Y-%m-%dT%H:%M:%S.000Z'
RE_INSTALL_REFS = re.compile(r'\d+\)\s+(.+)') RE_INSTALL_REFS = re.compile(r'\d+\)\s+(.+)')
class FlatpakManager(SoftwareManager): class FlatpakManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext): def __init__(self, context: ApplicationContext):
super(FlatpakManager, self).__init__(context=context) super(FlatpakManager, self).__init__(context=context)
@@ -603,7 +603,7 @@ class FlatpakManager(SoftwareManager):
else: else:
traceback.print_exc() traceback.print_exc()
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
if not self.context.root_user: if not self.context.root_user:
fields = [] fields = []
@@ -623,13 +623,15 @@ class FlatpakManager(SoftwareManager):
default_option=[o for o in install_opts if o.value == flatpak_config['installation_level']][0], default_option=[o for o in install_opts if o.value == flatpak_config['installation_level']][0],
max_per_line=len(install_opts), max_per_line=len(install_opts),
max_width=floor(self.context.screen_width * 0.22), max_width=floor(self.context.screen_width * 0.22),
type_=SelectViewType.RADIO)) type_=SelectViewType.RADIO,
id_='install'))
return PanelComponent([FormComponent(fields, self.i18n['installation'].capitalize())]) yield SettingsView(self, PanelComponent([FormComponent(fields, self.i18n['installation'].capitalize())]))
def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
flatpak_config = self.configman.get_config() flatpak_config = self.configman.get_config()
flatpak_config['installation_level'] = component.components[0].components[0].get_selected() form = component.get_component_by_idx(0, FormComponent)
flatpak_config['installation_level'] = form.get_single_select_component('install').get_selected()
try: try:
self.configman.save_config(flatpak_config) self.configman.save_config(flatpak_config)

View File

@@ -5,7 +5,7 @@ from threading import Thread
from typing import List, Set, Type, Optional, Tuple, Generator from typing import List, Set, Type, Optional, Tuple, Generator
from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \
TransactionResult, SoftwareAction TransactionResult, SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \ from bauh.api.abstract.model import SoftwarePackage, PackageHistory, PackageUpdate, PackageSuggestion, \
@@ -27,7 +27,7 @@ from bauh.gems.snap.snapd import SnapdClient
RE_AVAILABLE_CHANNELS = re.compile(re.compile(r'(\w+)\s+(snap install.+)')) RE_AVAILABLE_CHANNELS = re.compile(re.compile(r'(\w+)\s+(snap install.+)'))
class SnapManager(SoftwareManager): class SnapManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext): def __init__(self, context: ApplicationContext):
super(SnapManager, self).__init__(context=context) super(SnapManager, self).__init__(context=context)
@@ -427,7 +427,7 @@ class SnapManager(SoftwareManager):
if pkg.screenshots: if pkg.screenshots:
yield from pkg.screenshots yield from pkg.screenshots
def get_settings(self) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
snap_config = self.configman.get_config() snap_config = self.configman.get_config()
max_width = 200 max_width = 200
@@ -446,14 +446,15 @@ class SnapManager(SoftwareManager):
label=self.i18n['snap.config.categories_exp'], label=self.i18n['snap.config.categories_exp'],
tooltip=self.i18n['snap.config.categories_exp.tip']) tooltip=self.i18n['snap.config.categories_exp.tip'])
return PanelComponent([FormComponent([install_channel, categories_exp], self.i18n['installation'].capitalize())]) panel = PanelComponent([FormComponent([install_channel, categories_exp], self.i18n['installation'].capitalize())])
yield SettingsView(self, panel)
def save_settings(self, component: ViewComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
snap_config = self.configman.get_config() snap_config = self.configman.get_config()
panel = component.components[0] form = component.get_component_by_idx(0, FormComponent)
snap_config['install_channel'] = panel.get_component('snap_install_channel').get_selected() snap_config['install_channel'] = form.get_single_select_component('snap_install_channel').get_selected()
snap_config['categories_exp'] = panel.get_component('snap_cat_exp').get_int_value() snap_config['categories_exp'] = form.get_text_input('snap_cat_exp').get_int_value()
try: try:
self.configman.save_config(snap_config) self.configman.save_config(snap_config)

View File

@@ -18,7 +18,7 @@ from requests import Response
from bauh.api.abstract.context import ApplicationContext from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.controller import SoftwareManager, SearchResult, UpgradeRequirements, TransactionResult, \ from bauh.api.abstract.controller import SoftwareManager, SearchResult, UpgradeRequirements, TransactionResult, \
SoftwareAction SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import SoftwarePackage, CustomSoftwareAction, PackageSuggestion, PackageUpdate, \ from bauh.api.abstract.model import SoftwarePackage, CustomSoftwareAction, PackageSuggestion, PackageUpdate, \
@@ -62,7 +62,7 @@ RE_SYMBOLS_SPLIT = re.compile(r'[\-|_\s:.]')
DEFAULT_LANGUAGE_HEADER = 'en-US, en' DEFAULT_LANGUAGE_HEADER = 'en-US, en'
class WebApplicationManager(SoftwareManager): class WebApplicationManager(SoftwareManager, SettingsController):
def __init__(self, context: ApplicationContext, suggestions_loader: Optional[SuggestionsLoader] = None): def __init__(self, context: ApplicationContext, suggestions_loader: Optional[SuggestionsLoader] = None):
super(WebApplicationManager, self).__init__(context=context) super(WebApplicationManager, self).__init__(context=context)
@@ -1105,7 +1105,7 @@ class WebApplicationManager(SoftwareManager):
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) -> Optional[ViewComponent]: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
web_config = self.configman.get_config() web_config = self.configman.get_config()
max_width = floor(self.context.screen_width * 0.15) max_width = floor(self.context.screen_width * 0.15)
@@ -1149,26 +1149,27 @@ class WebApplicationManager(SoftwareManager):
form_env = FormComponent(label=self.i18n['web.settings.nativefier.env'].capitalize(), form_env = FormComponent(label=self.i18n['web.settings.nativefier.env'].capitalize(),
components=[input_electron, select_nativefier, env_settings_exp, sugs_exp]) components=[input_electron, select_nativefier, env_settings_exp, sugs_exp])
return PanelComponent([form_env]) yield SettingsView(self, PanelComponent([form_env]))
def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]: def save_settings(self, component: PanelComponent) -> Tuple[bool, Optional[List[str]]]:
web_config = self.configman.get_config() web_config = self.configman.get_config()
form_env = component.components[0] form_env = component.get_component_by_idx(0, FormComponent)
web_config['environment']['electron']['version'] = str(form_env.get_component('electron_branch').get_value()).strip() electron_version = str(form_env.get_text_input('electron_branch').get_value()).strip()
web_config['environment']['electron']['version'] = electron_version
if len(web_config['environment']['electron']['version']) == 0: if len(web_config['environment']['electron']['version']) == 0:
web_config['environment']['electron']['version'] = None web_config['environment']['electron']['version'] = None
system_nativefier = form_env.get_component('nativefier').get_selected() system_nativefier = form_env.get_single_select_component('nativefier').get_selected()
if system_nativefier and not nativefier.is_available(): if system_nativefier and not nativefier.is_available():
return False, [self.i18n['web.settings.env.nativefier.system.not_installed'].format('Nativefier')] return False, [self.i18n['web.settings.env.nativefier.system.not_installed'].format('Nativefier')]
web_config['environment']['system'] = system_nativefier web_config['environment']['system'] = system_nativefier
web_config['environment']['cache_exp'] = form_env.get_component('web_cache_exp').get_int_value() web_config['environment']['cache_exp'] = form_env.get_text_input('web_cache_exp').get_int_value()
web_config['suggestions']['cache_exp'] = form_env.get_component('web_sugs_exp').get_int_value() web_config['suggestions']['cache_exp'] = form_env.get_text_input('web_sugs_exp').get_int_value()
try: try:
self.configman.save_config(web_config) self.configman.save_config(web_config)

View File

@@ -7,12 +7,12 @@ from threading import Thread
from typing import List, Set, Type, Tuple, Dict, Optional, Generator, Callable from typing import List, Set, Type, Tuple, Dict, Optional, Generator, Callable
from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \ from bauh.api.abstract.controller import SoftwareManager, SearchResult, ApplicationContext, UpgradeRequirements, \
UpgradeRequirement, TransactionResult, SoftwareAction UpgradeRequirement, TransactionResult, SoftwareAction, SettingsView, SettingsController
from bauh.api.abstract.disk import DiskCacheLoader from bauh.api.abstract.disk import DiskCacheLoader
from bauh.api.abstract.handler import ProcessWatcher, TaskManager from bauh.api.abstract.handler import ProcessWatcher, TaskManager
from bauh.api.abstract.model import SoftwarePackage, PackageUpdate, PackageHistory, PackageSuggestion, \ from bauh.api.abstract.model import SoftwarePackage, PackageUpdate, PackageHistory, PackageSuggestion, \
CustomSoftwareAction CustomSoftwareAction
from bauh.api.abstract.view import ViewComponent, TabGroupComponent, MessageType from bauh.api.abstract.view import ViewComponent, TabGroupComponent, MessageType, PanelComponent
from bauh.api.exception import NoInternetException from bauh.api.exception import NoInternetException
from bauh.commons.boot import CreateConfigFile from bauh.commons.boot import CreateConfigFile
from bauh.commons.html import bold from bauh.commons.html import bold
@@ -36,7 +36,7 @@ class GenericUpgradeRequirements(UpgradeRequirements):
self.sub_requirements = sub_requirements self.sub_requirements = sub_requirements
class GenericSoftwareManager(SoftwareManager): class GenericSoftwareManager(SoftwareManager, SettingsController):
def __init__(self, managers: List[SoftwareManager], context: ApplicationContext, config: dict): def __init__(self, managers: List[SoftwareManager], context: ApplicationContext, config: dict):
super(GenericSoftwareManager, self).__init__(context=context) super(GenericSoftwareManager, self).__init__(context=context)
@@ -532,7 +532,7 @@ class GenericSoftwareManager(SoftwareManager):
def get_working_managers(self): def get_working_managers(self):
return [m for m in self.managers if self._can_work(m)] return [m for m in self.managers if self._can_work(m)]
def get_settings(self) -> ViewComponent: def get_settings(self) -> Optional[Generator[SettingsView, None, None]]:
if self.settings_manager is None: if self.settings_manager is None:
self.settings_manager = GenericSettingsManager(managers=self.managers, self.settings_manager = GenericSettingsManager(managers=self.managers,
working_managers=self.working_managers, working_managers=self.working_managers,
@@ -542,9 +542,9 @@ class GenericSoftwareManager(SoftwareManager):
self.settings_manager.managers = self.managers self.settings_manager.managers = self.managers
self.settings_manager.working_managers = self.working_managers self.settings_manager.working_managers = self.working_managers
return self.settings_manager.get_settings() yield SettingsView(self, self.settings_manager.get_settings())
def save_settings(self, component: TabGroupComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: TabGroupComponent) -> Tuple[bool, Optional[List[str]]]:
return self.settings_manager.save_settings(component) return self.settings_manager.save_settings(component)
def _map_pkgs_by_manager(self, pkgs: List[SoftwarePackage], pkg_filters: list = None) -> Dict[SoftwareManager, List[SoftwarePackage]]: def _map_pkgs_by_manager(self, pkgs: List[SoftwarePackage], pkg_filters: list = None) -> Dict[SoftwareManager, List[SoftwarePackage]]:

View File

@@ -1,18 +1,17 @@
import logging import os
import os import os
import time import time
import traceback import traceback
from math import floor from math import floor
from threading import Thread from threading import Thread
from typing import List, Tuple, Optional, Dict from typing import List, Tuple, Optional, Dict, Type, Iterable
from PyQt5.QtWidgets import QApplication, QStyleFactory from PyQt5.QtWidgets import QApplication, QStyleFactory
from bauh import ROOT_DIR, __app_name__ from bauh import ROOT_DIR, __app_name__
from bauh.api.abstract.context import ApplicationContext from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.controller import SoftwareManager from bauh.api.abstract.controller import SoftwareManager, SettingsController, SettingsView
from bauh.api.abstract.download import FileDownloader from bauh.api.abstract.view import TabComponent, InputOption, TextComponent, MultipleSelectComponent, \
from bauh.api.abstract.view import ViewComponent, TabComponent, InputOption, TextComponent, MultipleSelectComponent, \
PanelComponent, FormComponent, TabGroupComponent, SingleSelectComponent, SelectViewType, TextInputComponent, \ PanelComponent, FormComponent, TabGroupComponent, SingleSelectComponent, SelectViewType, TextInputComponent, \
FileChooserComponent, RangeInputComponent FileChooserComponent, RangeInputComponent
from bauh.commons.view_utils import new_select from bauh.commons.view_utils import new_select
@@ -20,10 +19,9 @@ from bauh.view.core import timeshift
from bauh.view.core.config import CoreConfigManager, BACKUP_REMOVE_METHODS, BACKUP_DEFAULT_REMOVE_METHOD from bauh.view.core.config import CoreConfigManager, BACKUP_REMOVE_METHODS, BACKUP_DEFAULT_REMOVE_METHOD
from bauh.view.core.downloader import AdaptableFileDownloader from bauh.view.core.downloader import AdaptableFileDownloader
from bauh.view.util import translation from bauh.view.util import translation
from bauh.view.util.translation import I18n
class GenericSettingsManager: class GenericSettingsManager(SettingsController):
def __init__(self, context: ApplicationContext, managers: List[SoftwareManager], def __init__(self, context: ApplicationContext, managers: List[SoftwareManager],
working_managers: List[SoftwareManager], configman: CoreConfigManager): working_managers: List[SoftwareManager], configman: CoreConfigManager):
@@ -34,27 +32,35 @@ class GenericSettingsManager:
self.logger = context.logger self.logger = context.logger
self.file_downloader = self.context.file_downloader self.file_downloader = self.context.file_downloader
self.configman = configman self.configman = configman
self._settings_views: Optional[Dict[Type, List[SettingsView]]] = None
def get_settings(self) -> ViewComponent: def get_settings(self) -> TabGroupComponent:
tabs = list() tabs = list()
gem_opts, def_gem_opts, gem_tabs = [], set(), [] gem_opts, def_gem_opts, gem_tabs = [], set(), []
self._settings_views = dict()
for man in self.managers: for man in self.managers:
can_work, reason_not_work = man.can_work() can_work, reason_not_work = man.can_work()
modname = man.__module__.split('.')[-2] modname = man.__module__.split('.')[-2]
icon_path = "{r}/gems/{n}/resources/img/{n}.svg".format(r=ROOT_DIR, n=modname)
man_comp = man.get_settings() if can_work else None man_settings = man.get_settings() if can_work else None
if man_comp: if man_settings:
tab_name = self.i18n.get('gem.{}.label'.format(modname), modname.capitalize()) for view in man_settings:
gem_tabs.append(TabComponent(label=tab_name, content=man_comp, icon_path=icon_path, id_=modname)) icon_path = view.icon_path if view.icon_path else f"{ROOT_DIR}/gems/{modname}/resources/img/{modname}.svg"
tab_name = view.label if view.label else self.i18n.get(f'gem.{modname}.label', modname.capitalize())
gem_tabs.append(TabComponent(label=tab_name, content=view.component, icon_path=icon_path))
views = self._settings_views.get(man.__class__, list())
self._settings_views[man.__class__] = views
views.append(view)
help_tip = reason_not_work if not can_work and reason_not_work else self.i18n.get(f'gem.{modname}.info') help_tip = reason_not_work if not can_work and reason_not_work else self.i18n.get(f'gem.{modname}.info')
opt = InputOption(label=self.i18n.get('gem.{}.label'.format(modname), modname.capitalize()), opt = InputOption(label=self.i18n.get(f'gem.{modname}.label', modname.capitalize()),
tooltip=help_tip, tooltip=help_tip,
value=modname, value=modname,
icon_path='{r}/gems/{n}/resources/img/{n}.svg'.format(r=ROOT_DIR, n=modname), icon_path=f'{ROOT_DIR}/gems/{modname}/resources/img/{modname}.svg',
read_only=not can_work, read_only=not can_work,
extra_properties={'warning': 'true'} if not can_work else None) extra_properties={'warning': 'true'} if not can_work else None)
gem_opts.append(opt) gem_opts.append(opt)
@@ -351,63 +357,64 @@ class GenericSettingsManager:
core_config = self.configman.get_config() core_config = self.configman.get_config()
# general # general
general_form = general.components[0] gen_form = general.get_component_by_idx(0, FormComponent)
locale = general_form.get_component('locale').get_selected() locale = gen_form.get_single_select_component('locale').get_selected()
if locale != self.i18n.current_key: if locale != self.i18n.current_key:
core_config['locale'] = locale core_config['locale'] = locale
core_config['system']['notifications'] = general_form.get_component('sys_notify').get_selected() core_config['system']['notifications'] = gen_form.get_single_select_component('sys_notify').get_selected()
core_config['suggestions']['enabled'] = general_form.get_component('sugs_enabled').get_selected() core_config['suggestions']['enabled'] = gen_form.get_single_select_component('sugs_enabled').get_selected()
core_config['store_root_password'] = general_form.get_component('store_pwd').get_selected() core_config['store_root_password'] = gen_form.get_single_select_component('store_pwd').get_selected()
sugs_by_type = general_form.get_component('sugs_by_type').get_int_value() sugs_by_type = gen_form.get_text_input('sugs_by_type').get_int_value()
core_config['suggestions']['by_type'] = sugs_by_type core_config['suggestions']['by_type'] = sugs_by_type
core_config['updates']['ask_for_reboot'] = general_form.get_component('ask_for_reboot').get_selected() core_config['updates']['ask_for_reboot'] = gen_form.get_single_select_component('ask_for_reboot').get_selected()
core_config['boot']['load_apps'] = general_form.get_component('boot.load_apps').get_selected() core_config['boot']['load_apps'] = gen_form.get_single_select_component('boot.load_apps').get_selected()
# advanced # advanced
adv_form = advanced.components[0] adv_form = advanced.get_component_by_idx(0, FormComponent)
download_mthreaded = adv_form.get_component('down_mthread').get_selected() download_mthreaded = adv_form.get_single_select_component('down_mthread').get_selected()
core_config['download']['multithreaded'] = download_mthreaded core_config['download']['multithreaded'] = download_mthreaded
mthread_client = adv_form.get_component('mthread_client').get_selected() mthread_client = adv_form.get_single_select_component('mthread_client').get_selected()
core_config['download']['multithreaded_client'] = mthread_client core_config['download']['multithreaded_client'] = mthread_client
if isinstance(self.file_downloader, AdaptableFileDownloader): if isinstance(self.file_downloader, AdaptableFileDownloader):
self.file_downloader.multithread_client = mthread_client self.file_downloader.multithread_client = mthread_client
self.file_downloader.multithread_enabled = download_mthreaded self.file_downloader.multithread_enabled = download_mthreaded
single_dep_check = adv_form.get_component('dep_check').get_selected() single_dep_check = adv_form.get_single_select_component('dep_check').get_selected()
core_config['system']['single_dependency_checking'] = single_dep_check core_config['system']['single_dependency_checking'] = single_dep_check
data_exp = adv_form.get_component('data_exp').get_int_value() data_exp = adv_form.get_text_input('data_exp').get_int_value()
core_config['memory_cache']['data_expiration'] = data_exp core_config['memory_cache']['data_expiration'] = data_exp
icon_exp = adv_form.get_component('icon_exp').get_int_value() icon_exp = adv_form.get_text_input('icon_exp').get_int_value()
core_config['memory_cache']['icon_expiration'] = icon_exp core_config['memory_cache']['icon_expiration'] = icon_exp
core_config['disk']['trim']['after_upgrade'] = adv_form.get_component('trim_after_upgrade').get_selected() trim_after_upgrade = adv_form.get_single_select_component('trim_after_upgrade').get_selected()
core_config['disk']['trim']['after_upgrade'] = trim_after_upgrade
# backup # backup
if backup: if backup:
bkp_form = backup.components[0] bkp_form = backup.get_component_by_idx(0, FormComponent)
core_config['backup']['enabled'] = bkp_form.get_component('enabled').get_selected() core_config['backup']['enabled'] = bkp_form.get_single_select_component('enabled').get_selected()
core_config['backup']['mode'] = bkp_form.get_component('mode').get_selected() core_config['backup']['mode'] = bkp_form.get_single_select_component('mode').get_selected()
core_config['backup']['type'] = bkp_form.get_component('type').get_selected() core_config['backup']['type'] = bkp_form.get_single_select_component('type').get_selected()
core_config['backup']['remove_method'] = bkp_form.get_component('remove_method').get_selected() core_config['backup']['remove_method'] = bkp_form.get_single_select_component('remove_method').get_selected()
core_config['backup']['install'] = bkp_form.get_component('install').get_selected() core_config['backup']['install'] = bkp_form.get_single_select_component('install').get_selected()
core_config['backup']['uninstall'] = bkp_form.get_component('uninstall').get_selected() core_config['backup']['uninstall'] = bkp_form.get_single_select_component('uninstall').get_selected()
core_config['backup']['upgrade'] = bkp_form.get_component('upgrade').get_selected() core_config['backup']['upgrade'] = bkp_form.get_single_select_component('upgrade').get_selected()
core_config['backup']['downgrade'] = bkp_form.get_component('downgrade').get_selected() core_config['backup']['downgrade'] = bkp_form.get_single_select_component('downgrade').get_selected()
# tray # tray
tray_form = tray.components[0] tray_form = tray.get_component_by_idx(0, FormComponent)
core_config['updates']['check_interval'] = tray_form.get_component('updates_interval').get_int_value() core_config['updates']['check_interval'] = tray_form.get_text_input('updates_interval').get_int_value()
def_icon_path = tray_form.get_component('def_icon').file_path def_icon_path = tray_form.get_component('def_icon').file_path
core_config['ui']['tray']['default_icon'] = def_icon_path if def_icon_path else None core_config['ui']['tray']['default_icon'] = def_icon_path if def_icon_path else None
@@ -416,30 +423,30 @@ class GenericSettingsManager:
core_config['ui']['tray']['updates_icon'] = up_icon_path if up_icon_path else None core_config['ui']['tray']['updates_icon'] = up_icon_path if up_icon_path else None
# ui # ui
ui_form = ui.components[0] ui_form = ui.get_component_by_idx(0, FormComponent)
core_config['download']['icons'] = ui_form.get_component('down_icons').get_selected() core_config['download']['icons'] = ui_form.get_single_select_component('down_icons').get_selected()
core_config['ui']['hdpi'] = ui_form.get_component('hdpi').get_selected() core_config['ui']['hdpi'] = ui_form.get_single_select_component('hdpi').get_selected()
previous_autoscale = core_config['ui']['auto_scale'] previous_autoscale = core_config['ui']['auto_scale']
core_config['ui']['auto_scale'] = ui_form.get_component('auto_scale').get_selected() core_config['ui']['auto_scale'] = ui_form.get_single_select_component('auto_scale').get_selected()
if previous_autoscale and not core_config['ui']['auto_scale']: if previous_autoscale and not core_config['ui']['auto_scale']:
self.logger.info("Deleting environment variable QT_AUTO_SCREEN_SCALE_FACTOR") self.logger.info("Deleting environment variable QT_AUTO_SCREEN_SCALE_FACTOR")
del os.environ['QT_AUTO_SCREEN_SCALE_FACTOR'] del os.environ['QT_AUTO_SCREEN_SCALE_FACTOR']
core_config['ui']['scale_factor'] = ui_form.get_component('scalef').value / 100 core_config['ui']['scale_factor'] = ui_form.get_component('scalef').value / 100
core_config['ui']['table']['max_displayed'] = ui_form.get_component('table_max').get_int_value() core_config['ui']['table']['max_displayed'] = ui_form.get_text_input('table_max').get_int_value()
style = ui_form.get_component('style').get_selected() style = ui_form.get_single_select_component('style').get_selected()
cur_style = core_config['ui']['qt_style'] if core_config['ui']['qt_style'] else QApplication.instance().property('qt_style') cur_style = core_config['ui']['qt_style'] if core_config['ui']['qt_style'] else QApplication.instance().property('qt_style')
if style != cur_style: if style != cur_style:
core_config['ui']['qt_style'] = style core_config['ui']['qt_style'] = style
QApplication.instance().setProperty('qt_style', style) QApplication.instance().setProperty('qt_style', style)
core_config['ui']['system_theme'] = ui_form.get_component('system_theme').get_selected() core_config['ui']['system_theme'] = ui_form.get_single_select_component('system_theme').get_selected()
# gems # gems
checked_gems = gems_panel.components[1].get_component('gems').get_selected_values() checked_gems = gems_panel.components[1].get_component('gems').get_selected_values()
@@ -457,11 +464,12 @@ class GenericSettingsManager:
except: except:
return False, [traceback.format_exc()] return False, [traceback.format_exc()]
def _save_manager_settings(self, man: SoftwareManager, panel: ViewComponent, success_map: Dict[str, bool], warnings: List[str]): def _save_views(self, views: Iterable[SettingsView], success_list: List[bool], warnings: List[str]):
success = False success = False
for view in views:
try: try:
res = man.save_settings(panel) res = view.save()
if res: if res:
success, errors = res[0], res[1] success, errors = res[0], res[1]
@@ -469,12 +477,13 @@ class GenericSettingsManager:
if errors: if errors:
warnings.extend(errors) warnings.extend(errors)
except: except:
self.logger.error("An exception happened while {} was trying to save its settings".format(man.__class__.__name__)) self.logger.error(f"An exception happened while {view.controller.__class__.__name__}"
f" was trying to save settings")
traceback.print_exc() traceback.print_exc()
finally: finally:
success_map[man.__class__.__name__] = success success_list.append(success)
def _save_core_settings(self, root_component: TabGroupComponent, success_map: Dict[str, bool], warnings: List[str]): def _save_core_settings(self, root_component: TabGroupComponent, success_list: List[bool], warnings: List[str]):
success = False success = False
try: try:
@@ -492,35 +501,29 @@ class GenericSettingsManager:
self.logger.error("An exception happened while saving the core settings") self.logger.error("An exception happened while saving the core settings")
traceback.print_exc() traceback.print_exc()
finally: finally:
success_map[self.__class__.__name__] = success success_list.append(success)
def save_settings(self, component: TabGroupComponent) -> Tuple[bool, List[str]]: def save_settings(self, component: TabGroupComponent) -> Tuple[bool, Optional[List[str]]]:
ti = time.time() ti = time.time()
save_threads, warnings, success_map = [], [], {} save_threads, warnings, success_list = [], [], []
save_core = Thread(target=self._save_core_settings, args=(component, success_map, warnings), daemon=True) save_core = Thread(target=self._save_core_settings, args=(component, success_list, warnings))
save_core.start() save_core.start()
save_threads.append(save_core) save_threads.append(save_core)
for man in self.managers: if self._settings_views:
if man:
modname = man.__module__.split('.')[-2]
tab = component.get_tab(modname)
if not tab: for views in self._settings_views.values():
self.logger.warning("Tab for {} was not found".format(man.__class__.__name__)) save_view = Thread(target=self._save_views, args=(views, success_list, warnings))
else: save_view.start()
save_man = Thread(target=self._save_manager_settings(man, tab.content, success_map, warnings), daemon=True) save_threads.append(save_view)
save_man.start()
save_threads.append(save_man)
for t in save_threads: for t in save_threads:
t.join() t.join()
success = all(success_map.values()) success = all(success_list)
tf = time.time() tf = time.time()
self.logger.info("Saving all settings took {0:.8f} seconds".format(tf - ti)) self.logger.info(f"Saving all settings took {tf - ti:.8f} seconds")
return success, warnings return success, warnings
def _gen_backup_settings(self, core_config: dict) -> TabComponent: def _gen_backup_settings(self, core_config: dict) -> TabComponent:

View File

@@ -2,7 +2,7 @@ import gc
from io import StringIO from io import StringIO
from typing import Optional from typing import Optional
from PyQt5.QtCore import QSize, Qt, QCoreApplication, QThread, pyqtSignal from PyQt5.QtCore import Qt, QCoreApplication, QThread, pyqtSignal
from PyQt5.QtGui import QCursor from PyQt5.QtGui import QCursor
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QPushButton, QHBoxLayout, QApplication from PyQt5.QtWidgets import QWidget, QVBoxLayout, QSizePolicy, QPushButton, QHBoxLayout, QApplication
@@ -45,7 +45,7 @@ class SettingsWindow(QWidget):
self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred) self.setSizePolicy(QSizePolicy.Minimum, QSizePolicy.Preferred)
self.window = window self.window = window
self.settings_model = self.manager.get_settings() self.settings_model = tuple(v for v in self.manager.get_settings())[0].component
self.tab_group = to_widget(self.settings_model, i18n) self.tab_group = to_widget(self.settings_model, i18n)
self.tab_group.setObjectName('settings') self.tab_group.setObjectName('settings')