openlp/openlp/core/ui/advancedtab.py

275 lines
16 KiB
Python

# -*- coding: utf-8 -*-
##########################################################################
# OpenLP - Open Source Lyrics Projection #
# ---------------------------------------------------------------------- #
# Copyright (c) 2008-2022 OpenLP Developers #
# ---------------------------------------------------------------------- #
# 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 3 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, see <https://www.gnu.org/licenses/>. #
##########################################################################
"""
The :mod:`advancedtab` provides an advanced settings facility.
"""
import logging
from PyQt5 import QtWidgets
from openlp.core.common.applocation import AppLocation
from openlp.core.common.i18n import UiStrings, translate
from openlp.core.lib.settingstab import SettingsTab
from openlp.core.ui.icons import UiIcons
from openlp.core.widgets.edits import PathEdit
from openlp.core.widgets.enums import PathEditType
from openlp.core.widgets.widgets import ProxyWidget
log = logging.getLogger(__name__)
class AdvancedTab(SettingsTab):
"""
The :class:`AdvancedTab` manages the advanced settings tab including the UI
and the loading and saving of the displayed settings.
"""
def __init__(self, parent):
"""
Initialise the settings tab
"""
self.data_exists = False
self.icon_path = UiIcons().settings
advanced_translated = translate('OpenLP.AdvancedTab', 'Advanced')
super(AdvancedTab, self).__init__(parent, 'Advanced', advanced_translated)
def setup_ui(self):
"""
Configure the UI elements for the tab.
"""
self.setObjectName('AdvancedTab')
super(AdvancedTab, self).setup_ui()
# Data Directory
self.data_directory_group_box = QtWidgets.QGroupBox(self.left_column)
self.data_directory_group_box.setObjectName('data_directory_group_box')
self.data_directory_layout = QtWidgets.QFormLayout(self.data_directory_group_box)
self.data_directory_layout.setObjectName('data_directory_layout')
self.data_directory_new_label = QtWidgets.QLabel(self.data_directory_group_box)
self.data_directory_new_label.setObjectName('data_directory_current_label')
self.data_directory_path_edit = PathEdit(self.data_directory_group_box, path_type=PathEditType.Directories,
default_path=AppLocation.get_directory(AppLocation.DataDir))
self.data_directory_layout.addRow(self.data_directory_new_label, self.data_directory_path_edit)
self.new_data_directory_has_files_label = QtWidgets.QLabel(self.data_directory_group_box)
self.new_data_directory_has_files_label.setObjectName('new_data_directory_has_files_label')
self.new_data_directory_has_files_label.setWordWrap(True)
self.data_directory_cancel_button = QtWidgets.QToolButton(self.data_directory_group_box)
self.data_directory_cancel_button.setObjectName('data_directory_cancel_button')
self.data_directory_cancel_button.setIcon(UiIcons().delete)
self.data_directory_copy_check_layout = QtWidgets.QHBoxLayout()
self.data_directory_copy_check_layout.setObjectName('data_directory_copy_check_layout')
self.data_directory_copy_check_box = QtWidgets.QCheckBox(self.data_directory_group_box)
self.data_directory_copy_check_box.setObjectName('data_directory_copy_check_box')
self.data_directory_copy_check_layout.addWidget(self.data_directory_copy_check_box)
self.data_directory_copy_check_layout.addStretch()
self.data_directory_copy_check_layout.addWidget(self.data_directory_cancel_button)
self.data_directory_layout.addRow(self.data_directory_copy_check_layout)
self.data_directory_layout.addRow(self.new_data_directory_has_files_label)
self.left_layout.addWidget(self.data_directory_group_box)
# Display Workarounds
self.display_workaround_group_box = QtWidgets.QGroupBox(self.left_column)
self.display_workaround_group_box.setObjectName('display_workaround_group_box')
self.display_workaround_layout = QtWidgets.QVBoxLayout(self.display_workaround_group_box)
self.display_workaround_layout.setObjectName('display_workaround_layout')
self.ignore_aspect_ratio_check_box = QtWidgets.QCheckBox(self.display_workaround_group_box)
self.ignore_aspect_ratio_check_box.setObjectName('ignore_aspect_ratio_check_box')
self.display_workaround_layout.addWidget(self.ignore_aspect_ratio_check_box)
self.x11_bypass_check_box = QtWidgets.QCheckBox(self.display_workaround_group_box)
self.x11_bypass_check_box.setObjectName('x11_bypass_check_box')
self.display_workaround_layout.addWidget(self.x11_bypass_check_box)
self.alternate_rows_check_box = QtWidgets.QCheckBox(self.display_workaround_group_box)
self.alternate_rows_check_box.setObjectName('alternate_rows_check_box')
self.display_workaround_layout.addWidget(self.alternate_rows_check_box)
self.allow_transparent_display_check_box = QtWidgets.QCheckBox(self.display_workaround_group_box)
self.allow_transparent_display_check_box.setObjectName('allow_transparent_display_check_box')
self.display_workaround_layout.addWidget(self.allow_transparent_display_check_box)
self.left_layout.addWidget(self.display_workaround_group_box)
# Proxies
self.proxy_widget = ProxyWidget(self.right_column)
self.right_layout.addWidget(self.proxy_widget)
# After the last item on each side, add some spacing
self.left_layout.addStretch()
self.right_layout.addStretch()
# Set up all the connections and things
self.alternate_rows_check_box.toggled.connect(self.on_alternate_rows_check_box_toggled)
self.data_directory_path_edit.pathChanged.connect(self.on_data_directory_path_edit_path_changed)
self.data_directory_cancel_button.clicked.connect(self.on_data_directory_cancel_button_clicked)
self.data_directory_copy_check_box.toggled.connect(self.on_data_directory_copy_check_box_toggled)
def retranslate_ui(self):
"""
Setup the interface translation strings.
"""
self.tab_title_visible = UiStrings().Advanced
self.data_directory_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Data Location'))
self.data_directory_new_label.setText(translate('OpenLP.AdvancedTab', 'Path:'))
self.data_directory_cancel_button.setText(translate('OpenLP.AdvancedTab', 'Cancel'))
self.data_directory_cancel_button.setToolTip(
translate('OpenLP.AdvancedTab', 'Cancel OpenLP data directory location change.'))
self.data_directory_copy_check_box.setText(translate('OpenLP.AdvancedTab', 'Copy data to new location.'))
self.data_directory_copy_check_box.setToolTip(translate(
'OpenLP.AdvancedTab', 'Copy the OpenLP data files to the new location.'))
self.new_data_directory_has_files_label.setText(
translate('OpenLP.AdvancedTab', '<strong>WARNING:</strong> New data directory location contains '
'OpenLP data files. These files WILL be replaced during a copy.'))
self.display_workaround_group_box.setTitle(translate('OpenLP.AdvancedTab', 'Display Workarounds'))
self.ignore_aspect_ratio_check_box.setText(translate('OpenLP.AdvancedTab', 'Ignore Aspect Ratio'))
self.x11_bypass_check_box.setText(translate('OpenLP.AdvancedTab', 'Bypass X11 Window Manager'))
self.alternate_rows_check_box.setText(translate('OpenLP.AdvancedTab', 'Use alternating row colours in lists'))
self.allow_transparent_display_check_box.setText(
translate('OpenLP.AdvancedTab', 'Disable display transparency'))
self.proxy_widget.retranslate_ui()
def load(self):
"""
Load settings from disk.
"""
self.ignore_aspect_ratio_check_box.setChecked(self.settings.value('advanced/ignore aspect ratio'))
self.x11_bypass_check_box.setChecked(self.settings.value('advanced/x11 bypass wm'))
# Prevent the dialog displayed by the alternate_rows_check_box to display.
self.alternate_rows_check_box.blockSignals(True)
self.alternate_rows_check_box.setChecked(self.settings.value('advanced/alternate rows'))
self.alternate_rows_check_box.blockSignals(False)
self.allow_transparent_display_check_box.setChecked(self.settings.value('advanced/disable transparent display'))
self.data_directory_copy_check_box.hide()
self.new_data_directory_has_files_label.hide()
self.data_directory_cancel_button.hide()
# Since data location can be changed, make sure the path is present.
self.data_directory_path_edit.path = AppLocation.get_data_path()
# Don't allow data directory move if running portable.
if self.settings.value('advanced/is portable'):
self.data_directory_group_box.hide()
def save(self):
"""
Save settings to disk.
"""
self.settings.setValue('advanced/disable transparent display',
self.allow_transparent_display_check_box.isChecked())
self.settings.setValue('advanced/ignore aspect ratio', self.ignore_aspect_ratio_check_box.isChecked())
if self.x11_bypass_check_box.isChecked() != self.settings.value('advanced/x11 bypass wm'):
self.settings.setValue('advanced/x11 bypass wm', self.x11_bypass_check_box.isChecked())
self.settings_form.register_post_process('config_screen_changed')
self.settings.setValue('advanced/alternate rows', self.alternate_rows_check_box.isChecked())
self.proxy_widget.save()
def cancel(self):
"""
Dialogue was cancelled, remove any pending data path change.
"""
self.on_data_directory_cancel_button_clicked()
SettingsTab.cancel(self)
def on_data_directory_path_edit_path_changed(self, new_path):
"""
Handle the `editPathChanged` signal of the data_directory_path_edit
:param pathlib.Path new_path: The new path
:rtype: None
"""
# Check if data already exists here.
self.check_data_overwrite(new_path)
# Make sure they want to change the data.
if self.data_directory_copy_check_box.isChecked():
warning_string = translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '
'location of the OpenLP data directory to:\n\n{path}'
'\n\nExisting files in this directory could be '
'overwritten. The data directory will be changed when '
'OpenLP is closed.').format(path=new_path)
else:
warning_string = translate('OpenLP.AdvancedTab', 'Are you sure you want to change the '
'location of the OpenLP data directory to:\n\n{path}'
'\n\nThe data directory will be changed when OpenLP is '
'closed.').format(path=new_path)
answer = QtWidgets.QMessageBox.question(self, translate('OpenLP.AdvancedTab', 'Confirm Data Directory Change'),
warning_string, defaultButton=QtWidgets.QMessageBox.No)
if answer != QtWidgets.QMessageBox.Yes:
self.data_directory_path_edit.path = AppLocation.get_data_path()
self.new_data_directory_has_files_label.hide()
return
# Save the new location.
self.main_window.new_data_path = new_path
self.data_directory_cancel_button.show()
def on_data_directory_copy_check_box_toggled(self):
"""
Copy existing data when you change your data directory.
"""
self.main_window.set_copy_data(self.data_directory_copy_check_box.isChecked())
if self.data_exists:
if self.data_directory_copy_check_box.isChecked():
self.new_data_directory_has_files_label.show()
else:
self.new_data_directory_has_files_label.hide()
def check_data_overwrite(self, data_path):
"""
Check if there's already data in the target directory.
:param pathlib.Path data_path: The target directory to check
"""
if (data_path / 'songs').exists():
self.data_exists = True
# Check is they want to replace existing data.
answer = QtWidgets.QMessageBox.warning(self,
translate('OpenLP.AdvancedTab', 'Overwrite Existing Data'),
translate('OpenLP.AdvancedTab',
'WARNING: \n\nThe location you have selected \n\n{path}'
'\n\nappears to contain OpenLP data files. Do you wish to '
'replace these files with the current data '
'files?').format(path=data_path),
QtWidgets.QMessageBox.StandardButtons(QtWidgets.QMessageBox.Yes |
QtWidgets.QMessageBox.No),
QtWidgets.QMessageBox.No)
self.data_directory_copy_check_box.show()
if answer == QtWidgets.QMessageBox.Yes:
self.data_directory_copy_check_box.setChecked(True)
self.new_data_directory_has_files_label.show()
else:
self.data_directory_copy_check_box.setChecked(False)
self.new_data_directory_has_files_label.hide()
else:
self.data_exists = False
self.data_directory_copy_check_box.setChecked(True)
self.new_data_directory_has_files_label.hide()
def on_data_directory_cancel_button_clicked(self):
"""
Cancel the data directory location change
"""
self.data_directory_path_edit.path = AppLocation.get_data_path()
self.data_directory_copy_check_box.setChecked(False)
self.main_window.new_data_path = None
self.main_window.set_copy_data(False)
self.data_directory_copy_check_box.hide()
self.data_directory_cancel_button.hide()
self.new_data_directory_has_files_label.hide()
def on_alternate_rows_check_box_toggled(self, checked):
"""
Notify user about required restart.
:param checked: The state of the check box (boolean).
"""
QtWidgets.QMessageBox.information(self, translate('OpenLP.AdvancedTab', 'Restart Required'),
translate('OpenLP.AdvancedTab',
'This change will only take effect once OpenLP '
'has been restarted.'))