Commit c572c396 authored by Urs Fleisch's avatar Urs Fleisch
Browse files

advanced playlist creation and dialog

parent 0bd6c59d
......@@ -25,7 +25,7 @@
</copyright>
<legalnotice id="fdl-notice">&FDLNotice;</legalnotice>
<date>2009-04-02</date>
<date>2009-09-23</date>
<releaseinfo>1.2</releaseinfo>
<abstract>
......@@ -843,18 +843,79 @@ wobei <guibutton>OK</guibutton> die aktuellen Einstellungen übernimmt.
</para></listitem>
</varlistentry>
<varlistentry>
<varlistentry id="create-playlist">
<term><menuchoice>
<guimenu>Datei</guimenu>
<guimenuitem>Stückliste erstellen</guimenuitem>
<guimenuitem>Stückliste erstellen...</guimenuitem>
</menuchoice></term>
<listitem><para><action>Erzeugt eine M3U Stückliste.</action> Die Datei wird im
geöffneten Verzeichnis gespeichert und trägt denselben Namen wie das
Verzeichnis, gefolgt von einer .m3u Erweiterung. Diese Datei enthält bloß
die Namen der im Dateilistenfeld angezeigten Dateien, keine speziellen
EXTM3U oder EXTINFO Zeilen werden generiert. Wenn alle Dateien eines Albums
in einem separaten Verzeichnis gespeichert werden, kann mit dieser Funktion
eine Stückliste für das Album erstellt werden.</para></listitem>
<listitem><para><action>Erzeugt eine Stückliste.</action> Das Format und der
Inhalt der Stückliste können mit verschiedenen Optionen bestimmt werden.
</para>
<para>
<guibutton>Wie Verzeichnisname</guibutton> generiert den Dateinamen der
Wiedergabeliste aus dem Namen des Verzeichnisses. Es kann aber auch ein
<guibutton>Format</guibutton> mit Werten aus den Tags benutzt werden,
z.B. "%{artist} - %{album}", um die Namen von Interpret und Album im
Dateinamen zu haben. Es können dieselben Format Codes wie bei
<link linkend="export">Exportieren</link> verwendet werden. Die
Dateierweiterung richtet sich nach dem Format der Stückliste.
</para>
<para>
Wo die Wiedergabeliste erstellt wird, kann bestimmt werden mit der
Auswahlliste <guilabel>Erstelle in</guilabel>
<variablelist>
<varlistentry><term>Aktuellem Verzeichnis</term>
<listitem><para>Die Stückliste wird im aktuellen Verzeichnis erstellt und
enthält nur Dateien aus diesem Verzeichnis.</para></listitem></varlistentry>
<varlistentry><term>Jedem Ordner</term>
<listitem><para>In jedem Verzeichnis, welches gelistete Dateien enthält, wird
eine eigene Stückliste erstellt, welche die Dateien aus dem jeweiligen
Verzeichnis enthält.
</para></listitem></varlistentry>
<varlistentry><term>Basisordner</term>
<listitem><para>Nur eine einzige Stückliste wird im Basisverzeichnis (d.h. dem
Verzeichnis der Dateiliste) erstellt, und sie enthält die gelisteten
Dateien aus dem Basisverzeichnis und allen Unterverzeichnissen.
</para></listitem></varlistentry>
</variablelist>
</para>
<para>
Das <guilabel>Format</guilabel> der Wiedergabeliste kann
<guilabel>M3U</guilabel>, <guilabel>PLS</guilabel> oder
<guilabel>XSPF</guilabel> sein.
</para>
<para>
<guibutton>Nur ausgewählte Dateien einfügen</guibutton> führt dazu, dass nur
ausgewählte Dateien in der Stückliste erscheinen. Wenn ein Verzeichnis
ausgewählt ist, so gelten all seine Dateien ebenfalls als selektiert.
Wenn diese Option nicht aktiviert ist, gelangen alle Audio-Dateien in die
Stückliste.
</para>
<para>
<guibutton>Sortiere nach Dateiname</guibutton> ordnet die Dateien wie üblich
nach dem Dateinamen in der Wiedergabeliste an. Mit <guibutton>Sortiere nach
Tag-Feld</guibutton> ist es möglich, eine Format-Zeichenkette mit Tag-Werten
für die Sortierung zu verwenden. "%{track.3}" kann beispielsweise benutzt
werden, um nach der Tracknummer zu sortieren (".3" wird verwendet, um 3
Stellen mit führenden Nullen zu kriegen, und somit korrekt nach der Nummer zu
sortieren). Es ist auch möglich, mehrere Codes zu verwenden,
z.B. "%{genre}%{year}", um nach einer Zeichenkette aus Stil und Jahr zu
sortieren.
</para>
<para>
Die Einträge in der Stückliste sind relative oder absolute Pfadangaben, je
nachdem ob <guibutton>Benutze relativen Pfad für Dateien in der Wiedergabeliste</guibutton> oder
<guibutton>Benutze vollen Pfad für Dateien in der Wiedergabeliste</guibutton>
gesetzt ist.
</para>
<para>
<guibutton>Nur Liste der Dateien schreiben</guibutton> führt dazu, dass die
Stückliste nur die Pfade zu den Dateien enthält. Wünscht man zusätzliche
Informationen, so steht <guibutton>Schreibe Informationen mit</guibutton>
einer Format-Zeichenfolge zur Verfügung, und es wird eine erweiterte
Stückliste generiert.
</para>
</listitem>
</varlistentry>
<varlistentry>
......
......@@ -25,7 +25,7 @@
</copyright>
<legalnotice id="fdl-notice">&FDLNotice;</legalnotice>
<date>2009-04-02</date>
<date>2009-09-23</date>
<releaseinfo>1.2</releaseinfo>
<abstract>
......@@ -781,22 +781,77 @@ or <guilabel>ID3v2</guilabel>) can be selected with a combo
box. Pushing <guibutton>To File</guibutton> or
<guibutton>To Clipboard</guibutton> stores the data in a file or on the
clipboard. <guibutton>OK</guibutton> and <guibutton>Cancel</guibutton> close
the dialog, whereat <guibutton>OK</guibutton> accepts the current dialog
the dialog, whereas <guibutton>OK</guibutton> accepts the current dialog
settings.
</para></listitem>
</varlistentry>
<varlistentry>
<varlistentry id="create-playlist">
<term><menuchoice>
<guimenu>File</guimenu>
<guimenuitem>Create Playlist</guimenuitem>
</menuchoice></term>
<listitem><para><action>Creates an M3U playlist.</action> The file will be stored in
the opened directory and have the same name as the directory, followed by
an .m3u extension. The file simply contains the names of the files displayed
in the file listbox, no special EXTM3U or EXTINFO lines are generated.
If all files of an album are stored in a separate directory, this function
can be used to generate a playlist for an album.</para></listitem>
<listitem><para>
<action>Creates a playlist.</action> The format and contents of the playlist
can be set by various options.</para>
<para>
The name of the playlist can be the <guibutton>Same as directory
name</guibutton> or use a <guibutton>Format</guibutton> with values
from the tags, e.g. "%{artist} - %{album}" 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 extension depends on the playlist
format.
</para>
<para>
The location of the generated playlist is determined by the selection of
the <guilabel>Create in</guilabel> combo box.
<variablelist>
<varlistentry><term>Current directory</term>
<listitem><para>The playlist is created in the current directory and contains
only files of the current directory.</para></listitem></varlistentry>
<varlistentry><term>Every directory</term>
<listitem><para>A playlist is created in every directory which contains
listed files, and each playlist contains the files of that directory.
</para></listitem></varlistentry>
<varlistentry><term>Top-level directory</term>
<listitem><para>Only one playlist is created in the top-level
directory (i.e. the directory of the file list) and it contains the listed
files of the top-level directory and all of its sub-directories.
</para></listitem></varlistentry>
</variablelist>
</para>
<para>
The <guilabel>Format</guilabel> of the playlist can
be <guilabel>M3U</guilabel>, <guilabel>PLS</guilabel> or
<guilabel>XSPF</guilabel>.
</para>
<para>
If <guibutton>Include only the selected files</guibutton> is checked, only the
selected files will be included in the playlist. If a directory is selected,
all of its files are selected. If this check box is not activated, all audio
files are included in the playlist.
</para>
<para>
<guibutton>Sort by file name</guibutton> selects the usual case where the
files are ordered by file name. With <guibutton>Sort by tag field</guibutton>,
it is possible to sort by a format string with values from tag fields. For
instance, "%{track.3}" can be used to sort by track number (the ".3" is used
to get three digits with leading zeros because strings are used for
sorting). It is also possible to use multiple fields, e.g. "%{genre}%{year}"
to sort using a string composed of genre and year.
</para>
<para>
The playlist entries will have relative or absolute file paths depending on
whether <guibutton>Use relative path for files in playlist</guibutton> or
<guibutton>Use full path for files in playlist</guibutton> is set.
</para>
<para>
When <guibutton>Write only list of files</guibutton> is set, the playlist
will only contain the paths to the files. To generate an extended playlist
with additional information, a format string can be set using
the <guibutton>Write info using</guibutton> control.
</para>
</listitem>
</varlistentry>
<varlistentry>
......
......@@ -4,7 +4,7 @@ if (HAVE_TAGLIB)
set(TAGLIBEXT_LIBRARIES taglibext)
endif (HAVE_TAGLIB)
set(kid3_SRCS filelist.cpp filelistitem.cpp frame.cpp framelist.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp)
set(kid3_SRCS filelist.cpp filelistitem.cpp frame.cpp framelist.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp playlistdialog.cpp playlistconfig.cpp playlistcreator.cpp)
if (HAVE_QTDBUS)
set(kid3_SRCS ${kid3_SRCS} scriptinterface.cpp)
......
......@@ -28,14 +28,14 @@ kid3_LDADD += taglibext/libtaglibext.la
endif
# which sources should be compiled for kid3
kid3_SOURCES = filelist.cpp filelistitem.cpp frame.cpp framelist.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp scriptinterface.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp
kid3_SOURCES = filelist.cpp filelistitem.cpp frame.cpp framelist.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp scriptinterface.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp playlistdialog.cpp playlistconfig.cpp playlistcreator.cpp
# these headers are automatically built
BUILT_SOURCES =
CLEANFILES = allsys.h allsys.h.gch
# these are the headers for your project that won't be installed
noinst_HEADERS = configdialog.h exportdialog.h filelist.h filelistitem.h formatbox.h formatconfig.h frame.h framelist.h frametable.h freedbclient.h freedbconfig.h freedbdialog.h generalconfig.h genres.h id3form.h importconfig.h importdialog.h importparser.h importselector.h kid3.h miscconfig.h m4afile.h mp3file.h rendirdialog.h dirlist.h taggedfile.h musicbrainzclient.h musicbrainzconfig.h musicbrainzdialog.h numbertracksdialog.h oggfile.hpp vcedit.h flacfile.hpp commandstable.h taglibfile.h importsourceconfig.h importsourcedialog.h importsourceclient.h discogsdialog.h discogsclient.h discogsconfig.h musicbrainzreleasedialog.h musicbrainzreleaseclient.h qtcompatmac.h dirinfo.h externalprocess.h stringlistedit.h tracktypedialog.h tracktypeclient.h scriptinterface.h filterconfig.h filterdialog.h filefilter.h expressionparser.h pictureframe.h formatreplacer.h httpclient.h downloaddialog.h picturelabel.h browsecoverartdialog.h configtable.h attributedata.h browserdialog.h imageviewer.h editframedialog.h editframefieldsdialog.h
noinst_HEADERS = configdialog.h exportdialog.h filelist.h filelistitem.h formatbox.h formatconfig.h frame.h framelist.h frametable.h freedbclient.h freedbconfig.h freedbdialog.h generalconfig.h genres.h id3form.h importconfig.h importdialog.h importparser.h importselector.h kid3.h miscconfig.h m4afile.h mp3file.h rendirdialog.h dirlist.h taggedfile.h musicbrainzclient.h musicbrainzconfig.h musicbrainzdialog.h numbertracksdialog.h oggfile.hpp vcedit.h flacfile.hpp commandstable.h taglibfile.h importsourceconfig.h importsourcedialog.h importsourceclient.h discogsdialog.h discogsclient.h discogsconfig.h musicbrainzreleasedialog.h musicbrainzreleaseclient.h qtcompatmac.h dirinfo.h externalprocess.h stringlistedit.h tracktypedialog.h tracktypeclient.h scriptinterface.h filterconfig.h filterdialog.h filefilter.h expressionparser.h pictureframe.h formatreplacer.h httpclient.h downloaddialog.h picturelabel.h browsecoverartdialog.h configtable.h attributedata.h browserdialog.h imageviewer.h editframedialog.h editframefieldsdialog.h playlistdialog.h playlistconfig.h playlistcreator.h
# additional files in distribution
EXTRA_DIST = kid3.desktop kid3ui.rc hi16-app-kid3.png hi32-app-kid3.png hi48-app-kid3.png hisc-app-kid3.svgz de_qt.po ru_qt.po es_qt.po fr_qt.po it_qt.po pl_qt.po nl_qt.po et_qt.po
......
......@@ -6,7 +6,7 @@
* \author Urs Fleisch
* \date 23 Feb 2007
*
* Copyright (C) 2007 Urs Fleisch
* Copyright (C) 2007-2009 Urs Fleisch
*
* This file is part of Kid3.
*
......@@ -244,6 +244,29 @@ QString TrackDataFormatReplacer::getToolTip(bool onlyRows)
}
/**
* Constructor.
* All fields except the import duration are set from the tagged file,
* which should be read using readTags() before. The frames are merged
* from tag 2 and tag 1 (where tag 2 is not set).
*
* @param taggedFile tagged file providing track data
*/
ImportTrackData::ImportTrackData(TaggedFile& taggedFile) :
m_fileDuration(taggedFile.getDuration()),
m_importDuration(0),
m_absFilename(taggedFile.getAbsFilename()),
m_fileExtension(taggedFile.getFileExtension()),
m_tagFormatV1(taggedFile.getTagFormatV1()),
m_tagFormatV2(taggedFile.getTagFormatV2())
{
taggedFile.getDetailInfo(m_detailInfo);
FrameCollection framesV1;
taggedFile.getAllFramesV1(framesV1);
taggedFile.getAllFramesV2(*this);
merge(framesV1);
}
/**
* Format a string from track data.
* Supported format fields:
......
......@@ -6,7 +6,7 @@
* \author Urs Fleisch
* \date 7 Jul 2005
*
* Copyright (C) 2005-2007 Urs Fleisch
* Copyright (C) 2005-2009 Urs Fleisch
*
* This file is part of Kid3.
*
......@@ -52,6 +52,16 @@ public:
m_fileDuration(fileDuration), m_importDuration(0),
m_absFilename(absFilename) {}
/**
* Constructor.
* All fields except the import duration are set from the tagged file,
* which should be read using readTags() before. The frames are merged
* from tag 2 and tag 1 (where tag 2 is not set).
*
* @param taggedFile tagged file providing track data
*/
ImportTrackData(TaggedFile& taggedFile);
/**
* Destructor.
*/
......
......@@ -92,6 +92,8 @@
#include "filterdialog.h"
#include "rendirdialog.h"
#include "downloaddialog.h"
#include "playlistdialog.h"
#include "playlistcreator.h"
#include "filelistitem.h"
#include "dirlist.h"
#include "pictureframe.h"
......@@ -130,6 +132,7 @@ FreedbConfig Kid3App::s_trackTypeCfg("TrackType");
DiscogsConfig Kid3App::s_discogsCfg("Discogs");
MusicBrainzConfig Kid3App::s_musicBrainzCfg("MusicBrainz");
FilterConfig Kid3App::s_filterCfg("Filter");
PlaylistConfig Kid3App::s_playlistCfg("Playlist");
/** Current directory */
QString Kid3App::s_dirName;
......@@ -141,7 +144,8 @@ Kid3App::Kid3App() :
m_downloadToAllFilesInDir(false),
m_importDialog(0), m_browseCoverArtDialog(0),
m_exportDialog(0), m_renDirDialog(0),
m_numberTracksDialog(0), m_filterDialog(0), m_downloadDialog(0)
m_numberTracksDialog(0), m_filterDialog(0), m_downloadDialog(0),
m_playlistDialog(0)
{
#ifdef CONFIG_USE_KDE
#if KDE_VERSION >= 0x035c00
......@@ -213,6 +217,7 @@ Kid3App::~Kid3App()
delete m_filterDialog;
delete m_downloadDialog;
delete m_browseCoverArtDialog;
delete m_playlistDialog;
#ifndef CONFIG_USE_KDE
delete s_helpBrowser;
s_helpBrowser = 0;
......@@ -319,8 +324,8 @@ void Kid3App::initActions()
SLOT(slotExport()), actionCollection(),
"export");
KCM_KActionIcon(fileCreatePlaylist, KCM_ICON_media_playlist,
i18n("&Create Playlist"), this,
SLOT(slotCreatePlaylist()), actionCollection(),
i18n("&Create Playlist..."), this,
SLOT(slotPlaylistDialog()), actionCollection(),
"create_playlist");
KCM_KAction(toolsApplyFilenameFormat,
i18n("Apply &Filename Format"), this,
......@@ -526,9 +531,9 @@ void Kid3App::initActions()
QAction* fileCreatePlaylist = new QAction(this);
if (fileCreatePlaylist) {
fileCreatePlaylist->setStatusTip(i18n("Create M3U Playlist"));
fileCreatePlaylist->QCM_setMenuText(i18n("&Create Playlist"));
fileCreatePlaylist->QCM_setMenuText(i18n("&Create Playlist..."));
connect(fileCreatePlaylist, QCM_SIGNAL_triggered,
this, SLOT(slotCreatePlaylist()));
this, SLOT(slotPlaylistDialog()));
}
QAction* fileQuit = new QAction(this);
if (fileQuit) {
......@@ -875,6 +880,7 @@ void Kid3App::saveOptions()
s_trackTypeCfg.writeToConfig(m_config);
s_discogsCfg.writeToConfig(m_config);
s_filterCfg.writeToConfig(m_config);
s_playlistCfg.writeToConfig(m_config);
#ifdef HAVE_TUNEPIMP
s_musicBrainzCfg.writeToConfig(m_config);
#endif
......@@ -925,6 +931,7 @@ void Kid3App::readOptions()
}
s_discogsCfg.readFromConfig(m_config);
s_filterCfg.readFromConfig(m_config);
s_playlistCfg.readFromConfig(m_config);
#ifdef HAVE_TUNEPIMP
s_musicBrainzCfg.readFromConfig(m_config);
#endif
......@@ -1641,34 +1648,96 @@ void Kid3App::slotStatusMsg(const QString& text)
}
/**
* Create playlist.
* Show playlist dialog.
*/
void Kid3App::slotPlaylistDialog()
{
if (!m_playlistDialog) {
m_playlistDialog = new PlaylistDialog(0);
}
if (m_playlistDialog) {
m_playlistDialog->readConfig();
if (m_playlistDialog->exec() == QDialog::Accepted) {
PlaylistConfig cfg;
m_playlistDialog->getCurrentConfig(cfg);
writePlaylist(cfg);
}
}
}
/**
* Write playlist according to playlist configuration.
*
* @param cfg playlist configuration to use
*
* @return true if ok.
*/
bool Kid3App::slotCreatePlaylist()
bool Kid3App::writePlaylist(const PlaylistConfig& cfg)
{
FileListItem* mp3file = m_view->firstFileInDir();
if (!(mp3file && mp3file->getFile())) return false;
QDir dir(mp3file->getFile()->getDirname());
QString dirname = dir.QCM_absolutePath();
QString fn = dirname + QDir::separator() + dir.dirName() + ".m3u";
QFile file(fn);
PlaylistCreator plCtr(m_view->getDirInfo()->getDirname(), cfg);
QString selectedDirPrefix;
FileListItem* item = cfg.m_location == PlaylistConfig::PL_CurrentDirectory ?
m_view->firstFileInDir() : m_view->firstFileOrDir();
bool noSelection = !cfg.m_onlySelectedFiles ||
m_view->numFilesOrDirsSelected() == 0;
bool ok = true;
QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
slotStatusMsg(i18n("Creating playlist..."));
bool ok = file.open(QCM_WriteOnly);
if (ok) {
QTextStream stream(&file);
while (mp3file != 0) {
stream << mp3file->getFile()->getFilename() << "\n";
mp3file = m_view->nextFileInDir();
while (item != 0) {
PlaylistCreator::Item plItem(item, plCtr);
bool inSelectedDir = false;
if (cfg.m_location != PlaylistConfig::PL_CurrentDirectory &&
plItem.isDir()) {
if (!selectedDirPrefix.isEmpty()) {
if (plItem.getDirName().startsWith(selectedDirPrefix)) {
inSelectedDir = true;
} else {
selectedDirPrefix = "";
}
}
if (inSelectedDir || noSelection || item->isSelected()) {
// if directory is selected, all its files are selected
#if QT_VERSION >= 0x040000
item->setExpanded(true);
#else
item->setOpen(true);
#endif
if (!inSelectedDir) {
selectedDirPrefix = plItem.getDirName();
}
}
} else if (plItem.isFile()) {
QString dirName = plItem.getDirName();
if (!selectedDirPrefix.isEmpty()) {
if (dirName.startsWith(selectedDirPrefix)) {
inSelectedDir = true;
} else {
selectedDirPrefix = "";
}
}
if (inSelectedDir || noSelection || item->isSelected()) {
ok = plItem.add() && ok;
}
}
file.close();
item = cfg.m_location == PlaylistConfig::PL_CurrentDirectory ?
m_view->nextFileInDir() : m_view->nextFileOrDir();
}
ok = plCtr.write() && ok;
slotStatusMsg(i18n("Ready."));
QApplication::restoreOverrideCursor();
return ok;
}
/**
* Create playlist.
*
* @return true if ok.
*/
bool Kid3App::slotCreatePlaylist()
{
return writePlaylist(s_playlistCfg);
}
/**
* Update track data and create import dialog.
*/
......@@ -1911,7 +1980,7 @@ void Kid3App::slotBrowseCoverArt()
*
* @return tagged file (can be new TagLibFile).
*/
static TaggedFile* readWithTagLibIfId3V24(FileListItem* item,
TaggedFile* Kid3App::readWithTagLibIfId3V24(FileListItem* item,
TaggedFile* taggedFile)
{
if (dynamic_cast<Mp3File*>(taggedFile) != 0 &&
......
......@@ -58,12 +58,14 @@ typedef QMainWindow Kid3AppBaseClass;
#include "discogsconfig.h"
#include "musicbrainzconfig.h"
#include "filterconfig.h"
#include "playlistconfig.h"
#include "frame.h"
class KURL;
class KUrl;
class Id3Form;
class TaggedFile;
class FileListItem;
class FrameList;
class ImportDialog;
class ExportDialog;
......@@ -75,6 +77,7 @@ class FilterDialog;
class FileFilter;
class QImage;
class DownloadDialog;
class PlaylistDialog;
/** Kid3 application */
class Kid3App : public Kid3AppBaseClass
......@@ -278,6 +281,17 @@ public:
*/
static QString getDirName() { return s_dirName; }
/**
* Read file with TagLib if it has an ID3v2.4 tag.
*
* @param item file list item, can be updated
* @param taggedFile tagged file
*
* @return tagged file (can be new TagLibFile).
*/
static TaggedFile* readWithTagLibIfId3V24(FileListItem* item,
TaggedFile* taggedFile);
/** Filename format configuration */
static FormatConfig s_fnFormatCfg;
/** ID3 format configuration */
......@@ -296,6 +310,8 @@ public:
static MusicBrainzConfig s_musicBrainzCfg;
/** Filter configuration */
static FilterConfig s_filterCfg;
/** Playlist configuration */
static PlaylistConfig s_playlistCfg;
protected:
/**
......@@ -492,6 +508,11 @@ public slots:
*/
void slotStatusMsg(const QString& text);
/**
* Show playlist dialog.
*/
void slotPlaylistDialog();
/**
* Create playlist.
*
......@@ -716,6 +737,15 @@ private:
*/
bool importTags(int tagMask, const QString& path, int fmtIdx);
/**
* Write playlist according to playlist configuration.
*
* @param cfg playlist configuration to use
*
* @return true if ok.
*/
bool writePlaylist(const PlaylistConfig& cfg);
/**
* Show or hide the ID3V1.1 controls according to the settings and
* set the menu entries appropriately.
......@@ -774,6 +804,8 @@ private:
FilterDialog* m_filterDialog;
/** Download dialog */
DownloadDialog* m_downloadDialog;
/** Playlist dialog */
PlaylistDialog* m_playlistDialog;
/** Frame list */
FrameList* m_framelist;
......
......@@ -49,9 +49,9 @@ contains(CFG_LIBS, -ltag) {
POST_TARGETDEPS += $$TAGLIBEXT_LIB
}
SOURCES = filelist.cpp filelistitem.cpp framelist.cpp frame.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp
SOURCES = filelist.cpp filelistitem.cpp framelist.cpp frame.cpp frametable.cpp genres.cpp id3form.cpp kid3.cpp main.cpp m4afile.cpp mp3file.cpp configdialog.cpp exportdialog.cpp formatconfig.cpp formatbox.cpp importdialog.cpp importselector.cpp importparser.cpp generalconfig.cpp importconfig.cpp miscconfig.cpp freedbdialog.cpp freedbconfig.cpp freedbclient.cpp rendirdialog.cpp dirlist.cpp taggedfile.cpp musicbrainzdialog.cpp musicbrainzconfig.cpp musicbrainzclient.cpp numbertracksdialog.cpp oggfile.cpp vcedit.c flacfile.cpp commandstable.cpp taglibfile.cpp importsourceconfig.cpp importsourcedialog.cpp importsourceclient.cpp discogsdialog.cpp discogsclient.cpp discogsconfig.cpp musicbrainzreleasedialog.cpp musicbrainzreleaseclient.cpp externalprocess.cpp importtrackdata.cpp stringlistedit.cpp tracktypedialog.cpp tracktypeclient.cpp filterconfig.cpp filterdialog.cpp filefilter.cpp expressionparser.cpp pictureframe.cpp formatreplacer.cpp httpclient.cpp downloaddialog.cpp picturelabel.cpp browsecoverartdialog.cpp configtable.cpp attributedata.cpp browserdialog.cpp imageviewer.cpp editframedialog.cpp editframefieldsdialog.cpp playlistdialog.cpp playlistconfig.cpp playlistcreator.cpp
HEADERS = configdialog.h exportdialog.h filelist.h filelistitem.h formatbox.h formatconfig.h frame.h framelist.h frametable.h freedbclient.h freedbconfig.h freedbdialog.h generalconfig.h genres.h id3form.h importconfig.h importdialog.h importparser.h importselector.h kid3.h miscconfig.h m4afile.h mp3file.h rendirdialog.h dirlist.h taggedfile.h musicbrainzclient.h musicbrainzconfig.h musicbrainzdialog.h numbertracksdialog.h oggfile.hpp vcedit.h flacfile.hpp commandstable.h taglibfile.h importsourceconfig.h importsourcedialog.h importsourceclient.h discogsdialog.h discogsclient.h discogsconfig.h musicbrainzreleasedialog.h musicbrainzreleaseclient.h qtcompatmac.h dirinfo.h externalprocess.h stringlistedit.h tracktypedialog.h tracktypeclient.h filterconfig.h filterdialog.h filefilter.h expressionparser.h pictureframe.h formatreplacer.h httpclient.h downloaddialog.h picturelabel.h browsecoverartdialog.h configtable.h attributedata.h browserdialog.h imageviewer.h editframedialog.h editframefieldsdialog.h
HEADERS = configdialog.h exportdialog.h filelist.h filelistitem.h formatbox.h formatconfig.h frame.h framelist.h frametable.h freedbclient.h freedbconfig.h freedbdialog.h generalconfig.h genres.h id3form.h importconfig.h importdialog.h importparser.h importselector.h kid3.h miscconfig.h m4afile.h mp3file.h rendirdialog.h dirlist.h taggedfile.h musicbrainzclient.h musicbrainzconfig.h musicbrainzdialog.h numbertracksdialog.h oggfile.hpp vcedit.h flacfile.hpp commandstable.h taglibfile.h importsourceconfig.h importsourcedialog.h importsourceclient.h discogsdialog.h discogsclient.h discogsconfig.h musicbrainzreleasedialog.h musicbrainzreleaseclient.h qtcompatmac.h dirinfo.h externalprocess.h stringlistedit.h tracktypedialog.h tracktypeclient.h filterconfig.h filterdialog.h filefilter.h expressionparser.h pictureframe.h formatreplacer.h httpclient.h downloaddialog.h picturelabel.h browsecoverartdialog.h configtable.h attributedata.h browserdialog.h imageviewer.h editframedialog.h editframefieldsdialog.h playlistdialog.h playlistconfig.h playlistcreator.h
unix:program.path = $$CFG_BINDIR $$CFG_DATAROOTDIR/applications $$CFG_DATAROOTDIR/icons/hicolor/16x16/apps $$CFG_DATAROOTDIR/icons/hicolor/32x32/apps $$CFG_DATAROOTDIR/icons/hicolor/48x48/apps $$CFG_DATAROOTDIR/icons/hicolor/scalable/apps
win32 {
......
/**
* \file playlistconfig.cpp
* Configuration for playlist dialog.
*
* \b Project: Kid3
* \author Urs Fleisch
* \date 16 Sep 2009
*
* Copyright (C) 2009 Urs Fleisch
*
* This file is part of Kid3.
*
* Kid3 is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* Kid3 is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
<