File indexing completed on 2025-02-23 04:34:18
0001 /** 0002 * \file rendirdialog.cpp 0003 * Rename directory dialog. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 21 Mar 2004 0008 * 0009 * Copyright (C) 2004-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 "rendirdialog.h" 0028 #include <QLayout> 0029 #include <QPushButton> 0030 #include <QComboBox> 0031 #include <QLabel> 0032 #include <QDir> 0033 #include <QApplication> 0034 #include <QTextEdit> 0035 #include <QCursor> 0036 #include <QVBoxLayout> 0037 #include <QFormLayout> 0038 #include "taggedfile.h" 0039 #include "frame.h" 0040 #include "trackdata.h" 0041 #include "contexthelp.h" 0042 #include "rendirconfig.h" 0043 #include "dirrenamer.h" 0044 #include "stringlisteditdialog.h" 0045 0046 /** 0047 * Constructor. 0048 * 0049 * @param parent parent widget 0050 * @param dirRenamer directory renamer 0051 */ 0052 RenDirDialog::RenDirDialog(QWidget* parent, DirRenamer* dirRenamer) 0053 : QWizard(parent), m_taggedFile(nullptr), m_dirRenamer(dirRenamer) 0054 { 0055 setObjectName(QLatin1String("RenDirDialog")); 0056 setModal(true); 0057 setWindowTitle(tr("Rename Folder")); 0058 setSizeGripEnabled(true); 0059 #ifdef Q_OS_WIN32 0060 // The default on Windows with Qt 6.5.1 has a strange looking black rectangle 0061 // with a left arrow at the top left of the wizard dialog. 0062 setWizardStyle(ModernStyle); 0063 #endif 0064 0065 auto mainPage = new QWizardPage; 0066 0067 auto mainLayout = new QVBoxLayout(mainPage); 0068 setupMainPage(mainPage, mainLayout); 0069 mainPage->setTitle(tr("Format")); 0070 addPage(mainPage); 0071 0072 auto previewPage = new QWizardPage; 0073 setupPreviewPage(previewPage); 0074 previewPage->setTitle(tr("Preview")); 0075 addPage(previewPage); 0076 0077 setOptions(HaveHelpButton | HaveCustomButton1); 0078 setButtonText(CustomButton1, tr("&Save Settings")); 0079 connect(this, &QWizard::helpRequested, this, &RenDirDialog::showHelp); 0080 connect(this, &QWizard::customButtonClicked, this, &RenDirDialog::saveConfig); 0081 connect(this, &QWizard::currentIdChanged, this, &RenDirDialog::pageChanged); 0082 } 0083 0084 /** 0085 * Set up the main wizard page. 0086 * 0087 * @param page widget 0088 * @param vlayout layout 0089 */ 0090 void RenDirDialog::setupMainPage(QWidget* page, QVBoxLayout* vlayout) 0091 { 0092 if (!page || !vlayout) { 0093 return; 0094 } 0095 0096 auto actionLayout = new QFormLayout; 0097 actionLayout->setFieldGrowthPolicy(QFormLayout::AllNonFixedFieldsGrow); 0098 m_actionComboBox = new QComboBox(page); 0099 m_tagversionComboBox = new QComboBox(page); 0100 m_actionComboBox->insertItem(ActionRename, tr("Rename Folder")); 0101 m_actionComboBox->insertItem(ActionCreate, tr("Create Folder")); 0102 actionLayout->addRow(tr("&Action:"), m_actionComboBox); 0103 connect(m_actionComboBox, static_cast<void (QComboBox::*)(int)>( 0104 &QComboBox::activated), this, &RenDirDialog::slotUpdateNewDirname); 0105 const QList<QPair<Frame::TagVersion, QString> > tagVersions = 0106 Frame::availableTagVersions(); 0107 for (auto it = tagVersions.constBegin(); it != tagVersions.constEnd(); ++it) { 0108 m_tagversionComboBox->addItem(it->second, it->first); 0109 } 0110 actionLayout->addRow(tr("&Source:"), m_tagversionComboBox); 0111 connect(m_tagversionComboBox, static_cast<void (QComboBox::*)(int)>( 0112 &QComboBox::activated), this, &RenDirDialog::slotUpdateNewDirname); 0113 0114 auto formatLayout = new QHBoxLayout; 0115 m_formatComboBox = new QComboBox(page); 0116 m_formatComboBox->setEditable(true); 0117 const RenDirConfig& renDirCfg = RenDirConfig::instance(); 0118 m_formats = renDirCfg.dirFormats(); 0119 m_format = renDirCfg.dirFormat(); 0120 setFormats(); 0121 formatLayout->addWidget(m_formatComboBox, 1); 0122 auto editFormatsButton = new QPushButton(tr("&Edit...")); 0123 connect(editFormatsButton, &QPushButton::clicked, 0124 this, &RenDirDialog::editFormats); 0125 formatLayout->addWidget(editFormatsButton); 0126 auto formatLabel = new QLabel(tr("&Format:")); 0127 formatLabel->setBuddy(m_formatComboBox); 0128 actionLayout->addRow(formatLabel, formatLayout); 0129 m_tagversionComboBox->setCurrentIndex( 0130 m_tagversionComboBox->findData(renDirCfg.renDirSource())); 0131 connect(m_formatComboBox, static_cast<void (QComboBox::*)(int)>( 0132 &QComboBox::activated), this, &RenDirDialog::slotUpdateNewDirname); 0133 connect(m_formatComboBox, &QComboBox::editTextChanged, 0134 this, &RenDirDialog::slotUpdateNewDirname); 0135 0136 m_currentDirLabel = new QLabel(page); 0137 m_newDirLabel = new QLabel(page); 0138 actionLayout->addRow(tr("From:"), m_currentDirLabel); 0139 actionLayout->addRow(tr("To:"), m_newDirLabel); 0140 0141 vlayout->addLayout(actionLayout); 0142 0143 if (QByteArray geometry = renDirCfg.windowGeometry(); !geometry.isEmpty()) { 0144 restoreGeometry(geometry); 0145 } 0146 } 0147 0148 /** 0149 * Set up the preview wizard page. 0150 * 0151 * @param page widget 0152 */ 0153 void RenDirDialog::setupPreviewPage(QWidget* page) 0154 { 0155 auto vlayout = new QVBoxLayout(page); 0156 m_edit = new QTextEdit(page); 0157 m_edit->setReadOnly(true); 0158 m_edit->setAcceptRichText(false); 0159 vlayout->addWidget(m_edit); 0160 } 0161 0162 /** 0163 * Start dialog. 0164 * 0165 * @param taggedFile file to use for rename preview 0166 * @param dirName if taggedFile is 0, the directory can be set here 0167 */ 0168 void RenDirDialog::startDialog(TaggedFile* taggedFile, const QString& dirName) 0169 { 0170 m_taggedFile = taggedFile; 0171 if (m_taggedFile) { 0172 slotUpdateNewDirname(); 0173 } else { 0174 m_currentDirLabel->setText(dirName); 0175 m_newDirLabel->clear(); 0176 } 0177 restart(); 0178 } 0179 0180 /** 0181 * Set new directory name. 0182 * 0183 * @param dir new directory name 0184 */ 0185 void RenDirDialog::setNewDirname(const QString& dir) 0186 { 0187 m_newDirLabel->setText(dir); 0188 } 0189 0190 /** 0191 * Get new directory name. 0192 * 0193 * @return new directory name. 0194 */ 0195 QString RenDirDialog::getNewDirname() const 0196 { 0197 return m_newDirLabel->text(); 0198 } 0199 0200 /** 0201 * Set configuration from dialog in directory renamer. 0202 */ 0203 void RenDirDialog::setDirRenamerConfiguration() { 0204 m_dirRenamer->setTagVersion(Frame::tagVersionCast( 0205 m_tagversionComboBox->itemData(m_tagversionComboBox->currentIndex()).toInt())); 0206 m_dirRenamer->setAction(m_actionComboBox->currentIndex() == ActionCreate); 0207 m_format = m_formatComboBox->currentText(); 0208 m_dirRenamer->setFormat(m_format); 0209 } 0210 0211 /** 0212 * Set new directory name according to current settings. 0213 */ 0214 void RenDirDialog::slotUpdateNewDirname() 0215 { 0216 if (m_taggedFile) { 0217 setDirRenamerConfiguration(); 0218 QString currentDirname; 0219 QString newDirname(m_dirRenamer->generateNewDirname(m_taggedFile, 0220 ¤tDirname)); 0221 m_currentDirLabel->setText(currentDirname); 0222 setNewDirname(newDirname); 0223 } 0224 } 0225 0226 /** 0227 * Save the local settings to the configuration. 0228 */ 0229 void RenDirDialog::saveConfig() 0230 { 0231 RenDirConfig& renDirCfg = RenDirConfig::instance(); 0232 m_format = m_formatComboBox->currentText(); 0233 setFormats(); 0234 renDirCfg.setDirFormats(m_formats); 0235 renDirCfg.setDirFormat(m_format); 0236 renDirCfg.setRenDirSource(Frame::tagVersionCast( 0237 m_tagversionComboBox->itemData(m_tagversionComboBox->currentIndex()).toInt())); 0238 QByteArray geometry = saveGeometry(); 0239 renDirCfg.setWindowGeometry(geometry); 0240 restoreGeometry(geometry); // Keep geometry when dialog is reopened 0241 } 0242 0243 /** 0244 * Show help. 0245 */ 0246 void RenDirDialog::showHelp() 0247 { 0248 ContextHelp::displayHelp(QLatin1String("rename-directory")); 0249 } 0250 0251 /** 0252 * Request action scheduling and then accept dialog. 0253 */ 0254 void RenDirDialog::requestActionSchedulingAndAccept() 0255 { 0256 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor)); 0257 setDirRenamerConfiguration(); 0258 emit actionSchedulingRequested(); 0259 QApplication::restoreOverrideCursor(); 0260 accept(); 0261 } 0262 0263 /** 0264 * Clear action preview. 0265 */ 0266 void RenDirDialog::clearPreview() 0267 { 0268 if (m_edit) { 0269 m_edit->clear(); 0270 m_edit->setLineWrapMode(QTextEdit::NoWrap); 0271 } 0272 } 0273 0274 /** 0275 * Display action preview. 0276 * 0277 * @param actionStrs description of action 0278 */ 0279 void RenDirDialog::displayActionPreview(const QStringList& actionStrs) 0280 { 0281 QString str = actionStrs.at(0); 0282 #if QT_VERSION >= 0x050b00 0283 int width = fontMetrics().horizontalAdvance(str) + 8; 0284 #else 0285 int width = fontMetrics().width(str) + 8; 0286 #endif 0287 #if QT_VERSION >= 0x050a00 0288 if (m_edit->tabStopDistance() < width) { 0289 m_edit->setTabStopDistance(width); 0290 } 0291 #else 0292 if (m_edit->tabStopWidth() < width) { 0293 m_edit->setTabStopWidth(width); 0294 } 0295 #endif 0296 if (actionStrs.size() > 1) { 0297 str += QLatin1Char('\t'); 0298 str += actionStrs.at(1); 0299 } 0300 if (actionStrs.size() > 2) { 0301 str += QLatin1String("\n\t"); 0302 str += actionStrs.at(2); 0303 } 0304 m_edit->append(str); 0305 } 0306 0307 /** 0308 * Wizard page changed. 0309 */ 0310 void RenDirDialog::pageChanged() 0311 { 0312 if (currentId() == 1) { 0313 clearPreview(); 0314 setDirRenamerConfiguration(); 0315 emit actionSchedulingRequested(); 0316 } 0317 } 0318 0319 /** 0320 * Open dialog to edit formats. 0321 */ 0322 void RenDirDialog::editFormats() 0323 { 0324 setFormats(); 0325 if (StringListEditDialog dialog(m_formats, tr("Folder Name from Tag"), this); 0326 dialog.exec() == QDialog::Accepted) { 0327 m_formats = dialog.stringList(); 0328 setFormats(); 0329 } 0330 } 0331 0332 /** 0333 * Set items of format combo box from configuration. 0334 */ 0335 void RenDirDialog::setFormats() 0336 { 0337 int idx = m_formats.indexOf(m_format); 0338 if (idx == -1) { 0339 m_formats.append(m_format); 0340 idx = m_formats.size() - 1; 0341 } 0342 m_formatComboBox->blockSignals(true); 0343 if (!m_formats.isEmpty()) { 0344 m_formatComboBox->clear(); 0345 m_formatComboBox->addItems(m_formats); 0346 } 0347 m_formatComboBox->setCurrentIndex(idx); 0348 m_formatComboBox->blockSignals(false); 0349 } 0350 0351 /** 0352 * Called when the wizard is canceled. 0353 */ 0354 void RenDirDialog::reject() 0355 { 0356 m_dirRenamer->abort(); 0357 QWizard::reject(); 0358 }