File indexing completed on 2025-02-23 04:34:18
0001 /** 0002 * \file playlistdialog.cpp 0003 * Create playlist dialog. 0004 * 0005 * \b Project: Kid3 0006 * \author Urs Fleisch 0007 * \date 13 Sep 2009 0008 * 0009 * Copyright (C) 2009-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 "playlistdialog.h" 0028 #include <QLayout> 0029 #include <QPushButton> 0030 #include <QLabel> 0031 #include <QString> 0032 #include <QCheckBox> 0033 #include <QComboBox> 0034 #include <QLineEdit> 0035 #include <QRadioButton> 0036 #include <QButtonGroup> 0037 #include <QFrame> 0038 #include <QToolTip> 0039 #include <QVBoxLayout> 0040 #include <QHBoxLayout> 0041 #include <QGroupBox> 0042 #include "playlistconfig.h" 0043 #include "contexthelp.h" 0044 #include "trackdata.h" 0045 0046 /** 0047 * Constructor. 0048 * 0049 * @param parent parent widget 0050 */ 0051 PlaylistDialog::PlaylistDialog(QWidget* parent) 0052 : QDialog(parent) 0053 { 0054 setObjectName(QLatin1String("PlaylistDialog")); 0055 setModal(true); 0056 setWindowTitle(tr("Create Playlist")); 0057 setSizeGripEnabled(true); 0058 0059 auto vlayout = new QVBoxLayout(this); 0060 auto fnGroupBox = new QGroupBox(this); 0061 auto fnGroupBoxLayout = new QVBoxLayout(fnGroupBox); 0062 m_sameAsDirNameButton = new QRadioButton(this); 0063 fnGroupBoxLayout->addWidget(m_sameAsDirNameButton); 0064 auto fileNameFormatLayout = new QHBoxLayout; 0065 m_fileNameFormatButton = new QRadioButton(this); 0066 m_fileNameFormatComboBox = new QComboBox(this); 0067 m_fileNameFormatComboBox->setToolTip(TrackDataFormatReplacer::getToolTip()); 0068 fileNameFormatLayout->addWidget(m_fileNameFormatButton); 0069 fileNameFormatLayout->addWidget(m_fileNameFormatComboBox); 0070 fnGroupBoxLayout->addLayout(fileNameFormatLayout); 0071 0072 auto fileNameForEmptyLayout = new QHBoxLayout; 0073 m_fileNameForEmptyButton = new QRadioButton(this); 0074 m_fileNameForEmptyEdit = new QLineEdit(this); 0075 fileNameForEmptyLayout->addWidget(m_fileNameForEmptyButton); 0076 fileNameForEmptyLayout->addWidget(m_fileNameForEmptyEdit); 0077 fnGroupBoxLayout->addLayout(fileNameForEmptyLayout); 0078 0079 auto locationLayout = new QHBoxLayout; 0080 auto locationLabel = new QLabel(this); 0081 m_locationComboBox = new QComboBox(this); 0082 locationLayout->addWidget(locationLabel); 0083 locationLayout->addWidget(m_locationComboBox); 0084 fnGroupBoxLayout->addLayout(locationLayout); 0085 vlayout->addWidget(fnGroupBox); 0086 0087 auto pcGroupBox = new QGroupBox(this); 0088 auto pcGroupBoxLayout = new QVBoxLayout(pcGroupBox); 0089 auto formatLayout = new QHBoxLayout; 0090 auto formatLabel = new QLabel(this); 0091 m_formatComboBox = new QComboBox(this); 0092 formatLayout->addWidget(formatLabel); 0093 formatLayout->addWidget(m_formatComboBox); 0094 pcGroupBoxLayout->addLayout(formatLayout); 0095 m_onlySelectedFilesCheckBox = new QCheckBox(this); 0096 pcGroupBoxLayout->addWidget(m_onlySelectedFilesCheckBox); 0097 0098 auto sortLine = new QFrame(pcGroupBox); 0099 sortLine->setFrameShape(QFrame::HLine); 0100 sortLine->setFrameShadow(QFrame::Sunken); 0101 pcGroupBoxLayout->addWidget(sortLine); 0102 auto sortButtonGroup = new QButtonGroup(pcGroupBox); 0103 m_sortFileNameButton = new QRadioButton(this); 0104 pcGroupBoxLayout->addWidget(m_sortFileNameButton); 0105 auto sortTagFieldLayout = new QHBoxLayout; 0106 m_sortTagFieldButton = new QRadioButton(this); 0107 m_sortTagFieldComboBox = new QComboBox(this); 0108 m_sortTagFieldComboBox->setToolTip(TrackDataFormatReplacer::getToolTip()); 0109 sortTagFieldLayout->addWidget(m_sortTagFieldButton); 0110 sortTagFieldLayout->addWidget(m_sortTagFieldComboBox); 0111 pcGroupBoxLayout->addLayout(sortTagFieldLayout); 0112 sortButtonGroup->addButton(m_sortFileNameButton); 0113 sortButtonGroup->addButton(m_sortTagFieldButton); 0114 0115 auto pathLine = new QFrame(pcGroupBox); 0116 pathLine->setFrameShape(QFrame::HLine); 0117 pathLine->setFrameShadow(QFrame::Sunken); 0118 pcGroupBoxLayout->addWidget(pathLine); 0119 auto pathButtonGroup = new QButtonGroup(pcGroupBox); 0120 m_relPathButton = new QRadioButton(this); 0121 pcGroupBoxLayout->addWidget(m_relPathButton); 0122 m_fullPathButton = new QRadioButton(this); 0123 pcGroupBoxLayout->addWidget(m_fullPathButton); 0124 pathButtonGroup->addButton(m_relPathButton); 0125 pathButtonGroup->addButton(m_fullPathButton); 0126 0127 auto writeLine = new QFrame(pcGroupBox); 0128 writeLine->setFrameShape(QFrame::HLine); 0129 writeLine->setFrameShadow(QFrame::Sunken); 0130 pcGroupBoxLayout->addWidget(writeLine); 0131 auto writeButtonGroup = new QButtonGroup(pcGroupBox); 0132 m_writeListButton = new QRadioButton(this); 0133 pcGroupBoxLayout->addWidget(m_writeListButton); 0134 auto writeInfoLayout = new QHBoxLayout; 0135 m_writeInfoButton = new QRadioButton(this); 0136 m_writeInfoComboBox = new QComboBox(this); 0137 m_writeInfoComboBox->setToolTip(TrackDataFormatReplacer::getToolTip()); 0138 writeInfoLayout->addWidget(m_writeInfoButton); 0139 writeInfoLayout->addWidget(m_writeInfoComboBox); 0140 pcGroupBoxLayout->addLayout(writeInfoLayout); 0141 writeButtonGroup->addButton(m_writeListButton); 0142 writeButtonGroup->addButton(m_writeInfoButton); 0143 vlayout->addWidget(pcGroupBox); 0144 fnGroupBox->setTitle(tr("Playlist File Name")); 0145 m_sameAsDirNameButton->setText(tr("Same as &folder name")); 0146 m_sameAsDirNameButton->setChecked(true); 0147 m_fileNameFormatButton->setText(tr("&Format:")); 0148 m_fileNameFormatComboBox->setEditable(true); 0149 m_fileNameFormatComboBox->setEnabled(false); 0150 connect(m_fileNameFormatButton, &QAbstractButton::toggled, 0151 m_fileNameFormatComboBox, &QWidget::setEnabled); 0152 m_fileNameForEmptyButton->setText(tr("Create ne&w empty playlist:")); 0153 m_fileNameForEmptyEdit->setText(tr("New")); 0154 m_fileNameForEmptyEdit->setEnabled(false); 0155 // Position line edit aligned with combo box. 0156 m_fileNameForEmptyEdit->setSizePolicy(m_fileNameFormatComboBox->sizePolicy()); 0157 connect(m_fileNameForEmptyButton, &QAbstractButton::toggled, 0158 m_fileNameForEmptyEdit, &QWidget::setEnabled); 0159 locationLabel->setText(tr("Cr&eate in:")); 0160 locationLabel->setBuddy(m_locationComboBox); 0161 m_locationComboBox->addItems({ 0162 tr("Current folder"), 0163 tr("Every folder"), 0164 tr("Top-level folder") 0165 }); 0166 pcGroupBox->setTitle(tr("Playlist Content")); 0167 formatLabel->setText(tr("For&mat:")); 0168 formatLabel->setBuddy(m_formatComboBox); 0169 m_formatComboBox->addItems( 0170 {QLatin1String("M3U"), QLatin1String("PLS"), QLatin1String("XSPF")}); 0171 m_onlySelectedFilesCheckBox->setText(tr("Incl&ude only the selected files")); 0172 m_sortFileNameButton->setText(tr("Sort by file &name")); 0173 m_sortFileNameButton->setChecked(true); 0174 m_sortTagFieldButton->setText(tr("Sort by &tag field")); 0175 m_sortTagFieldComboBox->setEditable(true); 0176 m_sortTagFieldComboBox->setEnabled(false); 0177 QStringList lst; 0178 lst.reserve(Frame::FT_LastFrame - Frame::FT_FirstFrame + 1); 0179 for (int type = Frame::FT_FirstFrame; type <= Frame::FT_LastFrame; ++type) { 0180 QString frameName = 0181 Frame::ExtendedType(static_cast<Frame::Type>(type), QLatin1String("")) 0182 .getName().toLower(); 0183 if (frameName == QLatin1String("track number")) frameName = QLatin1String("track.3"); 0184 if (!frameName.isEmpty()) { 0185 lst.append(QLatin1String("%{") + frameName + QLatin1String("}")); 0186 } 0187 } 0188 m_sortTagFieldComboBox->addItems(lst); 0189 connect(m_sortTagFieldButton, &QAbstractButton::toggled, 0190 m_sortTagFieldComboBox, &QWidget::setEnabled); 0191 m_relPathButton->setText(tr("Use &relative path for files in playlist")); 0192 m_relPathButton->setChecked(true); 0193 m_fullPathButton->setText(tr("Use full p&ath for files in playlist")); 0194 m_writeListButton->setText(tr("Write only &list of files")); 0195 m_writeListButton->setChecked(true); 0196 m_writeInfoButton->setText(tr("Write &info using")); 0197 m_writeInfoComboBox->setEditable(true); 0198 m_writeInfoComboBox->setEnabled(false); 0199 m_writeInfoComboBox->addItems({ 0200 QLatin1String("%{artist} - %{title}"), QLatin1String("%{title}"), 0201 QLatin1String("%{track.1}/%{tracks} - %{artist} - %{album} - %{title}") 0202 }); 0203 connect(m_writeInfoButton, &QAbstractButton::toggled, 0204 m_writeInfoComboBox, &QWidget::setEnabled); 0205 0206 auto hlayout = new QHBoxLayout; 0207 auto helpButton = new QPushButton(tr("&Help"), this); 0208 helpButton->setAutoDefault(false); 0209 hlayout->addWidget(helpButton); 0210 connect(helpButton, &QAbstractButton::clicked, this, &PlaylistDialog::showHelp); 0211 auto saveButton = new QPushButton(tr("&Save Settings"), this); 0212 saveButton->setAutoDefault(false); 0213 hlayout->addWidget(saveButton); 0214 connect(saveButton, &QAbstractButton::clicked, this, &PlaylistDialog::saveConfig); 0215 auto hspacer = new QSpacerItem(16, 0, QSizePolicy::Expanding, 0216 QSizePolicy::Minimum); 0217 hlayout->addItem(hspacer); 0218 0219 auto okButton = new QPushButton(tr("&OK"), this); 0220 hlayout->addWidget(okButton); 0221 connect(okButton, &QAbstractButton::clicked, this, &QDialog::accept); 0222 auto cancelButton = new QPushButton(tr("&Cancel"), this); 0223 hlayout->addWidget(cancelButton); 0224 connect(cancelButton, &QAbstractButton::clicked, this, &QDialog::reject); 0225 vlayout->addLayout(hlayout); 0226 } 0227 0228 /** 0229 * Read the local settings from the configuration. 0230 */ 0231 void PlaylistDialog::readConfig() 0232 { 0233 const PlaylistConfig& playlistCfg = PlaylistConfig::instance(); 0234 m_fileNameFormatButton->setChecked( 0235 playlistCfg.useFileNameFormat()); 0236 m_sameAsDirNameButton->setChecked( 0237 !playlistCfg.useFileNameFormat()); 0238 m_onlySelectedFilesCheckBox->setChecked( 0239 playlistCfg.onlySelectedFiles()); 0240 m_sortTagFieldButton->setChecked(playlistCfg.useSortTagField()); 0241 m_sortFileNameButton->setChecked(!playlistCfg.useSortTagField()); 0242 m_fullPathButton->setChecked(playlistCfg.useFullPath()); 0243 m_relPathButton->setChecked(!playlistCfg.useFullPath()); 0244 m_writeInfoButton->setChecked(playlistCfg.writeInfo()); 0245 m_writeListButton->setChecked(!playlistCfg.writeInfo()); 0246 m_locationComboBox->setCurrentIndex(playlistCfg.location()); 0247 m_formatComboBox->setCurrentIndex(playlistCfg.format()); 0248 m_fileNameFormatComboBox->clear(); 0249 m_fileNameFormatComboBox->addItems(playlistCfg.fileNameFormats()); 0250 m_fileNameFormatComboBox->setEditText( 0251 playlistCfg.fileNameFormat()); 0252 m_sortTagFieldComboBox->setEditText(playlistCfg.sortTagField()); 0253 m_writeInfoComboBox->setEditText(playlistCfg.infoFormat()); 0254 0255 if (QByteArray geometry = playlistCfg.windowGeometry(); !geometry.isEmpty()) { 0256 restoreGeometry(geometry); 0257 } 0258 } 0259 0260 /** 0261 * Get the current dialog configuration. 0262 * 0263 * @param cfg the current configuration is returned here 0264 */ 0265 void PlaylistDialog::getCurrentConfig(PlaylistConfig& cfg) const 0266 { 0267 cfg.setUseFileNameFormat(m_fileNameFormatButton->isChecked()); 0268 cfg.setOnlySelectedFiles(m_onlySelectedFilesCheckBox->isChecked()); 0269 cfg.setUseSortTagField(m_sortTagFieldButton->isChecked()); 0270 cfg.setUseFullPath(m_fullPathButton->isChecked()); 0271 cfg.setWriteInfo(m_writeInfoButton->isChecked()); 0272 cfg.setLocation(static_cast<PlaylistConfig::PlaylistLocation>( 0273 m_locationComboBox->currentIndex())); 0274 cfg.setFormat(static_cast<PlaylistConfig::PlaylistFormat>( 0275 m_formatComboBox->currentIndex())); 0276 cfg.setFileNameFormat(m_fileNameFormatComboBox->currentText()); 0277 cfg.setSortTagField(m_sortTagFieldComboBox->currentText()); 0278 cfg.setInfoFormat(m_writeInfoComboBox->currentText()); 0279 QByteArray geometry = saveGeometry(); 0280 cfg.setWindowGeometry(geometry); 0281 } 0282 0283 /** 0284 * Get the entered file name to create a new empty playlist. 0285 * @return file name if "Create new empty playlist" is selected, else empty. 0286 */ 0287 QString PlaylistDialog::getFileNameForNewEmptyPlaylist() const 0288 { 0289 return m_fileNameForEmptyButton->isChecked() 0290 ? m_fileNameForEmptyEdit->text() : QString(); 0291 } 0292 0293 /** 0294 * Save the local settings to the configuration. 0295 */ 0296 void PlaylistDialog::saveConfig() const 0297 { 0298 getCurrentConfig(PlaylistConfig::instance()); 0299 } 0300 0301 /** 0302 * Show help. 0303 */ 0304 void PlaylistDialog::showHelp() 0305 { 0306 ContextHelp::displayHelp(QLatin1String("create-playlist")); 0307 }