gem selector panel working

This commit is contained in:
Vinicius Moreira
2019-09-11 17:50:53 -03:00
parent ba5e1da11b
commit fb779cd650
12 changed files with 149 additions and 77 deletions

View File

@@ -49,7 +49,7 @@ else:
enabled_managers = [m for m in managers if m.is_enabled()]
if not user_config.gems and enabled_managers:
gem_panel = GemSelectorPanel(enabled_managers, i18n, boot=True)
gem_panel = GemSelectorPanel(enabled_managers, i18n, managers_set=None)
gem_panel.show()
else:
manager = GenericSoftwareManager(enabled_managers, context=context, app_args=args)
@@ -62,7 +62,9 @@ else:
download_icons=bool(args.download_icons),
screen_size=app.primaryScreen().size(),
suggestions=args.sugs,
display_limit=args.max_displayed)
display_limit=args.max_displayed,
config=user_config,
context=context)
if args.tray:
trayIcon = TrayIcon(locale_keys=i18n,

View File

@@ -1,7 +1,7 @@
import inspect
import os
import pkgutil
from typing import List
from typing import List, Type
from bauh import ROOT_DIR
from bauh.api.abstract.controller import SoftwareManager, ApplicationContext
@@ -29,10 +29,11 @@ def load_managers(locale: str, context: ApplicationContext, names: List[str] = N
manager_class = find_manager(module)
if manager_class:
locale_path = '{}/resources/locale'.format(f.path)
if locale:
locale_path = '{}/resources/locale'.format(f.path)
if os.path.exists(locale_path):
context.i18n.update(util.get_locale_keys(locale, locale_path))
if os.path.exists(locale_path):
context.i18n.update(util.get_locale_keys(locale, locale_path))
managers.append(manager_class(context=context))

View File

@@ -113,6 +113,11 @@ def save_several(pkgnames: Set[str], mirror: str, overwrite: bool = True) -> int
if entries:
desktop_matches[pkg] = entries[0]
if len(entries) > 1:
for e in entries:
if e.startswith('/usr/share/applications'):
desktop_matches[pkg] = e
if not desktop_matches:
no_desktop_files = to_cache
else:
@@ -130,7 +135,7 @@ def save_several(pkgnames: Set[str], mirror: str, overwrite: bool = True) -> int
for field in RE_DESKTOP_ENTRY.findall(desktop_entry):
if field[0] == 'Exec':
p.command = field[1].strip()
p.command = field[1].strip().replace('"', '')
elif field[0] == 'Icon':
p.icon_path = field[1].strip()

View File

@@ -90,13 +90,14 @@ class ArchPackage(SoftwarePackage):
return cache
def fill_cached_data(self, data: dict):
for a in {'command', 'icon_path', 'mirror', 'desktop_entry'}:
val = data.get(a)
if val:
setattr(self, a, val)
if data:
for a in {'command', 'icon_path', 'mirror', 'desktop_entry'}:
val = data.get(a)
if val:
setattr(self, a, val)
if a == 'icon_path':
self.icon_url = val
if a == 'icon_path':
self.icon_url = val
def can_be_run(self) -> bool:
# only returns if there is a desktop entry set for the application to avoid running command-line applications

View File

@@ -44,7 +44,7 @@ popup.button.yes=Yes
popup.button.no=No
popup.button.cancel=Cancel
tray.action.manage=Manage applications
tray.action.exit=Exit
tray.action.exit=Quit
tray.action.about=About
tray.action.refreshing=Refreshing
notification.new_updates=Updates
@@ -85,7 +85,7 @@ bt.app_upgrade=Upgrade
bt.app_not_upgrade=Don't upgrade
manage_window.upgrade_all.popup.title=Upgrade
manage_window.upgrade_all.popup.body=Upgrade all selected applications ?
manage_window.bt_about.tooltip=About
manage_window.settings.about=About
warning.no_managers=There are no installed extensions. It will not be possible to intall and manage applications.
confirmation=confirmation
and=and
@@ -103,3 +103,10 @@ manage_window.name_filter.tooltip=Type here to filter apps by name
manage_window.name_filter.placeholder=Filter by name
publisher=publisher
publisher.unknown=unknown publisher
welcome=welcome
gem_selector.title=Application types
gem_selector.question=What types of applications do you want to find here ?
proceed=proceed
change=change
exit=exit
manage_window.settings.gems=Application types

View File

@@ -46,7 +46,7 @@ popup.button.yes=Sí
popup.button.no=No
popup.button.cancel=Cancelar
tray.action.manage=Administrar aplicativos
tray.action.exit=Salir
tray.action.exit=Cerrar
tray.action.about=Sobre
tray.action.refreshing=Recargando
notification.new_updates=Actualizaciones
@@ -87,7 +87,7 @@ bt.app_upgrade=Actualizar
bt.app_not_upgrade=No actualizar
manage_window.upgrade_all.popup.title=Actualizar
manage_window.upgrade_all.popup.body=¿Actualizar todos los aplicativos seleccionados?
manage_window.bt_about.tooltip=Sobre
manage_window.settings.about=Sobre
warning.no_managers=No hay extensiones instaladas. No será posible instalar y administrar aplicaciones.
confirmation=confirmación
and=y
@@ -104,4 +104,11 @@ any=cualquier
manage_window.name_filter.tooltip=Escriba aquí para filtrar aplicaciones por nombre
manage_window.name_filter.placeholder=Filtrar por nombre
publisher=publicador
publisher.unknown=publicador desconocido
publisher.unknown=publicador desconocido
welcome=bienvenido
gem_selector.title=Tipos de aplicativos
gem_selector.question=¿Qué tipos de aplicativos quieres encontrar aquí?
proceed=continuar
change=cambiar
exit=salir
manage_window.settings.gems=Tipos de aplicativos

View File

@@ -46,7 +46,7 @@ popup.button.yes=Sim
popup.button.no=Não
popup.button.cancel=Cancelar
tray.action.manage=Gerenciar aplicativos
tray.action.exit=Sair
tray.action.exit=Fechar
tray.action.about=Sobre
tray.action.refreshing=Recarregando
notification.new_updates=Atualizações
@@ -87,7 +87,7 @@ bt.app_upgrade=Atualizar
bt.app_not_upgrade=Não atualizar
manage_window.upgrade_all.popup.title=Atualizar
manage_window.upgrade_all.popup.body=Atualizar todos os aplicativos selecionados ?
manage_window.bt_about.tooltip=Sobre
manage_window.settings.about=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
@@ -104,4 +104,11 @@ any=qualquer
manage_window.name_filter.tooltip=Digite aqui para filtrar aplicativos pelo nome
manage_window.name_filter.placeholder=Filtrar por nome
publisher=publicador
publisher.unknown=publicador desconhecido
publisher.unknown=publicador desconhecido
welcome=bem vindo
gem_selector.title=Tipos de aplicativos
gem_selector.question=Quais tipos de aplicativos você quer encontrar por aqui ?
proceed=continuar
change=alterar
exit=sair
manage_window.settings.gems=Tipos de aplicativos

View File

@@ -47,11 +47,12 @@ class AsyncDiskCacheLoader(Thread, DiskCacheLoader):
if os.path.exists(pkg.get_disk_data_path()):
with open(pkg.get_disk_data_path()) as f:
cached_data = json.loads(f.read())
pkg.fill_cached_data(cached_data)
cache = self.cache_map.get(pkg.__class__)\
if cached_data:
pkg.fill_cached_data(cached_data)
cache = self.cache_map.get(pkg.__class__)\
if cache:
cache.add_non_existing(pkg.id, cached_data)
if cache:
cache.add_non_existing(pkg.id, cached_data)
class DefaultDiskCacheLoaderFactory(DiskCacheLoaderFactory):
@@ -63,10 +64,8 @@ class DefaultDiskCacheLoaderFactory(DiskCacheLoaderFactory):
def map(self, pkg_type: Type[SoftwarePackage], cache: MemoryCache):
if pkg_type:
if pkg_type in self.cache_map:
raise Exception('{} is already mapped')
self.cache_map[pkg_type] = cache
if pkg_type not in self.cache_map:
self.cache_map[pkg_type] = cache
def new(self) -> AsyncDiskCacheLoader:
return AsyncDiskCacheLoader(enabled=self.disk_cache_enabled, cache_map=self.cache_map)

View File

@@ -13,32 +13,12 @@ from bauh.api.abstract.model import PackageStatus
from bauh.util import resource
from bauh.util.html import strip_html
from bauh.view.qt import dialog
from bauh.view.qt.components import IconButton
from bauh.view.qt.view_model import PackageView, PackageViewStatus
INSTALL_BT_STYLE = 'background: {back}; color: white; font-size: 10px; font-weight: bold'
class IconButton(QWidget):
def __init__(self, icon_path: str, action, background: str = None, align: int = Qt.AlignCenter, tooltip: str = None):
super(IconButton, self).__init__()
self.bt = QToolButton()
self.bt.setIcon(QIcon(icon_path))
self.bt.clicked.connect(action)
if background:
self.bt.setStyleSheet('QToolButton { color: white; background: ' + background + '}')
if tooltip:
self.bt.setToolTip(tooltip)
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setAlignment(align)
layout.addWidget(self.bt)
self.setLayout(layout)
class UpdateToggleButton(QWidget):
def __init__(self, app_view: PackageView, root: QWidget, i18n: dict, checked: bool = True, clickable: bool = True):

View File

@@ -1,10 +1,9 @@
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QIcon
from PyQt5.QtWidgets import QRadioButton, QGroupBox, QCheckBox, QComboBox, QGridLayout, QWidget, \
QLabel, QSizePolicy, QLineEdit
QLabel, QSizePolicy, QLineEdit, QToolButton, QHBoxLayout
from bauh import ROOT_DIR
from bauh.api.abstract.view import SingleSelectComponent, InputOption, MultipleSelectComponent, SelectViewType
from bauh.commons import resource
class RadioButtonQt(QRadioButton):
@@ -162,6 +161,27 @@ class InputFilter(QLineEdit):
self.last_text = p_str
class IconButton(QWidget):
def __init__(self, icon_path: str, action, background: str = None, align: int = Qt.AlignCenter, tooltip: str = None):
super(IconButton, self).__init__()
self.bt = QToolButton()
self.bt.setIcon(QIcon(icon_path))
self.bt.clicked.connect(action)
if background:
self.bt.setStyleSheet('QToolButton { color: white; background: ' + background + '}')
if tooltip:
self.bt.setToolTip(tooltip)
layout = QHBoxLayout()
layout.setContentsMargins(0, 0, 0, 0)
layout.setAlignment(align)
layout.addWidget(self.bt)
self.setLayout(layout)
def new_single_select(model: SingleSelectComponent):
if model.type == SelectViewType.RADIO:
return RadioSelectQt(model)

View File

@@ -16,26 +16,28 @@ from bauh.view.qt.components import MultipleSelectQt, CheckboxQt, new_spacer
class GemSelectorPanel(QWidget):
def __init__(self, managers: List[SoftwareManager], i18n: dict, boot: bool):
def __init__(self, managers: List[SoftwareManager], i18n: dict, managers_set: List[str], exit_on_close: bool = True):
super(GemSelectorPanel, self).__init__()
self.managers = managers
self.setLayout(QGridLayout())
self.setWindowIcon(QIcon(resource.get_path('img/logo.svg', ROOT_DIR)))
self.setWindowTitle('Welcome' if boot else 'Supported types')
self.setWindowTitle(i18n['welcome'].capitalize() if not managers_set else i18n['gem_selector.title'])
self.resize(400, 400)
self.exit_on_close = exit_on_close
self.label_question = QLabel('What types of applications do you want to find here ?')
self.label_question = QLabel(i18n['gem_selector.question'])
self.label_question.setStyleSheet('QLabel { font-weight: bold}')
self.layout().addWidget(self.label_question, 0, 1, Qt.AlignHCenter)
self.bt_proceed = QPushButton('Proceed')
self.bt_proceed.setStyleSheet('QPushButton { background: green; color: white; font-weight: bold}')
self.bt_proceed.setEnabled(True)
self.bt_proceed = QPushButton(i18n['proceed' if not managers_set else 'change'].capitalize())
self.bt_proceed.setStyleSheet("""QPushButton { background: green; color: white; font-weight: bold}
QPushButton:disabled { background-color: gray; }
""")
self.bt_proceed.clicked.connect(self.save)
self.bt_exit = QPushButton('Exit')
self.bt_exit = QPushButton(i18n['exit'].capitalize())
self.bt_exit.setStyleSheet('QPushButton { background: red; color: white; font-weight: bold}')
self.bt_exit.clicked.connect(lambda: QCoreApplication.exit())
self.bt_exit.clicked.connect(self.exit)
gem_options = []
@@ -45,7 +47,14 @@ class GemSelectorPanel(QWidget):
value=modname,
icon_path='{r}/gems/{n}/resources/img/{n}.png'.format(r=ROOT_DIR, n=modname)))
self.gem_select_model = MultipleSelectComponent(label='', options=gem_options, default_options=set(gem_options), max_per_line=3)
if managers_set:
default_ops = {o for o in gem_options if o.value in managers_set}
else:
default_ops = set(gem_options)
self.bt_proceed.setEnabled(bool(default_ops))
self.gem_select_model = MultipleSelectComponent(label='', options=gem_options, default_options=default_ops, max_per_line=3)
self.gem_select = MultipleSelectQt(self.gem_select_model, self.check_state)
self.layout().addWidget(self.gem_select, 1, 1)
@@ -59,11 +68,18 @@ class GemSelectorPanel(QWidget):
self.setFixedSize(self.size())
def check_state(self, model: CheckboxQt, checked: bool):
self.bt_proceed.setEnabled(bool(self.gem_select_model.values))
if self.isVisible():
self.bt_proceed.setEnabled(bool(self.gem_select_model.values))
def save(self):
config = Configuration(gems=[o.value for o in self.gem_select_model.values])
save(config)
subprocess.Popen([sys.executable, *sys.argv])
self.close()
QCoreApplication.exit()
def exit(self):
if self.exit_on_close:
QCoreApplication.exit()
else:
self.close()

