1# -*- coding: utf-8 -*- 2# 3# Picard, the next-generation MusicBrainz tagger 4# 5# Copyright (C) 2007 Lukáš Lalinský 6# Copyright (C) 2013-2015, 2018-2019 Laurent Monin 7# Copyright (C) 2016-2017 Sambhav Kothari 8# Copyright (C) 2017 Frederik “Freso” S. Olesen 9# Copyright (C) 2017 Sophist-UK 10# Copyright (C) 2018 Vishal Choudhary 11# Copyright (C) 2019 Philipp Wolfer 12# 13# This program is free software; you can redistribute it and/or 14# modify it under the terms of the GNU General Public License 15# as published by the Free Software Foundation; either version 2 16# of the License, or (at your option) any later version. 17# 18# This program is distributed in the hope that it will be useful, 19# but WITHOUT ANY WARRANTY; without even the implied warranty of 20# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 21# GNU General Public License for more details. 22# 23# You should have received a copy of the GNU General Public License 24# along with this program; if not, write to the Free Software 25# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 26 27 28from PyQt5 import ( 29 QtCore, 30 QtWidgets, 31) 32 33from picard.config import get_config 34from picard.const.sys import ( 35 IS_MACOS, 36 IS_WIN, 37) 38from picard.util import find_existing_path 39 40 41class StandardButton(QtWidgets.QPushButton): 42 43 OK = 0 44 CANCEL = 1 45 HELP = 2 46 CLOSE = 4 47 48 __types = { 49 OK: (N_('&Ok'), 'SP_DialogOkButton'), 50 CANCEL: (N_('&Cancel'), 'SP_DialogCancelButton'), 51 HELP: (N_('&Help'), 'SP_DialogHelpButton'), 52 CLOSE: (N_('Clos&e'), 'SP_DialogCloseButton'), 53 } 54 55 def __init__(self, btntype): 56 label = _(self.__types[btntype][0]) 57 args = [label] 58 if not IS_WIN and not IS_MACOS: 59 iconname = self.__types[btntype][1] 60 if hasattr(QtWidgets.QStyle, iconname): 61 icon = self.tagger.style().standardIcon(getattr(QtWidgets.QStyle, iconname)) 62 args = [icon, label] 63 super().__init__(*args) 64 65 66# The following code is there to fix 67# https://tickets.metabrainz.org/browse/PICARD-417 68# In some older version of PyQt/sip it's impossible to connect a signal 69# emitting an `int` to a slot expecting a `bool`. 70# By using `enabledSlot` instead we can force python to do the 71# conversion from int (`state`) to bool. 72def enabledSlot(func, state): 73 """Calls `func` with `state`.""" 74 func(state) 75 76 77def find_starting_directory(): 78 config = get_config() 79 if config.setting["starting_directory"]: 80 path = config.setting["starting_directory_path"] 81 else: 82 path = config.persist["current_directory"] or QtCore.QDir.homePath() 83 return find_existing_path(path) 84 85 86class MultiDirsSelectDialog(QtWidgets.QFileDialog): 87 88 """Custom file selection dialog which allows the selection 89 of multiple directories. 90 Depending on the platform, dialog may fallback on non-native. 91 """ 92 93 def __init__(self, *args): 94 super().__init__(*args) 95 self.setFileMode(self.Directory) 96 self.setOption(self.ShowDirsOnly) 97 # The native dialog doesn't allow selecting >1 directory 98 self.setOption(self.DontUseNativeDialog) 99 for view in self.findChildren((QtWidgets.QListView, QtWidgets.QTreeView)): 100 if isinstance(view.model(), QtWidgets.QFileSystemModel): 101 view.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection) 102