File indexing completed on 2025-02-23 04:34:16
0001 /** 0002 * \file configdialogpages.cpp 0003 * Pages for configuration dialog. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 17 Sep 2003 0008 * 0009 * Copyright (C) 2003-2024 Urs Fleisch 0010 * 0011 * This file is part of Kid3. 0012 * 0013 * Kid3 is free software; you can redistribute it and/or modify 0014 * it under the terms of the GNU General Public License as published by 0015 * the Free Software Foundation; either version 2 of the License, or 0016 * (at your option) any later version. 0017 * 0018 * Kid3 is distributed in the hope that it will be useful, 0019 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0020 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0021 * GNU General Public License for more details. 0022 * 0023 * You should have received a copy of the GNU General Public License 0024 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0025 */ 0026 0027 #include "configdialogpages.h" 0028 #include <QLayout> 0029 #include <QPushButton> 0030 #include <QLabel> 0031 #include <QString> 0032 #include <QCheckBox> 0033 #include <QComboBox> 0034 #include <QLineEdit> 0035 #include <QTabWidget> 0036 #include <QListView> 0037 #include <QSpinBox> 0038 #include <QToolBox> 0039 #include <QVBoxLayout> 0040 #include <QHBoxLayout> 0041 #include <QFormLayout> 0042 #include <QGroupBox> 0043 #include <QStringListModel> 0044 #include <QStandardItemModel> 0045 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0046 #include <QMediaDevices> 0047 #include <QAudioDevice> 0048 #endif 0049 #include "formatconfig.h" 0050 #include "filenameformatbox.h" 0051 #include "tagformatbox.h" 0052 #include "tablemodeledit.h" 0053 #include "tagconfig.h" 0054 #include "fileconfig.h" 0055 #include "useractionsconfig.h" 0056 #include "guiconfig.h" 0057 #include "networkconfig.h" 0058 #include "importconfig.h" 0059 #include "playlistconfig.h" 0060 #include "stringlistedit.h" 0061 #include "stringlisteditdialog.h" 0062 #include "configtable.h" 0063 #include "commandstablemodel.h" 0064 #include "checkablestringlistmodel.h" 0065 #include "starratingmappingsmodel.h" 0066 #include "fileproxymodel.h" 0067 #include "contexthelp.h" 0068 #include "frame.h" 0069 #include "iplatformtools.h" 0070 0071 namespace { 0072 0073 /** 0074 * @brief Get string representation of folder patterns. 0075 * @param folders folder patterns 0076 * @param asteriskIfEmpty if true "*" is returned if @a folders is empty 0077 * @return string representation of folder patterns. 0078 */ 0079 QString folderPatternListToString(const QStringList& folders, 0080 bool asteriskIfEmpty = false) 0081 { 0082 QStringList patterns; 0083 QChar sep = QLatin1Char(' '); 0084 for (const QString& folder : folders) { 0085 if (QString pattern = folder.trimmed(); !pattern.isEmpty()) { 0086 if (pattern.contains(QLatin1Char(' '))) { 0087 sep = QLatin1Char(';'); 0088 } 0089 patterns.append(pattern); // clazy:exclude=reserve-candidates 0090 } 0091 } 0092 patterns.removeDuplicates(); 0093 if (patterns.isEmpty()) 0094 return QLatin1String(asteriskIfEmpty ? "*" : ""); 0095 0096 // Keep semicolon to mark that space is not a separator. 0097 if (patterns.size() == 1 && sep == QLatin1Char(';')) 0098 return patterns.first() + sep; 0099 0100 return patterns.join(sep); 0101 } 0102 0103 /** 0104 * @brief Get folder patterns from string representation. 0105 * @param patterns string representation of folder patterns 0106 * @param asteriskIfEmpty if true an empty list is returned for "*" 0107 * @return folder pattern list. 0108 */ 0109 QStringList folderPatternListFromString(const QString& patterns, 0110 bool asteriskIfEmpty = false) 0111 { 0112 if (asteriskIfEmpty && patterns == QLatin1String("*")) 0113 return QStringList(); 0114 0115 QStringList folders; 0116 const QChar sep = patterns.contains(QLatin1Char(';')) 0117 ? QLatin1Char(';') : QLatin1Char(' '); 0118 const auto patternList = patterns.split(sep); 0119 for (const QString& pattern : patternList) { 0120 if (QString folder = pattern.trimmed(); !folder.isEmpty()) { 0121 folders.append(folder); // clazy:exclude=reserve-candidates 0122 } 0123 } 0124 0125 return folders; 0126 } 0127 0128 } 0129 0130 /** 0131 * Constructor. 0132 */ 0133 ConfigDialogPages::ConfigDialogPages(IPlatformTools* platformTools, 0134 QObject* parent) : QObject(parent), 0135 m_platformTools(platformTools), 0136 m_loadLastOpenedFileCheckBox(nullptr), m_preserveTimeCheckBox(nullptr), 0137 m_markChangesCheckBox(nullptr), m_coverFileNameLineEdit(nullptr), 0138 m_nameFilterComboBox(nullptr), m_includeFoldersLineEdit(nullptr), 0139 m_excludeFoldersLineEdit(nullptr), m_showHiddenFilesCheckBox(nullptr), 0140 m_fileTextEncodingComboBox(nullptr), 0141 m_markTruncationsCheckBox(nullptr), m_textEncodingV1ComboBox(nullptr), 0142 m_totalNumTracksCheckBox(nullptr), m_commentNameComboBox(nullptr), 0143 m_pictureNameComboBox(nullptr), m_markOversizedPicturesCheckBox(nullptr), 0144 m_maximumPictureSizeSpinBox(nullptr), m_genreNotNumericCheckBox(nullptr), 0145 m_lowercaseId3ChunkCheckBox(nullptr), 0146 m_markStandardViolationsCheckBox(nullptr), m_textEncodingComboBox(nullptr), 0147 m_id3v2VersionComboBox(nullptr), m_trackNumberDigitsSpinBox(nullptr), 0148 m_fnFormatBox(nullptr), m_tagFormatBox(nullptr), 0149 m_onlyCustomGenresCheckBox(nullptr), m_genresEditModel(nullptr), 0150 m_customFramesEditModel(nullptr), 0151 m_quickAccessTagsModel(nullptr), m_starRatingMappingsModel(nullptr), 0152 m_trackNameComboBox(nullptr), m_playOnDoubleClickCheckBox(nullptr), 0153 m_selectFileOnPlayCheckBox(nullptr), 0154 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0155 m_audioOutputComboBox(nullptr), 0156 #endif 0157 m_commandsTable(nullptr), m_commandsTableModel(nullptr), 0158 m_browserLineEdit(nullptr), m_proxyCheckBox(nullptr), 0159 m_proxyLineEdit(nullptr), m_proxyAuthenticationCheckBox(nullptr), 0160 m_proxyUserNameLineEdit(nullptr), m_proxyPasswordLineEdit(nullptr), 0161 m_enabledMetadataPluginsModel(nullptr), m_enabledPluginsModel(nullptr) 0162 { 0163 } 0164 0165 /** 0166 * Create page with tags settings. 0167 * @return tags page. 0168 */ 0169 QWidget* ConfigDialogPages::createTagsPage() 0170 { 0171 auto tagsPage = new QWidget; 0172 auto vlayout = new QVBoxLayout(tagsPage); 0173 0174 auto tag1Page = new QWidget; 0175 auto tag1Layout = new QVBoxLayout(tag1Page); 0176 auto v1GroupBox = new QGroupBox(tr("ID3v1"), tag1Page); 0177 auto v1GroupBoxLayout = new QGridLayout(v1GroupBox); 0178 m_markTruncationsCheckBox = new QCheckBox( 0179 tr("&Mark truncated fields"), v1GroupBox); 0180 v1GroupBoxLayout->addWidget(m_markTruncationsCheckBox, 0, 0, 1, 2); 0181 auto textEncodingV1Label = new QLabel(tr("Text &encoding:"), v1GroupBox); 0182 m_textEncodingV1ComboBox = new QComboBox(v1GroupBox); 0183 m_textEncodingV1ComboBox->addItems(TagConfig::getTextCodecNames()); 0184 m_textEncodingV1ComboBox->setSizePolicy( 0185 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0186 textEncodingV1Label->setBuddy(m_textEncodingV1ComboBox); 0187 v1GroupBoxLayout->addWidget(textEncodingV1Label, 1, 0); 0188 v1GroupBoxLayout->addWidget(m_textEncodingV1ComboBox, 1, 1); 0189 tag1Layout->addWidget(v1GroupBox); 0190 tag1Layout->addStretch(); 0191 0192 auto tag2Page = new QWidget; 0193 auto tag2Layout = new QHBoxLayout(tag2Page); 0194 auto tag2LeftLayout = new QVBoxLayout; 0195 auto v2GroupBox = new QGroupBox(tr("ID3v2"), tag2Page); 0196 auto v2GroupBoxLayout = new QGridLayout(v2GroupBox); 0197 m_totalNumTracksCheckBox = new QCheckBox( 0198 tr("Use &track/total number of tracks format"), v2GroupBox); 0199 v2GroupBoxLayout->addWidget(m_totalNumTracksCheckBox, 0, 0, 1, 2); 0200 auto trackNumberDigitsLabel = new QLabel( 0201 tr("Track number &digits:"), v2GroupBox); 0202 m_trackNumberDigitsSpinBox = new QSpinBox(v2GroupBox); 0203 m_trackNumberDigitsSpinBox->setMaximum(5); 0204 m_genreNotNumericCheckBox = new QCheckBox( 0205 tr("&Genre as text instead of numeric string"), v2GroupBox); 0206 m_lowercaseId3ChunkCheckBox = new QCheckBox( 0207 tr("&WAV files with lowercase id3 chunk"), v2GroupBox); 0208 m_markStandardViolationsCheckBox = 0209 new QCheckBox(tr("Mar&k standard violations")); 0210 auto textEncodingLabel = new QLabel(tr("Text &encoding:"), v2GroupBox); 0211 m_textEncodingComboBox = new QComboBox(v2GroupBox); 0212 m_textEncodingComboBox->addItems(TagConfig::getTextEncodingNames()); 0213 m_textEncodingComboBox->setSizePolicy( 0214 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0215 textEncodingLabel->setBuddy(m_textEncodingComboBox); 0216 v2GroupBoxLayout->addWidget(m_genreNotNumericCheckBox, 1, 0, 1, 2); 0217 v2GroupBoxLayout->addWidget(m_lowercaseId3ChunkCheckBox, 2, 0, 1, 2); 0218 v2GroupBoxLayout->addWidget(m_markStandardViolationsCheckBox, 3, 0, 1, 2); 0219 v2GroupBoxLayout->addWidget(textEncodingLabel, 4, 0); 0220 v2GroupBoxLayout->addWidget(m_textEncodingComboBox, 4, 1); 0221 const TagConfig& tagCfg = TagConfig::instance(); 0222 if (!(tagCfg.taggedFileFeatures() & 0223 (TaggedFile::TF_ID3v22 | TaggedFile::TF_ID3v23 | TaggedFile::TF_ID3v24))) { 0224 m_genreNotNumericCheckBox->hide(); 0225 textEncodingLabel->hide(); 0226 m_textEncodingComboBox->hide(); 0227 } 0228 auto id3v2VersionLabel = new QLabel(tr("&Version used for new tags:"), 0229 v2GroupBox); 0230 m_id3v2VersionComboBox = new QComboBox(v2GroupBox); 0231 if (tagCfg.taggedFileFeatures() & TaggedFile::TF_ID3v23) 0232 m_id3v2VersionComboBox->addItem(tr("ID3v2.3.0"), TagConfig::ID3v2_3_0); 0233 if (tagCfg.taggedFileFeatures() & TaggedFile::TF_ID3v24) 0234 m_id3v2VersionComboBox->addItem(tr("ID3v2.4.0"), TagConfig::ID3v2_4_0); 0235 m_id3v2VersionComboBox->setSizePolicy( 0236 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0237 id3v2VersionLabel->setBuddy(m_id3v2VersionComboBox); 0238 v2GroupBoxLayout->addWidget(id3v2VersionLabel, 5, 0); 0239 v2GroupBoxLayout->addWidget(m_id3v2VersionComboBox, 5, 1); 0240 if (m_id3v2VersionComboBox->count() < 2) { 0241 id3v2VersionLabel->hide(); 0242 m_id3v2VersionComboBox->hide(); 0243 } 0244 trackNumberDigitsLabel->setBuddy(m_trackNumberDigitsSpinBox); 0245 v2GroupBoxLayout->addWidget(trackNumberDigitsLabel, 6, 0); 0246 v2GroupBoxLayout->addWidget(m_trackNumberDigitsSpinBox, 6, 1); 0247 tag2LeftLayout->addWidget(v2GroupBox); 0248 auto vorbisGroupBox = new QGroupBox(tr("Ogg/Vorbis"), tag2Page); 0249 auto commentNameLabel = new QLabel(tr("Co&mment field name:"), 0250 vorbisGroupBox); 0251 m_commentNameComboBox = new QComboBox(vorbisGroupBox); 0252 auto pictureNameLabel = new QLabel(tr("&Picture field name:"), 0253 vorbisGroupBox); 0254 m_pictureNameComboBox = new QComboBox(vorbisGroupBox); 0255 m_commentNameComboBox->setEditable(true); 0256 m_commentNameComboBox->addItems(TagConfig::getCommentNames()); 0257 m_commentNameComboBox->setSizePolicy( 0258 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0259 commentNameLabel->setBuddy(m_commentNameComboBox); 0260 m_pictureNameComboBox->addItems(TagConfig::getPictureNames()); 0261 m_pictureNameComboBox->setSizePolicy( 0262 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0263 pictureNameLabel->setBuddy(m_pictureNameComboBox); 0264 auto vorbisGroupBoxLayout = new QGridLayout(vorbisGroupBox); 0265 vorbisGroupBoxLayout->addWidget(commentNameLabel, 0, 0); 0266 vorbisGroupBoxLayout->addWidget(m_commentNameComboBox, 0, 1); 0267 vorbisGroupBoxLayout->addWidget(pictureNameLabel, 1, 0); 0268 vorbisGroupBoxLayout->addWidget(m_pictureNameComboBox, 1, 1); 0269 vorbisGroupBox->setLayout(vorbisGroupBoxLayout); 0270 tag2LeftLayout->addWidget(vorbisGroupBox); 0271 if (!(tagCfg.taggedFileFeatures() & TaggedFile::TF_OggPictures)) { 0272 vorbisGroupBox->hide(); 0273 } 0274 auto pictureGroupBox = new QGroupBox(tr("Picture"), tag2Page); 0275 auto pictureGroupBoxLayout = new QHBoxLayout(pictureGroupBox); 0276 m_markOversizedPicturesCheckBox = 0277 new QCheckBox(tr("Mark if &larger than (bytes):")); 0278 m_maximumPictureSizeSpinBox = new QSpinBox; 0279 m_maximumPictureSizeSpinBox->setRange(0, INT_MAX); 0280 pictureGroupBoxLayout->addWidget(m_markOversizedPicturesCheckBox); 0281 pictureGroupBoxLayout->addWidget(m_maximumPictureSizeSpinBox); 0282 tag2LeftLayout->addWidget(pictureGroupBox); 0283 tag2LeftLayout->addStretch(); 0284 tag2Layout->addLayout(tag2LeftLayout); 0285 0286 auto tag2RightLayout = new QVBoxLayout; 0287 auto tag2RightToolBox = new QToolBox; 0288 0289 auto genresWidget = new QWidget; 0290 m_onlyCustomGenresCheckBox = new QCheckBox(tr("&Show only custom genres"), 0291 genresWidget); 0292 m_genresEditModel = new QStringListModel(genresWidget); 0293 auto genresEdit = new StringListEdit(m_genresEditModel, genresWidget); 0294 auto vbox = new QVBoxLayout; 0295 vbox->addWidget(m_onlyCustomGenresCheckBox); 0296 vbox->addWidget(genresEdit); 0297 genresWidget->setLayout(vbox); 0298 tag2RightToolBox->addItem(genresWidget, tr("Cu&stom Genres")); 0299 0300 auto customFramesWidget = new QWidget; 0301 m_customFramesEditModel = new QStringListModel(customFramesWidget); 0302 connect(m_customFramesEditModel, &QStringListModel::dataChanged, 0303 this, &ConfigDialogPages::onCustomFramesEditModelChanged); 0304 connect(m_customFramesEditModel, &QStringListModel::rowsRemoved, 0305 this, &ConfigDialogPages::onCustomFramesEditModelChanged); 0306 auto customFramesEdit = new StringListEdit(m_customFramesEditModel, customFramesWidget); 0307 auto customFramesVBox = new QVBoxLayout; 0308 customFramesVBox->addWidget(customFramesEdit); 0309 customFramesWidget->setLayout(customFramesVBox); 0310 tag2RightToolBox->addItem(customFramesWidget, tr("Custom F&rames")); 0311 0312 auto quickAccessWidget = new QWidget; 0313 auto quickAccessTagsLayout = new QVBoxLayout(quickAccessWidget); 0314 auto quickAccessTagsListView = new QListView; 0315 m_quickAccessTagsModel = new QStandardItemModel(quickAccessWidget); 0316 quickAccessTagsListView->setModel(m_quickAccessTagsModel); 0317 quickAccessTagsListView->setAcceptDrops(true); 0318 quickAccessTagsListView->setDragEnabled(true); 0319 quickAccessTagsListView->setDragDropMode(QAbstractItemView::InternalMove); 0320 quickAccessTagsListView->setDragDropOverwriteMode(false); 0321 quickAccessTagsListView->setDefaultDropAction(Qt::MoveAction); 0322 quickAccessTagsListView->setDropIndicatorShown(true); 0323 quickAccessTagsLayout->addWidget(quickAccessTagsListView); 0324 auto reorderLabel = 0325 new QLabel(tr("Use drag and drop to reorder the items")); 0326 reorderLabel->setWordWrap(true); 0327 quickAccessTagsLayout->addWidget(reorderLabel); 0328 tag2RightToolBox->addItem(quickAccessWidget, tr("&Quick Access Frames")); 0329 tag2RightToolBox->setCurrentWidget(quickAccessWidget); 0330 tag2RightLayout->addWidget(tag2RightToolBox); 0331 tag2Layout->addLayout(tag2RightLayout); 0332 0333 auto tag3Page = new QWidget; 0334 auto tag3Layout = new QVBoxLayout(tag3Page); 0335 auto riffGroupBox = new QGroupBox(tr("RIFF INFO"), tag3Page); 0336 auto trackNameLabel = new QLabel(tr("Track nu&mber field name:"), 0337 riffGroupBox); 0338 m_trackNameComboBox = new QComboBox(riffGroupBox); 0339 m_trackNameComboBox->setEditable(true); 0340 m_trackNameComboBox->addItems(TagConfig::getRiffTrackNames()); 0341 m_trackNameComboBox->setSizePolicy( 0342 QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); 0343 trackNameLabel->setBuddy(m_trackNameComboBox); 0344 auto riffGroupBoxLayout = new QGridLayout(riffGroupBox); 0345 riffGroupBoxLayout->addWidget(trackNameLabel, 0, 0); 0346 riffGroupBoxLayout->addWidget(m_trackNameComboBox, 0, 1); 0347 riffGroupBox->setLayout(riffGroupBoxLayout); 0348 tag3Layout->addWidget(riffGroupBox); 0349 tag3Layout->addStretch(); 0350 0351 auto tag1AndTag2Page = new QWidget; 0352 auto tag1AndTag2Layout = new QVBoxLayout(tag1AndTag2Page); 0353 QString tagFormatTitle(tr("&Tag Format")); 0354 m_tagFormatBox = new TagFormatBox(tagFormatTitle, tag1AndTag2Page); 0355 auto ratingGroupBox = new QGroupBox(tr("Rating"), tag1AndTag2Page); 0356 auto ratingLayout = new QVBoxLayout(ratingGroupBox); 0357 m_starRatingMappingsModel = new StarRatingMappingsModel(ratingGroupBox); 0358 auto ratingEdit = new TableModelEdit(m_starRatingMappingsModel); 0359 ratingLayout->addWidget(ratingEdit); 0360 tag1AndTag2Layout->addWidget(m_tagFormatBox); 0361 tag1AndTag2Layout->addWidget(ratingGroupBox); 0362 0363 auto tagsTabWidget = new QTabWidget; 0364 if (tagCfg.taggedFileFeatures() & TaggedFile::TF_ID3v11) { 0365 tagsTabWidget->addTab(tag1Page, tr("Tag &1")); 0366 } 0367 tagsTabWidget->addTab(tag2Page, tr("Tag &2")); 0368 tagsTabWidget->addTab(tag3Page, tr("Tag &3")); 0369 tagsTabWidget->addTab(tag1AndTag2Page, tr("All Ta&gs")); 0370 tagsTabWidget->setCurrentIndex(1); 0371 vlayout->addWidget(tagsTabWidget); 0372 return tagsPage; 0373 } 0374 0375 /** 0376 * Create page with files settings. 0377 * @return files page. 0378 */ 0379 QWidget* ConfigDialogPages::createFilesPage() 0380 { 0381 auto filesPage = new QWidget; 0382 auto vlayout = new QVBoxLayout(filesPage); 0383 auto hlayout = new QHBoxLayout; 0384 auto leftLayout = new QVBoxLayout; 0385 auto rightLayout = new QVBoxLayout; 0386 0387 auto startupGroupBox = new QGroupBox(tr("Startup"), filesPage); 0388 m_loadLastOpenedFileCheckBox = new QCheckBox(tr("&Load last-opened files"), 0389 startupGroupBox); 0390 auto startupLayout = new QVBoxLayout; 0391 startupLayout->addWidget(m_loadLastOpenedFileCheckBox); 0392 startupGroupBox->setLayout(startupLayout); 0393 leftLayout->addWidget(startupGroupBox); 0394 auto saveGroupBox = new QGroupBox(tr("Save"), filesPage); 0395 m_preserveTimeCheckBox = new QCheckBox(tr("&Preserve file timestamp"), 0396 saveGroupBox); 0397 m_markChangesCheckBox = new QCheckBox(tr("&Mark changes"), saveGroupBox); 0398 m_coverFileNameLineEdit = new QLineEdit(saveGroupBox); 0399 m_fileTextEncodingComboBox = new QComboBox(saveGroupBox); 0400 m_fileTextEncodingComboBox->addItems(FileConfig::getTextCodecNames()); 0401 m_fileTextEncodingComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, 0402 QSizePolicy::Minimum)); 0403 auto formLayout = new QFormLayout; 0404 formLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); 0405 formLayout->addRow(m_preserveTimeCheckBox); 0406 formLayout->addRow(m_markChangesCheckBox); 0407 formLayout->addRow(tr("F&ilename for cover:"), m_coverFileNameLineEdit); 0408 formLayout->addRow(tr("Text &encoding (Export, Playlist):"), 0409 m_fileTextEncodingComboBox); 0410 saveGroupBox->setLayout(formLayout); 0411 leftLayout->addWidget(saveGroupBox); 0412 0413 auto fileListGroupBox = new QGroupBox(tr("File List"), filesPage); 0414 auto nameFilterLabel = new QLabel(tr("Filte&r:"), fileListGroupBox); 0415 m_nameFilterComboBox = new QComboBox(fileListGroupBox); 0416 m_nameFilterComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, 0417 QSizePolicy::Minimum)); 0418 QList<QPair<QString, QString> > filters = FileProxyModel::createNameFilters(); 0419 for (auto it = filters.constBegin(); it != filters.constEnd(); ++it) { 0420 QString nameFilter = m_platformTools->fileDialogNameFilter({*it}); 0421 m_nameFilterComboBox->addItem(it->first, nameFilter); 0422 } 0423 nameFilterLabel->setBuddy(m_nameFilterComboBox); 0424 auto includeFoldersLabel = new QLabel(tr("Inclu&de folders:"), 0425 fileListGroupBox); 0426 m_includeFoldersLineEdit = new QLineEdit(fileListGroupBox); 0427 includeFoldersLabel->setBuddy(m_includeFoldersLineEdit); 0428 auto excludeFoldersLabel = new QLabel(tr("E&xclude folders:"), 0429 fileListGroupBox); 0430 m_excludeFoldersLineEdit = new QLineEdit(fileListGroupBox); 0431 excludeFoldersLabel->setBuddy(m_excludeFoldersLineEdit); 0432 m_showHiddenFilesCheckBox = new QCheckBox(tr("&Show hidden files"), 0433 fileListGroupBox); 0434 auto fileListGroupBoxLayout = new QGridLayout(fileListGroupBox); 0435 fileListGroupBoxLayout->addWidget(nameFilterLabel, 0, 0); 0436 fileListGroupBoxLayout->addWidget(m_nameFilterComboBox, 0, 1); 0437 fileListGroupBoxLayout->addWidget(includeFoldersLabel, 1, 0); 0438 fileListGroupBoxLayout->addWidget(m_includeFoldersLineEdit, 1, 1); 0439 fileListGroupBoxLayout->addWidget(excludeFoldersLabel, 2, 0); 0440 fileListGroupBoxLayout->addWidget(m_excludeFoldersLineEdit, 2, 1); 0441 fileListGroupBoxLayout->addWidget(m_showHiddenFilesCheckBox, 3, 0, 1, 2); 0442 rightLayout->addWidget(fileListGroupBox); 0443 0444 auto formatGroupBox = new QGroupBox(tr("Format"), filesPage); 0445 auto formatLayout = new QVBoxLayout(formatGroupBox); 0446 auto filenameTagFormatLayout = new QHBoxLayout; 0447 auto editFormatsFromTagButton = 0448 new QPushButton(tr("Filename from tag") + QLatin1String("...")); 0449 connect(editFormatsFromTagButton, &QPushButton::clicked, 0450 this, &ConfigDialogPages::editFormatsFromTag); 0451 filenameTagFormatLayout->addWidget(editFormatsFromTagButton); 0452 auto editFormatsToTagButton = 0453 new QPushButton(tr("Tag from filename") + QLatin1String("...")); 0454 connect(editFormatsToTagButton, &QPushButton::clicked, 0455 this, &ConfigDialogPages::editFormatsToTag); 0456 filenameTagFormatLayout->addWidget(editFormatsToTagButton); 0457 formatLayout->addLayout(filenameTagFormatLayout); 0458 auto editPlaylistFormatsButton = 0459 new QPushButton(tr("Playlist") + QLatin1String("...")); 0460 connect(editPlaylistFormatsButton, &QPushButton::clicked, 0461 this, &ConfigDialogPages::editPlaylistFormats); 0462 formatLayout->addWidget(editPlaylistFormatsButton); 0463 rightLayout->addWidget(formatGroupBox); 0464 0465 rightLayout->addStretch(); 0466 0467 hlayout->addLayout(leftLayout); 0468 hlayout->addLayout(rightLayout); 0469 vlayout->addLayout(hlayout); 0470 0471 QString fnFormatTitle(tr("&Filename Format")); 0472 m_fnFormatBox = new FilenameFormatBox(fnFormatTitle, filesPage); 0473 vlayout->addWidget(m_fnFormatBox, 1); 0474 return filesPage; 0475 } 0476 0477 /** 0478 * Open dialog to edit "Filename from tag" formats. 0479 */ 0480 void ConfigDialogPages::editFormatsFromTag() 0481 { 0482 QWidget* parentWindow = nullptr; 0483 if (auto button = qobject_cast<QPushButton*>(sender())) { 0484 parentWindow = button->window(); 0485 } 0486 if (StringListEditDialog dialog( 0487 m_toFilenameFormats, tr("Filename from Tag"), parentWindow); 0488 dialog.exec() == QDialog::Accepted) { 0489 m_toFilenameFormats = dialog.stringList(); 0490 } 0491 } 0492 0493 /** 0494 * Open dialog to edit "Filename to tag" formats. 0495 */ 0496 void ConfigDialogPages::editFormatsToTag() 0497 { 0498 QWidget* parentWindow = nullptr; 0499 if (auto button = qobject_cast<QPushButton*>(sender())) { 0500 parentWindow = button->window(); 0501 } 0502 if (StringListEditDialog dialog( 0503 m_fromFilenameFormats, tr("Tag from Filename"), parentWindow); 0504 dialog.exec() == QDialog::Accepted) { 0505 m_fromFilenameFormats = dialog.stringList(); 0506 } 0507 } 0508 0509 /** 0510 * Open dialog to edit playlist file name formats. 0511 */ 0512 void ConfigDialogPages::editPlaylistFormats() 0513 { 0514 QWidget* parentWindow = nullptr; 0515 if (auto button = qobject_cast<QPushButton*>(sender())) { 0516 parentWindow = button->window(); 0517 } 0518 if (StringListEditDialog dialog( 0519 m_playlistFileNameFormats, tr("Playlist"), parentWindow); 0520 dialog.exec() == QDialog::Accepted) { 0521 m_playlistFileNameFormats = dialog.stringList(); 0522 } 0523 } 0524 0525 /** 0526 * Create page with actions settings. 0527 * @return actions page. 0528 */ 0529 QWidget* ConfigDialogPages::createActionsPage() 0530 { 0531 auto actionsPage = new QWidget; 0532 auto vlayout = new QVBoxLayout(actionsPage); 0533 auto browserGroupBox = new QGroupBox(tr("Browser"), actionsPage); 0534 auto browserLabel = new QLabel(tr("Web &browser:"), browserGroupBox); 0535 m_browserLineEdit = new QLineEdit(browserGroupBox); 0536 browserLabel->setBuddy(m_browserLineEdit); 0537 auto hbox = new QHBoxLayout; 0538 hbox->addWidget(browserLabel); 0539 hbox->addWidget(m_browserLineEdit); 0540 browserGroupBox->setLayout(hbox); 0541 vlayout->addWidget(browserGroupBox); 0542 0543 auto commandsGroupBox = new QGroupBox(tr("Context &Menu Commands"), 0544 actionsPage); 0545 m_playOnDoubleClickCheckBox = 0546 new QCheckBox(tr("&Play on double click"), commandsGroupBox); 0547 m_selectFileOnPlayCheckBox = 0548 new QCheckBox(tr("&Select file on play"), commandsGroupBox); 0549 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0550 auto audioOutputLayout = new QHBoxLayout; 0551 QLabel* audioOutputLabel = new QLabel(tr("A&udio output:"), commandsGroupBox); 0552 m_audioOutputComboBox = new QComboBox(commandsGroupBox); 0553 m_audioOutputComboBox->addItem(tr("System")); 0554 const auto audioOutputs = QMediaDevices::audioOutputs(); 0555 for (const auto& audioOutput : audioOutputs) { 0556 m_audioOutputComboBox->addItem(audioOutput.description(), audioOutput.id()); 0557 } 0558 audioOutputLabel->setBuddy(m_audioOutputComboBox); 0559 audioOutputLayout->addWidget(audioOutputLabel); 0560 audioOutputLayout->addWidget(m_audioOutputComboBox, 1); 0561 #endif 0562 m_commandsTableModel = new CommandsTableModel(commandsGroupBox); 0563 m_commandsTable = new ConfigTable(m_commandsTableModel, commandsGroupBox); 0564 m_commandsTable->setHorizontalResizeModes( 0565 m_commandsTableModel->getHorizontalResizeModes()); 0566 auto commandsLayout = new QVBoxLayout; 0567 commandsLayout->addWidget(m_playOnDoubleClickCheckBox); 0568 commandsLayout->addWidget(m_selectFileOnPlayCheckBox); 0569 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0570 commandsLayout->addLayout(audioOutputLayout); 0571 #endif 0572 commandsLayout->addWidget(m_commandsTable); 0573 commandsGroupBox->setLayout(commandsLayout); 0574 vlayout->addWidget(commandsGroupBox); 0575 return actionsPage; 0576 } 0577 0578 /** 0579 * Create page with network settings. 0580 * @return network page. 0581 */ 0582 QWidget* ConfigDialogPages::createNetworkPage() 0583 { 0584 auto networkPage = new QWidget; 0585 auto vlayout = new QVBoxLayout(networkPage); 0586 auto proxyGroupBox = new QGroupBox(tr("Proxy"), networkPage); 0587 m_proxyCheckBox = new QCheckBox(tr("&Proxy:"), proxyGroupBox); 0588 m_proxyLineEdit = new QLineEdit(proxyGroupBox); 0589 m_proxyAuthenticationCheckBox = new QCheckBox( 0590 tr("&Use authentication with proxy"), proxyGroupBox); 0591 auto proxyUserNameLabel = 0592 new QLabel(tr("Proxy user &name:"), proxyGroupBox); 0593 m_proxyUserNameLineEdit = new QLineEdit(proxyGroupBox); 0594 proxyUserNameLabel->setBuddy(m_proxyUserNameLineEdit); 0595 auto proxyPasswordLabel = 0596 new QLabel(tr("Proxy pass&word:"), proxyGroupBox); 0597 m_proxyPasswordLineEdit = new QLineEdit(proxyGroupBox); 0598 proxyPasswordLabel->setBuddy(m_proxyPasswordLineEdit); 0599 m_proxyPasswordLineEdit->setEchoMode(QLineEdit::Password); 0600 auto vbox = new QVBoxLayout; 0601 auto proxyHbox = new QHBoxLayout; 0602 proxyHbox->addWidget(m_proxyCheckBox); 0603 proxyHbox->addWidget(m_proxyLineEdit); 0604 vbox->addLayout(proxyHbox); 0605 vbox->addWidget(m_proxyAuthenticationCheckBox); 0606 auto authLayout = new QGridLayout; 0607 authLayout->addWidget(proxyUserNameLabel, 0, 0); 0608 authLayout->addWidget(m_proxyUserNameLineEdit, 0, 1); 0609 authLayout->addWidget(proxyPasswordLabel, 1, 0); 0610 authLayout->addWidget(m_proxyPasswordLineEdit, 1, 1); 0611 vbox->addLayout(authLayout); 0612 proxyGroupBox->setLayout(vbox); 0613 vlayout->addWidget(proxyGroupBox); 0614 0615 auto vspacer = new QSpacerItem(0, 0, 0616 QSizePolicy::Minimum, QSizePolicy::Expanding); 0617 vlayout->addItem(vspacer); 0618 return networkPage; 0619 } 0620 0621 /** 0622 * Create page with plugins settings. 0623 * @return plugins page. 0624 */ 0625 QWidget* ConfigDialogPages::createPluginsPage() 0626 { 0627 auto pluginsPage = new QWidget; 0628 auto vlayout = new QVBoxLayout(pluginsPage); 0629 auto metadataGroupBox = new QGroupBox( 0630 tr("&Metadata Plugins && Priority"), pluginsPage); 0631 0632 0633 auto metadataPluginsLayout = new QVBoxLayout(metadataGroupBox); 0634 m_enabledMetadataPluginsModel = 0635 new CheckableStringListModel(metadataGroupBox); 0636 auto metadataEdit = 0637 new StringListEdit(m_enabledMetadataPluginsModel, metadataGroupBox); 0638 metadataEdit->setEditingDisabled(true); 0639 metadataPluginsLayout->addWidget(metadataEdit); 0640 vlayout->addWidget(metadataGroupBox); 0641 0642 auto pluginsGroupBox = new QGroupBox(tr("A&vailable Plugins")); 0643 auto pluginsLayout = new QVBoxLayout(pluginsGroupBox); 0644 auto pluginsListView = new QListView; 0645 pluginsListView->setSelectionMode(QAbstractItemView::NoSelection); 0646 m_enabledPluginsModel = new CheckableStringListModel(pluginsGroupBox); 0647 pluginsListView->setModel(m_enabledPluginsModel); 0648 pluginsLayout->addWidget(pluginsListView); 0649 vlayout->addWidget(pluginsGroupBox); 0650 0651 vlayout->addStretch(); 0652 vlayout->addWidget( 0653 new QLabel(tr("Changes take only effect after a restart!"))); 0654 return pluginsPage; 0655 } 0656 0657 /** 0658 * Set values in pages from default configuration. 0659 */ 0660 void ConfigDialogPages::setDefaultConfig() 0661 { 0662 FilenameFormatConfig fnCfg; 0663 TagFormatConfig id3Cfg; 0664 TagConfig tagCfg; 0665 tagCfg.setAvailablePlugins(TagConfig::instance().availablePlugins()); 0666 tagCfg.setTaggedFileFeatures(TagConfig::instance().taggedFileFeatures()); 0667 tagCfg.setDefaultPluginOrder(); 0668 FileConfig fileCfg; 0669 UserActionsConfig userActionsCfg; 0670 userActionsCfg.setDefaultUserActions(); 0671 GuiConfig guiCfg; 0672 NetworkConfig networkCfg; 0673 networkCfg.setDefaultBrowser(); 0674 ImportConfig importCfg; 0675 importCfg.setAvailablePlugins(ImportConfig::instance().availablePlugins()); 0676 PlaylistConfig playlistCfg; 0677 setConfigs(fnCfg, id3Cfg, tagCfg, fileCfg, userActionsCfg, guiCfg, networkCfg, 0678 importCfg, playlistCfg); 0679 } 0680 0681 /** 0682 * Set values in dialog from current configuration. 0683 */ 0684 void ConfigDialogPages::setConfig() 0685 { 0686 const FormatConfig& fnCfg = FilenameFormatConfig::instance(); 0687 const FormatConfig& id3Cfg = TagFormatConfig::instance(); 0688 const TagConfig& tagCfg = TagConfig::instance(); 0689 const FileConfig& fileCfg = FileConfig::instance(); 0690 const UserActionsConfig& userActionsCfg = UserActionsConfig::instance(); 0691 const GuiConfig& guiCfg = GuiConfig::instance(); 0692 const NetworkConfig& networkCfg = NetworkConfig::instance(); 0693 const ImportConfig& importCfg = ImportConfig::instance(); 0694 const PlaylistConfig& playlistCfg = PlaylistConfig::instance(); 0695 setConfigs(fnCfg, id3Cfg, tagCfg, fileCfg, userActionsCfg, guiCfg, networkCfg, 0696 importCfg, playlistCfg); 0697 } 0698 0699 /** 0700 * Set values in dialog from given configurations. 0701 */ 0702 void ConfigDialogPages::setConfigs( 0703 const FormatConfig& fnCfg, const FormatConfig& id3Cfg, 0704 const TagConfig& tagCfg, const FileConfig& fileCfg, 0705 const UserActionsConfig& userActionsCfg, const GuiConfig& guiCfg, 0706 const NetworkConfig& networkCfg, const ImportConfig& importCfg, 0707 const PlaylistConfig& playlistCfg) 0708 { 0709 m_fnFormatBox->fromFormatConfig(fnCfg); 0710 m_tagFormatBox->fromFormatConfig(id3Cfg); 0711 m_markTruncationsCheckBox->setChecked(tagCfg.markTruncations()); 0712 m_totalNumTracksCheckBox->setChecked(tagCfg.enableTotalNumberOfTracks()); 0713 m_loadLastOpenedFileCheckBox->setChecked(fileCfg.loadLastOpenedFile()); 0714 m_preserveTimeCheckBox->setChecked(fileCfg.preserveTime()); 0715 m_markChangesCheckBox->setChecked(fileCfg.markChanges()); 0716 m_coverFileNameLineEdit->setText(fileCfg.defaultCoverFileName()); 0717 m_nameFilterComboBox->setCurrentIndex( 0718 m_nameFilterComboBox->findData(fileCfg.nameFilter())); 0719 m_includeFoldersLineEdit->setText( 0720 folderPatternListToString(fileCfg.includeFolders(), true)); 0721 m_excludeFoldersLineEdit->setText( 0722 folderPatternListToString(fileCfg.excludeFolders(), false)); 0723 m_showHiddenFilesCheckBox->setChecked(fileCfg.showHiddenFiles()); 0724 m_fileTextEncodingComboBox->setCurrentIndex(fileCfg.textEncodingIndex()); 0725 m_toFilenameFormats = fileCfg.toFilenameFormats(); 0726 m_fromFilenameFormats = fileCfg.fromFilenameFormats(); 0727 m_playlistFileNameFormats = playlistCfg.fileNameFormats(); 0728 m_onlyCustomGenresCheckBox->setChecked(tagCfg.onlyCustomGenres()); 0729 m_genresEditModel->setStringList(tagCfg.customGenres()); 0730 m_customFramesEditModel->setStringList( 0731 TagConfig::customFrameNamesToDisplayNames(tagCfg.customFrames())); 0732 m_starRatingMappingsModel->setMappings(tagCfg.starRatingMappings()); 0733 setQuickAccessFramesConfig(tagCfg.quickAccessFrameOrder(), tagCfg.quickAccessFrames()); 0734 m_commandsTableModel->setCommandList(userActionsCfg.contextMenuCommands()); 0735 int idx = m_commentNameComboBox->findText(tagCfg.commentName()); 0736 if (idx >= 0) { 0737 m_commentNameComboBox->setCurrentIndex(idx); 0738 } else { 0739 m_commentNameComboBox->addItem(tagCfg.commentName()); 0740 m_commentNameComboBox->setCurrentIndex(m_commentNameComboBox->count() - 1); 0741 } 0742 m_pictureNameComboBox->setCurrentIndex(tagCfg.pictureNameIndex()); 0743 m_genreNotNumericCheckBox->setChecked(tagCfg.genreNotNumeric()); 0744 m_lowercaseId3ChunkCheckBox->setChecked(tagCfg.lowercaseId3RiffChunk()); 0745 m_markStandardViolationsCheckBox->setChecked(tagCfg.markStandardViolations()); 0746 m_textEncodingV1ComboBox->setCurrentIndex(tagCfg.textEncodingV1Index()); 0747 m_textEncodingComboBox->setCurrentIndex(tagCfg.textEncoding()); 0748 m_id3v2VersionComboBox->setCurrentIndex( 0749 m_id3v2VersionComboBox->findData(tagCfg.id3v2Version())); 0750 m_trackNumberDigitsSpinBox->setValue(tagCfg.trackNumberDigits()); 0751 m_markOversizedPicturesCheckBox->setChecked(tagCfg.markOversizedPictures()); 0752 m_maximumPictureSizeSpinBox->setValue(tagCfg.maximumPictureSize()); 0753 idx = m_trackNameComboBox->findText(tagCfg.riffTrackName()); 0754 if (idx >= 0) { 0755 m_trackNameComboBox->setCurrentIndex(idx); 0756 } else { 0757 m_trackNameComboBox->addItem(tagCfg.riffTrackName()); 0758 m_trackNameComboBox->setCurrentIndex(m_trackNameComboBox->count() - 1); 0759 } 0760 m_browserLineEdit->setText(networkCfg.browser()); 0761 m_playOnDoubleClickCheckBox->setChecked(guiCfg.playOnDoubleClick()); 0762 m_selectFileOnPlayCheckBox->setChecked(guiCfg.selectFileOnPlayEnabled()); 0763 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0764 int audioOutputIndex = 0; 0765 QString text = guiCfg.preferredAudioOutput(); 0766 if (text.endsWith(QLatin1Char(']'))) { 0767 int idPos = text.lastIndexOf(QLatin1Char('[')); 0768 if (idPos != -1) { 0769 audioOutputIndex = m_audioOutputComboBox->findData( 0770 text.mid(idPos + 1, text.length() - idPos - 2).toLatin1()); 0771 if (audioOutputIndex == -1) { 0772 audioOutputIndex = 0; 0773 } 0774 } 0775 } 0776 m_audioOutputComboBox->setCurrentIndex(audioOutputIndex); 0777 #endif 0778 m_proxyCheckBox->setChecked(networkCfg.useProxy()); 0779 m_proxyLineEdit->setText(networkCfg.proxy()); 0780 m_proxyAuthenticationCheckBox->setChecked(networkCfg.useProxyAuthentication()); 0781 m_proxyUserNameLineEdit->setText(networkCfg.proxyUserName()); 0782 m_proxyPasswordLineEdit->setText(networkCfg.proxyPassword()); 0783 0784 QStringList metadataPlugins; 0785 if (QStringList pluginOrder = tagCfg.pluginOrder(); !pluginOrder.isEmpty()) { 0786 for (int i = 0; i < pluginOrder.size(); ++i) { 0787 metadataPlugins.append(QString()); // clazy:exclude=reserve-candidates 0788 } 0789 const auto pluginNames = tagCfg.availablePlugins(); 0790 for (const QString& pluginName : pluginNames) { 0791 if (int pluginIdx = pluginOrder.indexOf(pluginName); pluginIdx >= 0) { 0792 metadataPlugins[pluginIdx] = pluginName; 0793 } else { 0794 metadataPlugins.append(pluginName); // clazy:exclude=reserve-candidates 0795 } 0796 } 0797 metadataPlugins.removeAll(QString()); 0798 } else { 0799 metadataPlugins = tagCfg.availablePlugins(); 0800 } 0801 quint64 metadataPluginsMask = 0; 0802 quint64 mask = 1; 0803 QStringList disabledTagPlugins = tagCfg.disabledPlugins(); 0804 for (int i = 0; i < metadataPlugins.size(); ++i, mask <<= 1) { 0805 if (!disabledTagPlugins.contains(metadataPlugins.at(i))) { 0806 metadataPluginsMask |= mask; 0807 } 0808 } 0809 m_enabledMetadataPluginsModel->setStringList(metadataPlugins); 0810 m_enabledMetadataPluginsModel->setBitMask(metadataPluginsMask); 0811 0812 QStringList importPlugins = importCfg.availablePlugins(); 0813 quint64 importPluginsMask = 0; 0814 mask = 1; 0815 QStringList disabledPlugins = importCfg.disabledPlugins(); 0816 for (int i = 0; i < importPlugins.size(); ++i, mask <<= 1) { 0817 if (!disabledPlugins.contains(importPlugins.at(i))) { 0818 importPluginsMask |= mask; 0819 } 0820 } 0821 m_enabledPluginsModel->setStringList(importPlugins); 0822 m_enabledPluginsModel->setBitMask(importPluginsMask); 0823 0824 if (!guiCfg.configWindowGeometry().isEmpty()) { 0825 if (QWidget* configDialog = qobject_cast<QWidget*>(parent())) { 0826 configDialog->restoreGeometry(guiCfg.configWindowGeometry()); 0827 } 0828 } 0829 } 0830 0831 /** 0832 * Get values from dialog and store them in the current configuration. 0833 */ 0834 void ConfigDialogPages::getConfig() const 0835 { 0836 FormatConfig& fnCfg = FilenameFormatConfig::instance(); 0837 FormatConfig& id3Cfg = TagFormatConfig::instance(); 0838 TagConfig& tagCfg = TagConfig::instance(); 0839 FileConfig& fileCfg = FileConfig::instance(); 0840 UserActionsConfig& userActionsCfg = UserActionsConfig::instance(); 0841 GuiConfig& guiCfg = GuiConfig::instance(); 0842 NetworkConfig& networkCfg = NetworkConfig::instance(); 0843 ImportConfig& importCfg = ImportConfig::instance(); 0844 PlaylistConfig& playlistCfg = PlaylistConfig::instance(); 0845 0846 m_fnFormatBox->toFormatConfig(fnCfg); 0847 m_tagFormatBox->toFormatConfig(id3Cfg); 0848 tagCfg.setMarkTruncations(m_markTruncationsCheckBox->isChecked()); 0849 tagCfg.setEnableTotalNumberOfTracks(m_totalNumTracksCheckBox->isChecked()); 0850 fileCfg.setLoadLastOpenedFile(m_loadLastOpenedFileCheckBox->isChecked()); 0851 fileCfg.setPreserveTime(m_preserveTimeCheckBox->isChecked()); 0852 fileCfg.setMarkChanges(m_markChangesCheckBox->isChecked()); 0853 fileCfg.setDefaultCoverFileName(m_coverFileNameLineEdit->text()); 0854 fileCfg.setNameFilter(m_nameFilterComboBox->currentData().toString()); 0855 fileCfg.setIncludeFolders( 0856 folderPatternListFromString(m_includeFoldersLineEdit->text(), true)); 0857 fileCfg.setExcludeFolders( 0858 folderPatternListFromString(m_excludeFoldersLineEdit->text(), false)); 0859 fileCfg.setShowHiddenFiles(m_showHiddenFilesCheckBox->isChecked()); 0860 fileCfg.setTextEncodingIndex(m_fileTextEncodingComboBox->currentIndex()); 0861 fileCfg.setToFilenameFormats(m_toFilenameFormats); 0862 fileCfg.setFromFilenameFormats(m_fromFilenameFormats); 0863 playlistCfg.setFileNameFormats(m_playlistFileNameFormats); 0864 tagCfg.setOnlyCustomGenres(m_onlyCustomGenresCheckBox->isChecked()); 0865 tagCfg.setCustomGenres(m_genresEditModel->stringList()); 0866 tagCfg.setCustomFrames(TagConfig::customFrameNamesFromDisplayNames( 0867 m_customFramesEditModel->stringList())); 0868 tagCfg.setStarRatingMappings(m_starRatingMappingsModel->getMappings()); 0869 QList<int> frameTypes; 0870 quint64 frameMask = 0; 0871 getQuickAccessFramesConfig(frameTypes, frameMask); 0872 tagCfg.setQuickAccessFrames(frameMask); 0873 tagCfg.setQuickAccessFrameOrder(frameTypes); 0874 userActionsCfg.setContextMenuCommands(m_commandsTableModel->getCommandList()); 0875 tagCfg.setCommentName(m_commentNameComboBox->currentText()); 0876 tagCfg.setPictureNameIndex(m_pictureNameComboBox->currentIndex()); 0877 tagCfg.setGenreNotNumeric(m_genreNotNumericCheckBox->isChecked()); 0878 tagCfg.setLowercaseId3RiffChunk(m_lowercaseId3ChunkCheckBox->isChecked()); 0879 tagCfg.setMarkStandardViolations(m_markStandardViolationsCheckBox->isChecked()); 0880 tagCfg.setTextEncodingV1Index(m_textEncodingV1ComboBox->currentIndex()); 0881 tagCfg.setTextEncoding(m_textEncodingComboBox->currentIndex()); 0882 tagCfg.setId3v2Version(m_id3v2VersionComboBox->itemData( 0883 m_id3v2VersionComboBox->currentIndex()).toInt()); 0884 tagCfg.setTrackNumberDigits(m_trackNumberDigitsSpinBox->value()); 0885 tagCfg.setMarkOversizedPictures(m_markOversizedPicturesCheckBox->isChecked()); 0886 tagCfg.setMaximumPictureSize(m_maximumPictureSizeSpinBox->value()); 0887 tagCfg.setRiffTrackName(m_trackNameComboBox->currentText()); 0888 networkCfg.setBrowser(m_browserLineEdit->text()); 0889 guiCfg.setPlayOnDoubleClick(m_playOnDoubleClickCheckBox->isChecked()); 0890 guiCfg.setSelectFileOnPlayEnabled(m_selectFileOnPlayCheckBox->isChecked()); 0891 #if defined HAVE_QTMULTIMEDIA && QT_VERSION >= 0x060200 0892 guiCfg.setPreferredAudioOutput(m_audioOutputComboBox->currentData().isNull() 0893 ? QString() 0894 : m_audioOutputComboBox->currentText() + QLatin1String(" [") + 0895 QLatin1String(m_audioOutputComboBox->currentData().toByteArray()) + 0896 QLatin1Char(']')); 0897 #endif 0898 networkCfg.setUseProxy(m_proxyCheckBox->isChecked()); 0899 networkCfg.setProxy(m_proxyLineEdit->text()); 0900 networkCfg.setUseProxyAuthentication(m_proxyAuthenticationCheckBox->isChecked()); 0901 networkCfg.setProxyUserName(m_proxyUserNameLineEdit->text()); 0902 networkCfg.setProxyPassword(m_proxyPasswordLineEdit->text()); 0903 0904 QStringList pluginOrder, disabledPlugins; 0905 const int numPlugins = m_enabledMetadataPluginsModel->rowCount(); 0906 pluginOrder.reserve(numPlugins); 0907 for (int row = 0; row < numPlugins; ++row) { 0908 QString pluginName = 0909 m_enabledMetadataPluginsModel->index(row).data().toString(); 0910 pluginOrder.append(pluginName); 0911 if (m_enabledMetadataPluginsModel->index(row).data(Qt::CheckStateRole) 0912 .toInt() != Qt::Checked) { 0913 disabledPlugins.append(pluginName); // clazy:exclude=reserve-candidates 0914 } 0915 } 0916 tagCfg.setPluginOrder(pluginOrder); 0917 tagCfg.setDisabledPlugins(disabledPlugins); 0918 0919 disabledPlugins.clear(); 0920 for (int row = 0; row < m_enabledPluginsModel->rowCount(); ++row) { 0921 if (m_enabledPluginsModel->index(row).data(Qt::CheckStateRole) 0922 .toInt() != Qt::Checked) { 0923 disabledPlugins.append( 0924 m_enabledPluginsModel->index(row).data().toString()); 0925 } 0926 } 0927 importCfg.setDisabledPlugins(disabledPlugins); 0928 0929 if (QWidget* configDialog = qobject_cast<QWidget*>(parent())) { 0930 guiCfg.setConfigWindowGeometry(configDialog->saveGeometry()); 0931 } 0932 } 0933 0934 void ConfigDialogPages::onCustomFramesEditModelChanged() 0935 { 0936 QList<int> frameTypes; 0937 quint64 frameMask = 0; 0938 getQuickAccessFramesConfig(frameTypes, frameMask); 0939 setQuickAccessFramesConfig(frameTypes, frameMask); 0940 } 0941 0942 void ConfigDialogPages::getQuickAccessFramesConfig(QList<int>& frameTypes, 0943 quint64& frameMask) const 0944 { 0945 const int numQuickAccessTags = m_quickAccessTagsModel->rowCount(); 0946 QVariantList namesSelected; 0947 namesSelected.reserve(numQuickAccessTags); 0948 for (int row = 0; row < numQuickAccessTags; ++row) { 0949 QModelIndex index = m_quickAccessTagsModel->index(row, 0); 0950 auto name = index.data().toString(); 0951 auto frameType = index.data(Qt::UserRole).toInt(); 0952 auto selected = m_quickAccessTagsModel->data( 0953 index, Qt::CheckStateRole).toInt() == Qt::Checked; 0954 namesSelected.append( 0955 QVariantMap{{QLatin1String("name"), name}, 0956 {QLatin1String("type"), frameType}, 0957 {QLatin1String("selected"), selected}}); 0958 } 0959 TagConfig::setQuickAccessFrameSelection(namesSelected, frameTypes, frameMask); 0960 } 0961 0962 void ConfigDialogPages::setQuickAccessFramesConfig(const QList<int>& types, 0963 quint64 frameMask) 0964 { 0965 const QVariantList namesSelected = TagConfig::getQuickAccessFrameSelection( 0966 types, frameMask, m_customFramesEditModel->stringList()); 0967 m_quickAccessTagsModel->clear(); 0968 for (const QVariant& var : namesSelected) { 0969 auto map = var.toMap(); 0970 auto name = map.value(QLatin1String("name")).toString(); 0971 auto frameType = map.value(QLatin1String("type")).toInt(); 0972 auto selected = map.value(QLatin1String("selected")).toBool(); 0973 auto item = new QStandardItem(name); 0974 item->setData(frameType, Qt::UserRole); 0975 item->setCheckable(true); 0976 item->setCheckState(selected ? Qt::Checked : Qt::Unchecked); 0977 item->setDropEnabled(false); 0978 m_quickAccessTagsModel->appendRow(item); 0979 } 0980 }