View File

@@ -3,20 +3,24 @@ from functools import reduce
from typing import List, Type, Set
from PyQt5.QtCore import QEvent, Qt, QSize, pyqtSignal
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap
from PyQt5.QtGui import QIcon, QWindowStateChangeEvent, QPixmap, QCursor
from PyQt5.QtWidgets import QWidget, QVBoxLayout, QApplication, QCheckBox, QHeaderView, QToolButton, QToolBar, \
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QPushButton, QComboBox
QLabel, QPlainTextEdit, QLineEdit, QProgressBar, QPushButton, QComboBox, QMenu, QAction
from bauh.api.abstract.cache import MemoryCache
from bauh.api.abstract.context import ApplicationContext
from bauh.api.abstract.controller import SoftwareManager
from bauh.api.abstract.model import SoftwarePackage, PackageAction
from bauh.api.abstract.view import MessageType
from bauh.core import gems
from bauh.core.config import Configuration
from bauh.util import util, resource
from bauh.view.qt import dialog, commons
from bauh.view.qt.about import AboutDialog
from bauh.view.qt.apps_table import AppsTable, UpdateToggleButton
from bauh.view.qt.components import new_spacer, InputFilter
from bauh.view.qt.components import new_spacer, InputFilter, IconButton
from bauh.view.qt.confirmation import ConfirmationDialog
from bauh.view.qt.gem_selector import GemSelectorPanel
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
@@ -39,7 +43,8 @@ class ManageWindow(QWidget):
signal_user_res = pyqtSignal(bool)
signal_table_update = pyqtSignal()
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool, download_icons: bool, screen_size, suggestions: bool, display_limit: int, tray_icon=None):
def __init__(self, i18n: dict, icon_cache: MemoryCache, manager: SoftwareManager, disk_cache: bool, download_icons: bool,
screen_size, suggestions: bool, display_limit: int, config: Configuration, context: ApplicationContext, tray_icon=None):
super(ManageWindow, self).__init__()
self.i18n = i18n
self.manager = manager
@@ -53,6 +58,8 @@ class ManageWindow(QWidget):
self.disk_cache = disk_cache
self.download_icons = download_icons
self.screen_size = screen_size
self.config = config
self.context = context
self.icon_app = QIcon(resource.get_path('img/logo.svg'))
self.resize(ManageWindow.__BASE_HEIGHT__, ManageWindow.__BASE_HEIGHT__)
@@ -230,12 +237,8 @@ class ManageWindow(QWidget):
self.toolbar_bottom.addWidget(new_spacer())
bt_about = QToolButton()
bt_about.setStyleSheet('QToolButton { border: 0px; }')
bt_about.setIcon(QIcon(resource.get_path('img/about.svg')))
bt_about.clicked.connect(self._show_about)
bt_about.setToolTip(self.i18n['manage_window.bt_about.tooltip'])
self.ref_bt_about = self.toolbar_bottom.addWidget(bt_about)
bt_settings = IconButton(icon_path=resource.get_path('img/app_settings.svg'), action=self._show_settings_menu, background='#12ABAB')
self.ref_bt_settings = self.toolbar_bottom.addWidget(bt_settings)
self.layout.addWidget(self.toolbar_bottom)
@@ -712,7 +715,7 @@ class ManageWindow(QWidget):
def _begin_action(self, action_label: str, keep_search: bool = False, keep_bt_installed: bool = True, clear_filters: bool = False):
self.ref_input_name_filter.setVisible(False)
self.ref_combo_filter_type.setVisible(False)
self.ref_bt_about.setVisible(False)
self.ref_bt_settings.setVisible(False)
self.ref_label_updates.setVisible(False)
self.thread_animate_progress.stop = False
self.thread_animate_progress.start()
@@ -748,7 +751,7 @@ class ManageWindow(QWidget):
self.progress_bar.setTextVisible(False)
self._change_label_substatus('')
self.ref_bt_about.setVisible(True)
self.ref_bt_settings.setVisible(True)
self.ref_label_updates.setVisible(True)
self.ref_bt_refresh.setVisible(True)
@@ -897,3 +900,27 @@ class ManageWindow(QWidget):
self.refresh_apps(pkg_types={res['pkg'].model.__class__})
else:
self.checkbox_console.setChecked(True)
def _show_gems_selector(self):
managers = gems.load_managers(context=self.context, locale=None)
enabled_managers = [m for m in managers if m.is_enabled()]
gem_panel = GemSelectorPanel(managers=enabled_managers, i18n=self.i18n, managers_set=self.config.gems, exit_on_close=False)
gem_panel.show()
def _show_settings_menu(self):
menu_row = QMenu()
action_gems = QAction(self.i18n['manage_window.settings.gems'])
action_gems.setIcon(self.icon_app)
action_gems.triggered.connect(self._show_gems_selector)
menu_row.addAction(action_gems)
action_about = QAction(self.i18n['manage_window.settings.about'])
action_about.setIcon(QIcon(resource.get_path('img/about.svg')))
action_about.triggered.connect(self._show_about)
menu_row.addAction(action_about)
menu_row.adjustSize()
menu_row.popup(QCursor.pos())
menu_row.exec_()