mirror of
https://github.com/fergalmoran/picard.git
synced 2025-12-22 17:28:58 +00:00
241 lines
11 KiB
Python
241 lines
11 KiB
Python
# -*- coding: utf-8 -*-
|
|
#
|
|
# Picard, the next-generation MusicBrainz tagger
|
|
#
|
|
# Copyright (C) 2007-2008 Lukáš Lalinský
|
|
# Copyright (C) 2008 Will
|
|
# Copyright (C) 2009, 2019-2023 Philipp Wolfer
|
|
# Copyright (C) 2011, 2013 Michael Wiencek
|
|
# Copyright (C) 2013, 2019 Wieland Hoffmann
|
|
# Copyright (C) 2013-2014, 2018, 2020-2024 Laurent Monin
|
|
# Copyright (C) 2016 Rahul Raturi
|
|
# Copyright (C) 2016-2018 Sambhav Kothari
|
|
# Copyright (C) 2017 Antonio Larrosa
|
|
# Copyright (C) 2018, 2023-2024 Bob Swift
|
|
# Copyright (C) 2021 Gabriel Ferreira
|
|
#
|
|
# This program is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU General Public License
|
|
# as published by the Free Software Foundation; either version 2
|
|
# of the License, or (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program; if not, write to the Free Software
|
|
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
|
|
|
|
import os.path
|
|
|
|
from PyQt6 import (
|
|
QtCore,
|
|
QtWidgets,
|
|
)
|
|
from PyQt6.QtCore import QStandardPaths
|
|
|
|
from picard.config import (
|
|
BoolOption,
|
|
TextOption,
|
|
get_config,
|
|
)
|
|
from picard.const.languages import UI_LANGUAGES
|
|
from picard.const.sys import IS_MACOS
|
|
from picard.i18n import (
|
|
N_,
|
|
gettext as _,
|
|
gettext_constants,
|
|
)
|
|
from picard.util import strxfrm
|
|
|
|
from picard.ui.options import (
|
|
OptionsPage,
|
|
register_options_page,
|
|
)
|
|
from picard.ui.theme import (
|
|
AVAILABLE_UI_THEMES,
|
|
OS_SUPPORTS_THEMES,
|
|
UiTheme,
|
|
)
|
|
from picard.ui.ui_options_interface import Ui_InterfaceOptionsPage
|
|
from picard.ui.util import changes_require_restart_warning
|
|
|
|
|
|
_default_starting_dir = QStandardPaths.writableLocation(QStandardPaths.StandardLocation.HomeLocation)
|
|
|
|
# On macOS it is not common that the global menu shows icons
|
|
DEFAULT_SHOW_MENU_ICONS = not IS_MACOS
|
|
|
|
|
|
class InterfaceOptionsPage(OptionsPage):
|
|
|
|
NAME = 'interface'
|
|
TITLE = N_("User Interface")
|
|
PARENT = None
|
|
SORT_ORDER = 80
|
|
ACTIVE = True
|
|
HELP_URL = "/config/options_interface.html"
|
|
|
|
options = [
|
|
BoolOption('setting', 'toolbar_show_labels', True, title=N_("Show text labels under icons")),
|
|
BoolOption('setting', 'allow_multi_dirs_selection', False, title=N_("Allow selection of multiple directories")),
|
|
BoolOption('setting', 'show_menu_icons', DEFAULT_SHOW_MENU_ICONS, title=N_("Show icons in menus")),
|
|
BoolOption('setting', 'builtin_search', True, title=N_("Use builtin search rather than looking in browser")),
|
|
BoolOption('setting', 'use_adv_search_syntax', False, title=N_("Use advanced search syntax")),
|
|
BoolOption('setting', 'show_new_user_dialog', True, title=N_("Show a usage warning dialog when Picard starts")),
|
|
BoolOption('setting', 'quit_confirmation', True, title=N_("Show a quit confirmation dialog for unsaved changes")),
|
|
BoolOption('setting', 'file_save_warning', True, title=N_("Show a confirmation dialog when saving files")),
|
|
TextOption('setting', 'ui_language', '', title=N_("User interface language")),
|
|
TextOption('setting', 'ui_theme', str(UiTheme.DEFAULT), title=N_("User interface color theme")),
|
|
BoolOption('setting', 'filebrowser_horizontal_autoscroll', True, title=N_("Adjust horizontal position in file browser automatically")),
|
|
BoolOption('setting', 'starting_directory', False, title=N_("Begin browsing in a specific directory")),
|
|
TextOption('setting', 'starting_directory_path', _default_starting_dir, title=N_("Directory to begin browsing")),
|
|
TextOption('setting', 'load_image_behavior', 'append'),
|
|
]
|
|
|
|
# Those are labels for theme display
|
|
_UI_THEME_LABELS = {
|
|
UiTheme.DEFAULT: {
|
|
'label': N_("Default"),
|
|
'desc': N_("The default color scheme based on the operating system display settings"),
|
|
},
|
|
UiTheme.DARK: {
|
|
'label': N_("Dark"),
|
|
'desc': N_("A dark display theme"),
|
|
},
|
|
UiTheme.LIGHT: {
|
|
'label': N_("Light"),
|
|
'desc': N_("A light display theme"),
|
|
},
|
|
UiTheme.SYSTEM: {
|
|
'label': N_("System"),
|
|
'desc': N_("The Qt6 theme configured in the desktop environment"),
|
|
},
|
|
}
|
|
|
|
def __init__(self, parent=None):
|
|
super().__init__(parent)
|
|
self.ui = Ui_InterfaceOptionsPage()
|
|
self.ui.setupUi(self)
|
|
|
|
self.ui.ui_theme.clear()
|
|
for theme in AVAILABLE_UI_THEMES:
|
|
label = self._UI_THEME_LABELS[theme]['label']
|
|
desc = self._UI_THEME_LABELS[theme]['desc']
|
|
self.ui.ui_theme.addItem(_(label), theme)
|
|
idx = self.ui.ui_theme.findData(theme)
|
|
self.ui.ui_theme.setItemData(idx, _(desc), QtCore.Qt.ItemDataRole.ToolTipRole)
|
|
self.ui.ui_theme.setCurrentIndex(self.ui.ui_theme.findData(UiTheme.DEFAULT))
|
|
|
|
self.ui.ui_language.addItem(_("System default"), '')
|
|
language_list = [(lang[0], lang[1], gettext_constants(lang[2])) for lang in UI_LANGUAGES]
|
|
|
|
def fcmp(x):
|
|
return strxfrm(x[2])
|
|
for lang_code, native, translation in sorted(language_list, key=fcmp):
|
|
if native and native != translation:
|
|
name = '%s (%s)' % (translation, native)
|
|
else:
|
|
name = translation
|
|
self.ui.ui_language.addItem(name, lang_code)
|
|
self.ui.starting_directory.toggled.connect(
|
|
self.ui.starting_directory_path.setEnabled
|
|
)
|
|
self.ui.starting_directory.toggled.connect(
|
|
self.ui.starting_directory_browse.setEnabled
|
|
)
|
|
self.ui.starting_directory_browse.clicked.connect(self.starting_directory_browse)
|
|
|
|
if not OS_SUPPORTS_THEMES:
|
|
self.ui.ui_theme_container.hide()
|
|
|
|
self.ui.allow_multi_dirs_selection.stateChanged.connect(self.multi_selection_warning)
|
|
|
|
def load(self):
|
|
# Don't display the multi-selection warning when loading values.
|
|
# This is required because loading a different option profile could trigger the warning.
|
|
self.ui.allow_multi_dirs_selection.blockSignals(True)
|
|
|
|
config = get_config()
|
|
self.ui.toolbar_show_labels.setChecked(config.setting['toolbar_show_labels'])
|
|
self.ui.allow_multi_dirs_selection.setChecked(config.setting['allow_multi_dirs_selection'])
|
|
self.ui.show_menu_icons.setChecked(config.setting['show_menu_icons'])
|
|
self.ui.builtin_search.setChecked(config.setting['builtin_search'])
|
|
self.ui.use_adv_search_syntax.setChecked(config.setting['use_adv_search_syntax'])
|
|
self.ui.new_user_dialog.setChecked(config.setting['show_new_user_dialog'])
|
|
self.ui.quit_confirmation.setChecked(config.setting['quit_confirmation'])
|
|
self.ui.file_save_warning.setChecked(config.setting['file_save_warning'])
|
|
current_ui_language = config.setting['ui_language']
|
|
self.ui.ui_language.setCurrentIndex(self.ui.ui_language.findData(current_ui_language))
|
|
self.ui.filebrowser_horizontal_autoscroll.setChecked(config.setting['filebrowser_horizontal_autoscroll'])
|
|
self.ui.starting_directory.setChecked(config.setting['starting_directory'])
|
|
self.ui.starting_directory_path.setText(config.setting['starting_directory_path'])
|
|
current_theme = UiTheme(config.setting['ui_theme'])
|
|
self.ui.ui_theme.setCurrentIndex(self.ui.ui_theme.findData(current_theme))
|
|
|
|
# re-enable the multi-selection warning
|
|
self.ui.allow_multi_dirs_selection.blockSignals(False)
|
|
|
|
def save(self):
|
|
config = get_config()
|
|
config.setting['toolbar_show_labels'] = self.ui.toolbar_show_labels.isChecked()
|
|
config.setting['allow_multi_dirs_selection'] = self.ui.allow_multi_dirs_selection.isChecked()
|
|
config.setting['show_menu_icons'] = self.ui.show_menu_icons.isChecked()
|
|
self.tagger.enable_menu_icons(config.setting['show_menu_icons'])
|
|
config.setting['builtin_search'] = self.ui.builtin_search.isChecked()
|
|
config.setting['use_adv_search_syntax'] = self.ui.use_adv_search_syntax.isChecked()
|
|
config.setting['show_new_user_dialog'] = self.ui.new_user_dialog.isChecked()
|
|
config.setting['quit_confirmation'] = self.ui.quit_confirmation.isChecked()
|
|
config.setting['file_save_warning'] = self.ui.file_save_warning.isChecked()
|
|
self.tagger.window.update_toolbar_style()
|
|
new_theme_setting = str(self.ui.ui_theme.itemData(self.ui.ui_theme.currentIndex()))
|
|
new_language = self.ui.ui_language.itemData(self.ui.ui_language.currentIndex())
|
|
warnings = []
|
|
notes = []
|
|
if new_theme_setting != config.setting['ui_theme']:
|
|
warnings.append(_("You have changed the application theme."))
|
|
if new_theme_setting == str(UiTheme.SYSTEM):
|
|
notes.append(_(
|
|
'Please note that using the system theme might cause the user interface to be not shown correctly. '
|
|
'If this is the case select the "Default" theme option to use Picard\'s default theme again.'
|
|
))
|
|
config.setting['ui_theme'] = new_theme_setting
|
|
if new_language != config.setting['ui_language']:
|
|
config.setting['ui_language'] = new_language
|
|
warnings.append(_("You have changed the interface language."))
|
|
changes_require_restart_warning(self, warnings=warnings, notes=notes)
|
|
|
|
config.setting['filebrowser_horizontal_autoscroll'] = self.ui.filebrowser_horizontal_autoscroll.isChecked()
|
|
config.setting['starting_directory'] = self.ui.starting_directory.isChecked()
|
|
config.setting['starting_directory_path'] = os.path.normpath(self.ui.starting_directory_path.text())
|
|
|
|
def starting_directory_browse(self):
|
|
item = self.ui.starting_directory_path
|
|
path = QtWidgets.QFileDialog.getExistingDirectory(self, "", item.text())
|
|
if path:
|
|
path = os.path.normpath(path)
|
|
item.setText(path)
|
|
|
|
def multi_selection_warning(self):
|
|
if not self.ui.allow_multi_dirs_selection.isChecked():
|
|
return
|
|
|
|
dialog = QtWidgets.QMessageBox(
|
|
QtWidgets.QMessageBox.Icon.Warning,
|
|
_('Option Setting Warning'),
|
|
_(
|
|
'When enabling the multiple directories option setting Picard will no longer use the system '
|
|
'file picker for selecting directories. This may result in reduced functionality.\n\n'
|
|
'Are you sure that you want to enable this setting?'
|
|
),
|
|
QtWidgets.QMessageBox.StandardButton.Yes | QtWidgets.QMessageBox.StandardButton.No,
|
|
self)
|
|
if dialog.exec() == QtWidgets.QMessageBox.StandardButton.No:
|
|
self.ui.allow_multi_dirs_selection.setCheckState(QtCore.Qt.CheckState.Unchecked)
|
|
|
|
|
|
register_options_page(InterfaceOptionsPage)
|