Commit 38b58265 authored by Urs Fleisch's avatar Urs Fleisch
Browse files

Import from tags to copy information between tags.

parent 37d9d9b6
......@@ -25,7 +25,7 @@ set(kid3_SRCS filelist.cpp fileproxymodel.cpp frame.cpp framelist.cpp
editframefieldsdialog.cpp playlistdialog.cpp playlistconfig.cpp
playlistcreator.cpp amazonimporter.cpp amazonconfig.cpp
recentfilesmenu.cpp playtoolbar.cpp textimporter.cpp textimportdialog.cpp
trackdatamatcher.cpp)
trackdatamatcher.cpp tagimportdialog.cpp)
if (HAVE_QTDBUS)
set(kid3_SRCS ${kid3_SRCS} scriptinterface.cpp)
......@@ -118,7 +118,8 @@ set(kid3_MOC_HDRS filelist.h frametable.h frametablemodel.h id3form.h kid3.h con
filterdialog.h filefilter.h httpclient.h downloaddialog.h
browsecoverartdialog.h configtable.h browserdialog.h imageviewer.h
editframedialog.h editframefieldsdialog.h playlistdialog.h recentfilesmenu.h
playtoolbar.h fileproxymodel.h trackdatamodel.h textimportdialog.h)
playtoolbar.h fileproxymodel.h trackdatamodel.h textimportdialog.h
tagimportdialog.h)
if (HAVE_QTDBUS)
set(kid3_MOC_HDRS ${kid3_MOC_HDRS} scriptinterface.h)
endif (HAVE_QTDBUS)
......
......@@ -43,6 +43,7 @@ ImportConfig::ImportConfig(const QString& grp) :
m_importDest(ImportConfig::DestV1), m_importFormatIdx(0),
m_enableTimeDifferenceCheck(true), m_maxTimeDifference(3),
m_importWindowWidth(-1), m_importWindowHeight(-1),
m_importTagsIdx(0),
m_exportSrcV1(true), m_exportFormatIdx(0),
m_exportWindowWidth(-1), m_exportWindowHeight(-1),
m_pictureSourceIdx(0),
......@@ -146,6 +147,38 @@ ImportConfig::ImportConfig(const QString& grp) :
m_exportFormatTracks.append("\"%{track}\"\\t\"%{title}\"\\t\"%{artist}\"\\t\"%{album}\"\\t\"%{year}\"\\t\"%{genre}\"\\t\"%{comment}\"\\t\"%{duration}.00\"");
m_exportFormatTrailers.append("");
m_importTagsNames.append("Artist to Album Artist");
m_importTagsSources.append("%{artist}");
m_importTagsExtractions.append("%{albumartist}(.+)");
m_importTagsNames.append("Album Artist to Artist");
m_importTagsSources.append("%{albumartist}");
m_importTagsExtractions.append("%{artist}(.+)");
m_importTagsNames.append("Artist to Composer");
m_importTagsSources.append("%{artist}");
m_importTagsExtractions.append("%{composer}(.+)");
m_importTagsNames.append("Artist to Conductor");
m_importTagsSources.append("%{artist}");
m_importTagsExtractions.append("%{conductor}(.+)");
m_importTagsNames.append("Track Number from Title");
m_importTagsSources.append("%{title}");
m_importTagsExtractions.append("\\s*%{track}(\\d+)[\\.\\s]+%{title}(.*\\S)\\s*");
m_importTagsNames.append("Track Number to Title");
m_importTagsSources.append("%{track} %{title}");
m_importTagsExtractions.append("%{title}(.+)");
m_importTagsNames.append("Subtitle from Title");
m_importTagsSources.append("%{title}");
m_importTagsExtractions.append("%{subtitle}(.+) - ");
m_importTagsNames.append("Custom Format");
m_importTagsSources.append("");
m_importTagsExtractions.append("");
m_exportFormatNames.append("CSV more unquoted");
m_exportFormatHeaders.append(
"Track\\tTitle\\tArtist\\tAlbum\\tDate\\tGenre\\tComment\\tDuration\\t"
......@@ -303,6 +336,11 @@ void ImportConfig::writeToConfig(
cfg.writeEntry("ImportWindowWidth", m_importWindowWidth);
cfg.writeEntry("ImportWindowHeight", m_importWindowHeight);
cfg.writeEntry("ImportTagsNames", m_importTagsNames);
cfg.writeEntry("ImportTagsSources", m_importTagsSources);
cfg.writeEntry("ImportTagsExtractions", m_importTagsExtractions);
cfg.writeEntry("ImportTagsIdx", m_importTagsIdx);
cfg.writeEntry("ExportSourceV1", m_exportSrcV1);
cfg.writeEntry("ExportFormatNames", m_exportFormatNames);
cfg.writeEntry("ExportFormatHeaders", m_exportFormatHeaders);
......@@ -332,6 +370,11 @@ void ImportConfig::writeToConfig(
config->setValue("/ImportWindowWidth", QVariant(m_importWindowWidth));
config->setValue("/ImportWindowHeight", QVariant(m_importWindowHeight));
config->setValue("/ImportTagsNames", QVariant(m_importTagsNames));
config->setValue("/ImportTagsSources", QVariant(m_importTagsSources));
config->setValue("/ImportTagsExtractions", QVariant(m_importTagsExtractions));
config->setValue("/ImportTagsIdx", QVariant(m_importTagsIdx));
config->setValue("/ExportSourceV1", QVariant(m_exportSrcV1));
config->setValue("/ExportFormatNames", QVariant(m_exportFormatNames));
config->setValue("/ExportFormatHeaders", QVariant(m_exportFormatHeaders));
......@@ -367,6 +410,7 @@ void ImportConfig::readFromConfig(
)
{
QStringList names, headers, tracks;
QStringList tagsNames, tagsSources, tagsExtractions;
QStringList expNames, expHeaders, expTracks, expTrailers, picNames, picUrls;
#ifdef CONFIG_USE_KDE
KConfigGroup cfg = config->group(m_group);
......@@ -383,6 +427,11 @@ void ImportConfig::readFromConfig(
m_importWindowWidth = cfg.readEntry("ImportWindowWidth", -1);
m_importWindowHeight = cfg.readEntry("ImportWindowHeight", -1);
tagsNames = cfg.readEntry("ImportTagsNames", QStringList());
tagsSources = cfg.readEntry("ImportTagsSources", QStringList());
tagsExtractions = cfg.readEntry("ImportTagsExtractions", QStringList());
m_importTagsIdx = cfg.readEntry("ImportTagsIdx", m_importTagsIdx);
m_exportSrcV1 = cfg.readEntry("ExportSourceV1", m_exportSrcV1);
expNames = cfg.readEntry("ExportFormatNames", QStringList());
expHeaders = cfg.readEntry("ExportFormatHeaders", QStringList());
......@@ -435,6 +484,11 @@ void ImportConfig::readFromConfig(
m_importWindowWidth = config->value("/ImportWindowWidth", -1).toInt();
m_importWindowHeight = config->value("/ImportWindowHeight", -1).toInt();
tagsNames = config->value("/ImportTagsNames").toStringList();
tagsSources = config->value("/ImportTagsSources").toStringList();
tagsExtractions = config->value("/ImportTagsExtractions").toStringList();
m_importTagsIdx = config->value("/ImportTagsIdx", m_importTagsIdx).toInt();
m_exportSrcV1 = config->value("/ExportSourceV1", m_exportSrcV1).toBool();
expNames = config->value("/ExportFormatNames").toStringList();
expHeaders = config->value("/ExportFormatHeaders").toStringList();
......@@ -484,6 +538,23 @@ void ImportConfig::readFromConfig(
}
}
QStringList::const_iterator tagsNamesIt, sourcesIt, extractionsIt;
for (tagsNamesIt = tagsNames.begin(), sourcesIt = tagsSources.begin(),
extractionsIt = tagsExtractions.begin();
tagsNamesIt != tagsNames.end() && sourcesIt != tagsSources.end() &&
extractionsIt != tagsExtractions.end();
++tagsNamesIt, ++sourcesIt, ++extractionsIt) {
int idx = m_importTagsNames.indexOf(*tagsNamesIt);
if (idx >= 0) {
m_importTagsSources[idx] = *sourcesIt;
m_importTagsExtractions[idx] = *extractionsIt;
} else if (!(*tagsNamesIt).isEmpty()) {
m_importTagsNames.append(*tagsNamesIt);
m_importTagsSources.append(*sourcesIt);
m_importTagsExtractions.append(*extractionsIt);
}
}
QStringList::const_iterator expNamesIt, expHeadersIt, expTracksIt,
expTrailersIt;
for (expNamesIt = expNames.begin(), expHeadersIt = expHeaders.begin(),
......@@ -519,6 +590,8 @@ void ImportConfig::readFromConfig(
if (m_importFormatIdx >= static_cast<int>(m_importFormatNames.size()))
m_importFormatIdx = 0;
if (m_importTagsIdx >= static_cast<int>(m_importTagsNames.size()))
m_importTagsIdx = 0;
if (m_exportFormatIdx >= static_cast<int>(m_exportFormatNames.size()))
m_exportFormatIdx = 0;
if (m_pictureSourceIdx >= static_cast<int>(m_pictureSourceNames.size()))
......
......@@ -106,6 +106,15 @@ public:
/** import window height */
int m_importWindowHeight;
/** Names of import tags formats */
QStringList m_importTagsNames;
/** Expressions for tag import sources */
QStringList m_importTagsSources;
/** regexp describing extraction from import tag sources */
QStringList m_importTagsExtractions;
/** selected import tags format */
int m_importTagsIdx;
/** true to export ID3v1 tags, else ID3v2 tags */
bool m_exportSrcV1;
/** Names of export formats */
......
......@@ -56,6 +56,7 @@
#include "amazonimporter.h"
#include "serverimportdialog.h"
#include "textimportdialog.h"
#include "tagimportdialog.h"
#include "kid3.h"
#include "taggedfile.h"
#include "trackdata.h"
......@@ -94,6 +95,7 @@ ImportDialog::ImportDialog(QWidget* parent, QString& caption,
m_amazonImporter = 0;
m_serverImportDialog = 0;
m_textImportDialog = 0;
m_tagImportDialog = 0;
#ifdef HAVE_TUNEPIMP
m_musicBrainzDialog = 0;
#endif
......@@ -121,6 +123,10 @@ ImportDialog::ImportDialog(QWidget* parent, QString& caption,
butbox);
fileButton->setAutoDefault(false);
butlayout->addWidget(fileButton);
QPushButton* tagsButton = new QPushButton(i18n("From T&ags..."),
butbox);
tagsButton->setAutoDefault(false);
butlayout->addWidget(tagsButton);
QPushButton* serverButton = new QPushButton(i18n("&From Server:"), butbox);
serverButton->setAutoDefault(false);
butlayout->addWidget(serverButton);
......@@ -182,6 +188,7 @@ ImportDialog::ImportDialog(QWidget* parent, QString& caption,
vlayout->addWidget(matchBox);
connect(fileButton, SIGNAL(clicked()), this, SLOT(fromText()));
connect(tagsButton, SIGNAL(clicked()), this, SLOT(fromTags()));
connect(serverButton, SIGNAL(clicked()), this, SLOT(fromServer()));
connect(m_serverComboBox, SIGNAL(activated(int)), this, SLOT(fromServer()));
connect(lengthButton, SIGNAL(clicked()), this, SLOT(matchWithLength()));
......@@ -220,6 +227,7 @@ ImportDialog::ImportDialog(QWidget* parent, QString& caption,
ImportDialog::~ImportDialog()
{
delete m_textImportDialog;
delete m_tagImportDialog;
delete m_serverImportDialog;
delete m_freedbImporter;
delete m_trackTypeImporter;
......@@ -274,6 +282,20 @@ void ImportDialog::fromText()
m_textImportDialog->show();
}
/**
* Import from tags.
*/
void ImportDialog::fromTags()
{
if (!m_tagImportDialog) {
m_tagImportDialog = new TagImportDialog(this, m_trackDataVector);
connect(m_tagImportDialog, SIGNAL(trackDataUpdated()),
this, SLOT(showPreview()));
}
m_tagImportDialog->clear();
m_tagImportDialog->show();
}
/**
* Display server import dialog.
*
......@@ -303,6 +325,8 @@ void ImportDialog::hideSubdialogs()
m_serverImportDialog->hide();
if (m_textImportDialog)
m_textImportDialog->hide();
if (m_tagImportDialog)
m_tagImportDialog->hide();
}
/**
......
......@@ -49,6 +49,7 @@ class AmazonImporter;
class ServerImporter;
class ServerImportDialog;
class TextImportDialog;
class TagImportDialog;
class ImportTrackDataVector;
class FrameCollection;
class FreedbConfig;
......@@ -158,6 +159,11 @@ private slots:
*/
void fromText();
/**
* Import from tags.
*/
void fromTags();
/**
* Show fields to import in text as preview in table.
*/
......@@ -276,6 +282,8 @@ private:
ServerImportDialog* m_serverImportDialog;
/** Text import dialog */
TextImportDialog* m_textImportDialog;
/** Tag import dialog */
TagImportDialog* m_tagImportDialog;
/** track data */
ImportTrackDataVector& m_trackDataVector;
};
......
......@@ -182,7 +182,7 @@ bool ImportParser::getNextTags(const QString& text, FrameCollection& frames, int
QString name = it.key();
QString str = m_re.cap(*it);
if (!str.isEmpty() && !name.startsWith("__")) {
frames.insert(Frame(Frame::getTypeFromName(name), str, name, -1));
frames.setValue(Frame::getTypeFromName(name), str);
}
}
if (m_trackIncrEnabled) {
......
/**
* \file tagimportdialog.cpp
* Dialog to import from other tags.
*
* \b Project: Kid3
* \author Urs Fleisch
* \date 20 Jun 2011
*
* Copyright (C) 2011 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/>.
*/
#include "tagimportdialog.h"
#include <QHBoxLayout>
#include <QFormLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>
#include "textimporter.h"
#include "importparser.h"
#include "kid3.h"
#include "qtcompatmac.h"
/**
* Constructor.
*
* @param parent parent widget
* @param trackDataVector track data to be filled with imported values
*/
TagImportDialog::TagImportDialog(QWidget* parent,
ImportTrackDataVector& trackDataVector) :
QDialog(parent), m_trackDataVector(trackDataVector)
{
setObjectName("TagImportDialog");
setWindowTitle(i18n("Import from Tags"));
setSizeGripEnabled(true);
QVBoxLayout* vboxLayout = new QVBoxLayout(this);
vboxLayout->setSpacing(6);
vboxLayout->setMargin(6);
m_formatComboBox = new QComboBox(this);
m_formatComboBox->setEditable(true);
m_sourceLineEdit = new QLineEdit(this);
m_extractionLineEdit = new QLineEdit(this);
m_sourceLineEdit->setToolTip(TrackDataFormatReplacer::getToolTip());
m_extractionLineEdit->setToolTip(ImportParser::getFormatToolTip());
connect(m_formatComboBox, SIGNAL(activated(int)),
this, SLOT(setFormatLineEdit(int)));
QFormLayout* formatLayout = new QFormLayout;
formatLayout->addRow(i18n("Format:"), m_formatComboBox);
formatLayout->addRow(i18n("Source:"), m_sourceLineEdit);
formatLayout->addRow(i18n("Extraction:"), m_extractionLineEdit);
vboxLayout->addLayout(formatLayout);
QHBoxLayout* buttonLayout = new QHBoxLayout;
QPushButton* helpButton = new QPushButton(i18n("&Help"), this);
helpButton->setAutoDefault(false);
buttonLayout->addWidget(helpButton);
connect(helpButton, SIGNAL(clicked()), this, SLOT(showHelp()));
QPushButton* saveButton = new QPushButton(i18n("&Save Settings"), this);
saveButton->setAutoDefault(false);
buttonLayout->addWidget(saveButton);
connect(saveButton, SIGNAL(clicked()), this, SLOT(saveConfig()));
buttonLayout->addStretch();
QPushButton* applyButton = new QPushButton(i18n("&Apply"), this);
applyButton->setAutoDefault(false);
buttonLayout->addWidget(applyButton);
connect(applyButton, SIGNAL(clicked()), this, SLOT(apply()));
QPushButton* closeButton = new QPushButton(i18n("&Close"), this);
closeButton->setAutoDefault(false);
buttonLayout->addWidget(closeButton);
connect(closeButton, SIGNAL(clicked()), this, SLOT(accept()));
vboxLayout->addLayout(buttonLayout);
}
/**
* Destructor.
*/
TagImportDialog::~TagImportDialog()
{
}
/**
* Clear dialog data.
*/
void TagImportDialog::clear()
{
setFormatFromConfig();
}
/**
* Apply import to track data.
*/
void TagImportDialog::apply()
{
TextImporter::importFromTags(m_sourceLineEdit->text(),
m_extractionLineEdit->text(),
m_trackDataVector);
emit trackDataUpdated();
}
/**
* Set the format combo box and line edits from the configuration.
*/
void TagImportDialog::setFormatFromConfig()
{
m_formatSources = Kid3App::s_genCfg.m_importTagsSources;
m_formatExtractions = Kid3App::s_genCfg.m_importTagsExtractions;
m_formatComboBox->clear();
m_formatComboBox->addItems(Kid3App::s_genCfg.m_importTagsNames);
m_formatComboBox->setCurrentIndex(Kid3App::s_genCfg.m_importTagsIdx);
setFormatLineEdit(Kid3App::s_genCfg.m_importTagsIdx);
}
/**
* Set the format lineedits to the format selected in the combo box.
*
* @param index current index of the combo box
*/
void TagImportDialog::setFormatLineEdit(int index)
{
if (index < static_cast<int>(m_formatSources.size())) {
m_sourceLineEdit->setText(m_formatSources[index]);
m_extractionLineEdit->setText(m_formatExtractions[index]);
} else {
m_sourceLineEdit->clear();
m_extractionLineEdit->clear();
}
}
/**
* Save the local settings to the configuration.
*/
void TagImportDialog::saveConfig()
{
Kid3App::s_genCfg.m_importTagsIdx = m_formatComboBox->currentIndex();
if (Kid3App::s_genCfg.m_importTagsIdx < static_cast<int>(Kid3App::s_genCfg.m_importTagsNames.size())) {
Kid3App::s_genCfg.m_importTagsNames[Kid3App::s_genCfg.m_importTagsIdx] = m_formatComboBox->currentText();
Kid3App::s_genCfg.m_importTagsSources[Kid3App::s_genCfg.m_importTagsIdx] = m_sourceLineEdit->text();
Kid3App::s_genCfg.m_importTagsExtractions[Kid3App::s_genCfg.m_importTagsIdx] = m_extractionLineEdit->text();
} else {
Kid3App::s_genCfg.m_importTagsIdx = Kid3App::s_genCfg.m_importTagsNames.size();
Kid3App::s_genCfg.m_importTagsNames.append(m_formatComboBox->currentText());
Kid3App::s_genCfg.m_importTagsSources.append(m_sourceLineEdit->text());
Kid3App::s_genCfg.m_importTagsExtractions.append(m_extractionLineEdit->text());
}
setFormatFromConfig();
}
/**
* Show help.
*/
void TagImportDialog::showHelp()
{
Kid3App::displayHelp("import");
}
/**
* \file tagimportdialog.h
* Dialog to import from other tags.
*
* \b Project: Kid3
* \author Urs Fleisch
* \date 20 Jun 2011
*
* Copyright (C) 2011 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/>.
*/
#ifndef TAGIMPORTDIALOG_H
#define TAGIMPORTDIALOG_H
#include <QDialog>
#include <QStringList>
class QLineEdit;
class QLabel;
class QComboBox;
class QPushButton;
class ImportTrackDataVector;
/**
* Dialog to import from a text (file or clipboard).
*/
class TagImportDialog : public QDialog {
Q_OBJECT
public:
/**
* Constructor.
*
* @param parent parent widget
* @param trackDataVector track data to be filled with imported values
*/
explicit TagImportDialog(QWidget* parent,
ImportTrackDataVector& trackDataVector);
/**
* Destructor.
*/
virtual ~TagImportDialog();
/**
* Clear dialog data.
*/
void clear();
private slots:
/**
* Apply import to track data.
*/
void apply();
/**
* Set the format lineedits to the format selected in the combo box.
*
* @param index current index of the combo box
*/
void setFormatLineEdit(int index);
/**
* Save the local settings to the configuration.
*/
void saveConfig();
/**
* Show help.
*/
void showHelp();
signals:
/**
* Emitted when the m_trackDataVector was updated with new imported data.
*/
void trackDataUpdated();
private:
/**
* Set the format combo box and line edits from the configuration.
*/
void setFormatFromConfig();
/** combobox with import formats */
QComboBox* m_formatComboBox;
/** LineEdit for source expression */
QLineEdit* m_sourceLineEdit;
/** LineEdit for extraction regexp */
QLineEdit* m_extractionLineEdit;
/** Source expressions */
QStringList m_formatSources;
/** Extraction regexps */
QStringList m_formatExtractions;
ImportTrackDataVector& m_trackDataVector;
};
#endif
......@@ -26,7 +26,7 @@
#include "textimportdialog.h"
#include <QHBoxLayout>
#include <QGroupBox>
#include <QFormLayout>
#include <QComboBox>
#include <QLineEdit>
#include <QPushButton>
......@@ -56,29 +56,26 @@ TextImportDialog::TextImportDialog(QWidget* parent,
QDialog(parent), m_textImporter(new TextImporter(trackDataVector))
{
setObjectName("TextImportDialog");
setWindowTitle(i18n("Import"));
setWindowTitle(i18n("Import from File/Clipboard"));
setSizeGripEnabled(true);
QVBoxLayout* vboxLayout = new QVBoxLayout(this);
vboxLayout->setSpacing(6);
vboxLayout->setMargin(6);
QGroupBox* fmtbox = new QGroupBox(i18n("Format"), this);
m_formatComboBox = new QComboBox(fmtbox);
m_formatComboBox = new QComboBox(this);
m_formatComboBox->setEditable(true);
m_headerLineEdit = new QLineEdit(fmtbox);
m_trackLineEdit = new QLineEdit(fmtbox);
m_headerLineEdit = new QLineEdit(this);
m_trackLineEdit = new QLineEdit(this);
QString formatToolTip = ImportParser::getFormatToolTip();
m_headerLineEdit->setToolTip(formatToolTip);
m_trackLineEdit->setToolTip(formatToolTip);
connect(m_formatComboBox, SIGNAL(activated(int)), this, SLOT(setFormatLineEdit(int)));
QVBoxLayout* vbox = new QVBoxLayout;
vbox->setMargin(2);
vbox->addWidget(m_formatComboBox);
vbox->addWidget(m_headerLineEdit);
vbox->addWidget(m_trackLineEdit);
fmtbox->setLayout(vbox);
vboxLayout->addWidget(fmtbox);
QFormLayout* formatLayout = new QFormLayout;
formatLayout->addRow(i18n("Format:"), m_formatComboBox);
formatLayout->addRow(i18n("Header:"), m_headerLineEdit);
formatLayout->addRow(i18n("Tracks:"), m_trackLineEdit);
vboxLayout->addLayout(formatLayout);
QHBoxLayout* buttonLayout = new QHBoxLayout;
QPushButton* helpButton = new QPushButton(i18n("&Help"), this);
......