Git commit 4e31b66e3ebe3177156b2548a14f740e0bd29810 by Urs Fleisch. Committed on 09/07/2022 at 08:56. Pushed by ufleisch into branch 'master'.
Allow playlist file name formats to be edited The playlist file name formats can be edited from the settings "Files/Format/Playlist..." and can then be used in the "Format" combobox of the "Create Playlist" dialog. BUG 450402 M +8 -0 doc/en/index.docbook M +42 -1 src/core/config/playlistconfig.cpp M +14 -0 src/core/config/playlistconfig.h M +36 -6 src/gui/dialogs/configdialogpages.cpp M +6 -1 src/gui/dialogs/configdialogpages.h M +2 -7 src/gui/dialogs/playlistdialog.cpp https://invent.kde.org/multimedia/kid3/commit/4e31b66e3ebe3177156b2548a14f740e0bd29810 diff --git a/doc/en/index.docbook b/doc/en/index.docbook index 6c94e9b0..ca874030 100644 --- a/doc/en/index.docbook +++ b/doc/en/index.docbook @@ -1612,6 +1612,9 @@ or use a <guibutton>Format</guibutton> with values from the tags, <abbrev>e.g.</ "<userinput>%{artist} - %{album}</userinput>" to have the artist and album name in the playlist file name. The format codes are the same as for <link linkend="export">Export</link>. +The list of available formats can be edited in the <guilabel>Format</guilabel> +section of the <guilabel>Files</guilabel> tab in the +<link linkend="configure-kid3">settings</link>. <guibutton>Create new empty playlist</guibutton> will make an empty playlist with the given name. The extension depends on the playlist format. @@ -2458,6 +2461,11 @@ boxes (with arrows up and down), which can be found in the <link linkend="file">File</link> section of the main window. </para> <para> +The <guibutton>Playlist</guibutton> button can be used to edit the file name +formats available in the <link linkend="create-playlist">Create Playlist</link> +dialog. +</para> +<para> <guilabel>Filename Format</guilabel> contains options for the format of the filenames. The same options as in <guilabel>Tag Format</guilabel> are available. </para> diff --git a/src/core/config/playlistconfig.cpp b/src/core/config/playlistconfig.cpp index 65bccce2..a83d8b3d 100644 --- a/src/core/config/playlistconfig.cpp +++ b/src/core/config/playlistconfig.cpp @@ -30,19 +30,34 @@ int PlaylistConfig::s_index = -1; +namespace { + +/** Default file name format list */ +const char* defaultFileNameFormats[] = { + "%{artist} - %{album}", + R"(%{artist} - %{"["year"] "}%{album})", + "%{album}", + "playlist_%{artist}_-_%{album}", + "playlist", + nullptr +}; + +} + /** * Constructor. */ PlaylistConfig::PlaylistConfig() : StoredConfig<PlaylistConfig>(QLatin1String("Playlist")), m_location(PL_CurrentDirectory), m_format(PF_M3U), - m_fileNameFormat(QLatin1String("%{artist} - %{album}")), + m_fileNameFormat(QLatin1String(defaultFileNameFormats[0])), m_sortTagField(QLatin1String("%{track.3}")), m_infoFormat(QLatin1String("%{artist} - %{title}")), m_useFileNameFormat(false), m_onlySelectedFiles(false), m_useSortTagField(false), m_useFullPath(false), m_writeInfo(false) { + initFormatListsIfEmpty(); } /** @@ -54,6 +69,7 @@ PlaylistConfig::PlaylistConfig(const PlaylistConfig& other) m_location(other.m_location), m_format(other.m_format), m_fileNameFormat(other.m_fileNameFormat), + m_fileNameFormatItems(other.m_fileNameFormatItems), m_sortTagField(other.m_sortTagField), m_infoFormat(other.m_infoFormat), m_useFileNameFormat(other.m_useFileNameFormat), @@ -75,6 +91,7 @@ PlaylistConfig& PlaylistConfig::operator=(const PlaylistConfig& other) m_location = other.m_location; m_format = other.m_format; m_fileNameFormat = other.m_fileNameFormat; + m_fileNameFormatItems = other.m_fileNameFormatItems; m_sortTagField = other.m_sortTagField; m_infoFormat = other.m_infoFormat; m_useFileNameFormat = other.m_useFileNameFormat; @@ -107,6 +124,7 @@ void PlaylistConfig::writeToConfig(ISettings* config) const config->setValue(QLatin1String("Format"), QVariant(static_cast<int>(m_format))); config->setValue(QLatin1String("FileNameFormat"), QVariant(m_fileNameFormat)); + config->setValue(QLatin1String("FileNameFormatItems"), QVariant(m_fileNameFormatItems)); config->setValue(QLatin1String("SortTagField"), QVariant(m_sortTagField)); config->setValue(QLatin1String("InfoFormat"), QVariant(m_infoFormat)); config->endGroup(); @@ -139,6 +157,8 @@ void PlaylistConfig::readFromConfig(ISettings* config) static_cast<int>(m_format)).toInt()); m_fileNameFormat = config->value(QLatin1String("FileNameFormat"), m_fileNameFormat).toString(); + m_fileNameFormatItems = config->value(QLatin1String("FileNameFormatItems"), + m_fileNameFormatItems).toStringList(); m_sortTagField = config->value(QLatin1String("SortTagField"), m_sortTagField).toString(); m_infoFormat = config->value(QLatin1String("InfoFormat"), @@ -148,8 +168,20 @@ void PlaylistConfig::readFromConfig(ISettings* config) m_windowGeometry = config->value(QLatin1String("WindowGeometry"), m_windowGeometry).toByteArray(); config->endGroup(); + + initFormatListsIfEmpty(); +} + +void PlaylistConfig::initFormatListsIfEmpty() +{ + if (m_fileNameFormatItems.size() <= 1) { + for (const char** sl = defaultFileNameFormats; *sl != nullptr; ++sl) { + m_fileNameFormatItems += QString::fromLatin1(*sl); + } + } } + void PlaylistConfig::setLocation(PlaylistLocation location) { if (m_location != location) { @@ -174,6 +206,15 @@ void PlaylistConfig::setFileNameFormat(const QString& fileNameFormat) } } +void PlaylistConfig::setFileNameFormats(const QStringList& fileNameFormatItems) +{ + if (m_fileNameFormatItems != fileNameFormatItems) { + m_fileNameFormatItems = fileNameFormatItems; + m_fileNameFormatItems.removeDuplicates(); + emit fileNameFormatsChanged(m_fileNameFormatItems); + } +} + void PlaylistConfig::setSortTagField(const QString& sortTagField) { if (m_sortTagField != sortTagField) { diff --git a/src/core/config/playlistconfig.h b/src/core/config/playlistconfig.h index d1c81b89..5eaf5fb2 100644 --- a/src/core/config/playlistconfig.h +++ b/src/core/config/playlistconfig.h @@ -143,6 +143,14 @@ public: /** Set playlist file name format. */ void setFileNameFormat(const QString& fileNameFormat); + /** Get playlist file name formats. */ + QStringList fileNameFormats() const { + return m_fileNameFormatItems; + } + + /** Set playlist file name formats. */ + void setFileNameFormats(const QStringList& fileNameFormatItems); + /** Get tag field used for sorting. */ QString sortTagField() const { return m_sortTagField; } @@ -222,6 +230,9 @@ signals: /** Emitted when @a fileNameFormat changed. */ void fileNameFormatChanged(const QString& fileNameFormat); + /** Emitted when @a fileNameFormats changed. */ + void fileNameFormatsChanged(const QStringList& fileNameFormats); + /** Emitted when @a sortTagField changed. */ void sortTagFieldChanged(const QString& sortTagField); @@ -249,6 +260,8 @@ signals: private: friend PlaylistConfig& StoredConfig<PlaylistConfig>::instance(); + void initFormatListsIfEmpty(); + void setLocationInt(int location) { setLocation(static_cast<PlaylistLocation>(location)); } @@ -260,6 +273,7 @@ private: PlaylistLocation m_location; PlaylistFormat m_format; QString m_fileNameFormat; + QStringList m_fileNameFormatItems; QString m_sortTagField; QString m_infoFormat; QByteArray m_windowGeometry; diff --git a/src/gui/dialogs/configdialogpages.cpp b/src/gui/dialogs/configdialogpages.cpp index 9c18e0c9..d0339213 100644 --- a/src/gui/dialogs/configdialogpages.cpp +++ b/src/gui/dialogs/configdialogpages.cpp @@ -52,6 +52,7 @@ #include "guiconfig.h" #include "networkconfig.h" #include "importconfig.h" +#include "playlistconfig.h" #include "stringlistedit.h" #include "stringlisteditdialog.h" #include "configtable.h" @@ -435,17 +436,24 @@ QWidget* ConfigDialogPages::createFilesPage() rightLayout->addWidget(fileListGroupBox); auto formatGroupBox = new QGroupBox(tr("Format"), filesPage); - auto formatLayout = new QHBoxLayout(formatGroupBox); + auto formatLayout = new QVBoxLayout(formatGroupBox); + auto filenameTagFormatLayout = new QHBoxLayout; auto editFormatsFromTagButton = new QPushButton(tr("Filename from tag") + QLatin1String("...")); connect(editFormatsFromTagButton, &QPushButton::clicked, this, &ConfigDialogPages::editFormatsFromTag); - formatLayout->addWidget(editFormatsFromTagButton); + filenameTagFormatLayout->addWidget(editFormatsFromTagButton); auto editFormatsToTagButton = new QPushButton(tr("Tag from filename") + QLatin1String("...")); connect(editFormatsToTagButton, &QPushButton::clicked, this, &ConfigDialogPages::editFormatsToTag); - formatLayout->addWidget(editFormatsToTagButton); + filenameTagFormatLayout->addWidget(editFormatsToTagButton); + formatLayout->addLayout(filenameTagFormatLayout); + auto editPlaylistFormatsButton = + new QPushButton(tr("Playlist") + QLatin1String("...")); + connect(editPlaylistFormatsButton, &QPushButton::clicked, + this, &ConfigDialogPages::editPlaylistFormats); + formatLayout->addWidget(editPlaylistFormatsButton); rightLayout->addWidget(formatGroupBox); rightLayout->addStretch(); @@ -492,6 +500,22 @@ void ConfigDialogPages::editFormatsToTag() } } +/** + * Open dialog to edit playlist file name formats. + */ +void ConfigDialogPages::editPlaylistFormats() +{ + QWidget* parentWindow = nullptr; + if (auto button = qobject_cast<QPushButton*>(sender())) { + parentWindow = button->window(); + } + StringListEditDialog dialog( + m_playlistFileNameFormats, tr("Playlist"), parentWindow); + if (dialog.exec() == QDialog::Accepted) { + m_playlistFileNameFormats = dialog.stringList(); + } +} + /** * Create page with actions settings. * @return actions page. @@ -624,8 +648,9 @@ void ConfigDialogPages::setDefaultConfig() networkCfg.setDefaultBrowser(); ImportConfig importCfg; importCfg.setAvailablePlugins(ImportConfig::instance().availablePlugins()); + PlaylistConfig playlistCfg; setConfigs(fnCfg, id3Cfg, tagCfg, fileCfg, userActionsCfg, guiCfg, networkCfg, - importCfg); + importCfg, playlistCfg); } /** @@ -641,8 +666,9 @@ void ConfigDialogPages::setConfig() const GuiConfig& guiCfg = GuiConfig::instance(); const NetworkConfig& networkCfg = NetworkConfig::instance(); const ImportConfig& importCfg = ImportConfig::instance(); + const PlaylistConfig& playlistCfg = PlaylistConfig::instance(); setConfigs(fnCfg, id3Cfg, tagCfg, fileCfg, userActionsCfg, guiCfg, networkCfg, - importCfg); + importCfg, playlistCfg); } /** @@ -652,7 +678,8 @@ void ConfigDialogPages::setConfigs( const FormatConfig& fnCfg, const FormatConfig& id3Cfg, const TagConfig& tagCfg, const FileConfig& fileCfg, const UserActionsConfig& userActionsCfg, const GuiConfig& guiCfg, - const NetworkConfig& networkCfg, const ImportConfig& importCfg) + const NetworkConfig& networkCfg, const ImportConfig& importCfg, + const PlaylistConfig& playlistCfg) { m_fnFormatBox->fromFormatConfig(fnCfg); m_tagFormatBox->fromFormatConfig(id3Cfg); @@ -672,6 +699,7 @@ void ConfigDialogPages::setConfigs( m_fileTextEncodingComboBox->setCurrentIndex(fileCfg.textEncodingIndex()); m_toFilenameFormats = fileCfg.toFilenameFormats(); m_fromFilenameFormats = fileCfg.fromFilenameFormats(); + m_playlistFileNameFormats = playlistCfg.fileNameFormats(); m_onlyCustomGenresCheckBox->setChecked(tagCfg.onlyCustomGenres()); m_genresEditModel->setStringList(tagCfg.customGenres()); m_customFramesEditModel->setStringList( @@ -774,6 +802,7 @@ void ConfigDialogPages::getConfig() const GuiConfig& guiCfg = GuiConfig::instance(); NetworkConfig& networkCfg = NetworkConfig::instance(); ImportConfig& importCfg = ImportConfig::instance(); + PlaylistConfig& playlistCfg = PlaylistConfig::instance(); m_fnFormatBox->toFormatConfig(fnCfg); m_tagFormatBox->toFormatConfig(id3Cfg); @@ -792,6 +821,7 @@ void ConfigDialogPages::getConfig() const fileCfg.setTextEncodingIndex(m_fileTextEncodingComboBox->currentIndex()); fileCfg.setToFilenameFormats(m_toFilenameFormats); fileCfg.setFromFilenameFormats(m_fromFilenameFormats); + playlistCfg.setFileNameFormats(m_playlistFileNameFormats); tagCfg.setOnlyCustomGenres(m_onlyCustomGenresCheckBox->isChecked()); tagCfg.setCustomGenres(m_genresEditModel->stringList()); tagCfg.setCustomFrames(TagConfig::customFrameNamesFromDisplayNames( diff --git a/src/gui/dialogs/configdialogpages.h b/src/gui/dialogs/configdialogpages.h index 0926bd5f..21549b52 100644 --- a/src/gui/dialogs/configdialogpages.h +++ b/src/gui/dialogs/configdialogpages.h @@ -49,6 +49,7 @@ class UserActionsConfig; class GuiConfig; class NetworkConfig; class ImportConfig; +class PlaylistConfig; class IPlatformTools; /** @@ -116,6 +117,7 @@ public slots: private slots: void editFormatsFromTag(); void editFormatsToTag(); + void editPlaylistFormats(); void onCustomFramesEditModelChanged(); private: @@ -126,7 +128,8 @@ private: const FormatConfig& fnCfg, const FormatConfig& id3Cfg, const TagConfig& tagCfg, const FileConfig& fileCfg, const UserActionsConfig& userActionsCfg, const GuiConfig& guiCfg, - const NetworkConfig& networkCfg, const ImportConfig& importCfg); + const NetworkConfig& networkCfg, const ImportConfig& importCfg, + const PlaylistConfig& playlistCfg); void getQuickAccessFramesConfig(QList<int>& frameTypes, quint64& frameMask) const; @@ -220,4 +223,6 @@ private: QStringList m_toFilenameFormats; /** Available formats for tag from filename */ QStringList m_fromFilenameFormats; + /** Available playlist file name formats */ + QStringList m_playlistFileNameFormats; }; diff --git a/src/gui/dialogs/playlistdialog.cpp b/src/gui/dialogs/playlistdialog.cpp index 81e22dc2..88d8ff88 100644 --- a/src/gui/dialogs/playlistdialog.cpp +++ b/src/gui/dialogs/playlistdialog.cpp @@ -147,13 +147,6 @@ PlaylistDialog::PlaylistDialog(QWidget* parent) m_fileNameFormatButton->setText(tr("&Format:")); m_fileNameFormatComboBox->setEditable(true); m_fileNameFormatComboBox->setEnabled(false); - m_fileNameFormatComboBox->addItems({ - QLatin1String("%{artist} - %{album}"), - QLatin1String(R"(%{artist} - %{"["year"] "}%{album})"), - QLatin1String("%{album}"), - QLatin1String("playlist_%{artist}_-_%{album}"), - QLatin1String("playlist") - }); connect(m_fileNameFormatButton, &QAbstractButton::toggled, m_fileNameFormatComboBox, &QWidget::setEnabled); m_fileNameForEmptyButton->setText(tr("Create ne&w empty playlist:")); @@ -252,6 +245,8 @@ void PlaylistDialog::readConfig() m_writeListButton->setChecked(!playlistCfg.writeInfo()); m_locationComboBox->setCurrentIndex(playlistCfg.location()); m_formatComboBox->setCurrentIndex(playlistCfg.format()); + m_fileNameFormatComboBox->clear(); + m_fileNameFormatComboBox->addItems(playlistCfg.fileNameFormats()); m_fileNameFormatComboBox->setEditText( playlistCfg.fileNameFormat()); m_sortTagFieldComboBox->setEditText(playlistCfg.sortTagField());
