Allow auto-insert of DB query results

This commit is contained in:
Martchus 2016-12-01 22:23:01 +01:00
parent 255fef9bdf
commit 733fe08890
9 changed files with 97 additions and 29 deletions

View File

@ -281,6 +281,10 @@ void DbQueryWidget::applyMatchingResults()
*/ */
void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit) void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
{ {
if(!m_model) {
return;
}
// determine already present title, album and artist // determine already present title, album and artist
const TagValue givenTitle = tagEdit->value(KnownField::Title); const TagValue givenTitle = tagEdit->value(KnownField::Title);
const TagValue givenAlbum = tagEdit->value(KnownField::Album); const TagValue givenAlbum = tagEdit->value(KnownField::Album);
@ -291,6 +295,7 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
try { try {
givenTrack = tagEdit->value(KnownField::TrackPosition).toPositionInSet().position(); givenTrack = tagEdit->value(KnownField::TrackPosition).toPositionInSet().position();
} catch (const ConversionException &) { } catch (const ConversionException &) {
givenTrack = 0;
} }
if(!givenTrack) { if(!givenTrack) {
for(const Tag *tag : tagEdit->tags()) { for(const Tag *tag : tagEdit->tags()) {
@ -304,12 +309,16 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
} }
} }
if(givenTitle.isEmpty() || !givenTrack) {
return;
}
// find row matching already present data // find row matching already present data
for(int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) { for(int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) {
if((!givenTitle.isEmpty() && givenTitle != m_model->fieldValue(row, KnownField::Title)) if((!givenTitle.isEmpty() && givenTitle != m_model->fieldValue(row, KnownField::Title))
|| (!givenAlbum.isEmpty() && givenAlbum != m_model->fieldValue(row, KnownField::Album)) || (!givenAlbum.isEmpty() && givenAlbum != m_model->fieldValue(row, KnownField::Album))
|| (!givenArtist.isEmpty() && givenArtist != m_model->fieldValue(row, KnownField::Artist)) || (!givenArtist.isEmpty() && givenArtist != m_model->fieldValue(row, KnownField::Artist))
|| (givenTrack && m_model->data(m_model->index(row, QueryResultsModel::TitleCol)).toInt())) { || (givenTrack && givenTrack != m_model->fieldValue(row, KnownField::PartNumber).toInteger())) {
continue; continue;
} }
@ -321,6 +330,16 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit)
} }
} }
/*!
* \brief The same as applyMatchingResults() but checks whether auto-insert is enabled before (and does nothing if not).
*/
void DbQueryWidget::autoInsertMatchingResults()
{
if(m_ui->autoInsertCheckBox->isChecked()) {
applyMatchingResults();
}
}
/*! /*!
* \brief Applies the results at the specified \a resultIndex for the selected fields to the specified \a tagEdit. * \brief Applies the results at the specified \a resultIndex for the selected fields to the specified \a tagEdit.
* \remarks * \remarks

View File

@ -43,6 +43,7 @@ public slots:
void applySelectedResults(); void applySelectedResults();
void applyMatchingResults(); void applyMatchingResults();
void applyMatchingResults(TagEdit *tagEdit); void applyMatchingResults(TagEdit *tagEdit);
void autoInsertMatchingResults();
void insertSearchTermsFromActiveTagEdit(); void insertSearchTermsFromActiveTagEdit();
void clearSearchCriteria(); void clearSearchCriteria();

View File

@ -208,14 +208,31 @@
</widget> </widget>
</item> </item>
<item> <item>
<widget class="QCheckBox" name="overrideCheckBox"> <layout class="QHBoxLayout" name="horizontalLayout">
<property name="text"> <item>
<string>Override existing values</string> <widget class="QCheckBox" name="overrideCheckBox">
</property> <property name="toolTip">
<property name="checked"> <string>Whether existing values of selected &quot;Fields to be used&quot; should be overridden with values from search result</string>
<bool>true</bool> </property>
</property> <property name="text">
</widget> <string>Override existing values</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item>
<widget class="QCheckBox" name="autoInsertCheckBox">
<property name="toolTip">
<string>Whether matching values for selected &quot;Fields to be used&quot; from the search result should be inserted automatically when opening a file</string>
</property>
<property name="text">
<string>Insert automatically</string>
</property>
</widget>
</item>
</layout>
</item> </item>
</layout> </layout>
</widget> </widget>
@ -267,6 +284,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Aborts the current query</string>
</property>
<property name="text"> <property name="text">
<string>Abort</string> <string>Abort</string>
</property> </property>
@ -280,6 +300,9 @@
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Searches MusicBrainz for meta data matching the specified &quot;Search criteria&quot;</string>
</property>
<property name="text"> <property name="text">
<string>Search <string>Search
MusicBrainz</string> MusicBrainz</string>
@ -298,6 +321,9 @@ MusicBrainz</string>
<verstretch>0</verstretch> <verstretch>0</verstretch>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip">
<string>Searches LyricWikia for meta data matching the specified &quot;Search criteria&quot;</string>
</property>
<property name="text"> <property name="text">
<string>Search <string>Search
LyricWikia</string> LyricWikia</string>
@ -320,7 +346,7 @@ LyricWikia</string>
</sizepolicy> </sizepolicy>
</property> </property>
<property name="toolTip"> <property name="toolTip">
<string>Inserts the selected result into the current tag (doesn't save anything)</string> <string>Inserts values of &quot;Fields to be used&quot; from the selected result into the current tag but does not save anything</string>
</property> </property>
<property name="text"> <property name="text">
<string>Use selected <string>Use selected

View File

@ -111,7 +111,7 @@ MainWindow::MainWindow(QWidget *parent) :
// dbquery dock widget // dbquery dock widget
if(settings.dbQuery.widgetShown) { if(settings.dbQuery.widgetShown) {
m_ui->dbQueryDockWidget->setWidget(m_dbQueryWidget = new DbQueryWidget(m_ui->tagEditorWidget, this)); initDbQueryWidget();
} }
// restore locked // restore locked
@ -335,14 +335,23 @@ void MainWindow::spawnExternalPlayer()
} }
} }
/*!
* \brief Initializes m_dbQueryWidget is not already initialized.
*/
void MainWindow::initDbQueryWidget()
{
if(!m_dbQueryWidget) {
m_ui->dbQueryDockWidget->setWidget(m_dbQueryWidget = new DbQueryWidget(m_ui->tagEditorWidget, this));
connect(m_ui->tagEditorWidget, &TagEditorWidget::tagValuesLoaded, m_dbQueryWidget, static_cast<void(DbQueryWidget::*)(void)>(&DbQueryWidget::autoInsertMatchingResults), Qt::DirectConnection);
}
}
/*! /*!
* \brief Toggles visibility of the database query widget. * \brief Toggles visibility of the database query widget.
*/ */
void MainWindow::toggleDbQueryWidget() void MainWindow::toggleDbQueryWidget()
{ {
if(!m_dbQueryWidget) { initDbQueryWidget();
m_ui->dbQueryDockWidget->setWidget(m_dbQueryWidget = new DbQueryWidget(m_ui->tagEditorWidget, this));
}
m_ui->dbQueryDockWidget->setVisible(m_ui->dbQueryDockWidget->isHidden()); m_ui->dbQueryDockWidget->setVisible(m_ui->dbQueryDockWidget->isHidden());
} }

View File

@ -76,6 +76,7 @@ private slots:
void showAboutDlg(); void showAboutDlg();
void showRenameFilesDlg(); void showRenameFilesDlg();
void spawnExternalPlayer(); void spawnExternalPlayer();
void initDbQueryWidget();
void toggleDbQueryWidget(); void toggleDbQueryWidget();
private: private:

View File

@ -55,10 +55,10 @@ TagEdit::TagEdit(QWidget *parent) :
* \brief Returns the current value for the specified \a field. * \brief Returns the current value for the specified \a field.
* \remarks Doesn't work for fields of the type picture. * \remarks Doesn't work for fields of the type picture.
*/ */
TagValue TagEdit::value(KnownField field) const TagValue TagEdit::value(KnownField field, TagTextEncoding encoding) const
{ {
if(const TagFieldEdit *edit = m_widgets.value(field, nullptr)) { if(const TagFieldEdit *edit = m_widgets.value(field, nullptr)) {
return edit->value(TagTextEncoding::Utf16LittleEndian, false); return edit->value(encoding, false);
} else { } else {
return TagValue(); return TagValue();
} }

View File

@ -3,7 +3,7 @@
#include "./previousvaluehandling.h" #include "./previousvaluehandling.h"
#include <c++utilities/application/global.h> #include <tagparser/tagvalue.h>
#include <QList> #include <QList>
#include <QMap> #include <QMap>
@ -32,7 +32,7 @@ class TagEdit : public QWidget
public: public:
explicit TagEdit(QWidget *parent = nullptr); explicit TagEdit(QWidget *parent = nullptr);
const QList<Media::Tag *> &tags() const; const QList<Media::Tag *> &tags() const;
Media::TagValue value(Media::KnownField field) const; Media::TagValue value(Media::KnownField field, Media::TagTextEncoding encoding = Media::TagTextEncoding::Utf16LittleEndian) const;
void setTag(Media::Tag *tag, bool updateUi = true); void setTag(Media::Tag *tag, bool updateUi = true);
void setTags(const QList<Media::Tag *> &tags, bool updateUi = true); void setTags(const QList<Media::Tag *> &tags, bool updateUi = true);
bool setValue(Media::KnownField field, const Media::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear); bool setValue(Media::KnownField field, const Media::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);

View File

@ -32,6 +32,7 @@
#include <QKeyEvent> #include <QKeyEvent>
#include <QClipboard> #include <QClipboard>
#include <QFileSystemModel> #include <QFileSystemModel>
#include <QFileInfo>
#include <QPlainTextEdit> #include <QPlainTextEdit>
#include <QMimeData> #include <QMimeData>
#include <QFileSystemWatcher> #include <QFileSystemWatcher>
@ -558,14 +559,14 @@ void TagEditorWidget::updateTagManagementMenu()
/*! /*!
* \brief Inserts the title from the filename if no title is available from the tags. * \brief Inserts the title from the filename if no title is available from the tags.
* \remarks Does nothing if there are no tags assigned and if this feature is not enabled in the settings. * \remarks Does nothing if there are no tags assigned or if this feature is not enabled.
*/ */
void TagEditorWidget::insertTitleFromFilename() void TagEditorWidget::insertTitleFromFilename()
{ {
if(!m_tags.empty() && Settings::values().editor.autoCompletition.insertTitleFromFilename) { if(!m_tags.empty() && Settings::values().editor.autoCompletition.insertTitleFromFilename) {
QString title; QString title;
int trackNum; int trackNum;
parseFileName(QString::fromLocal8Bit(m_fileInfo.fileName().c_str()), title, trackNum); parseFileName(m_fileName, title, trackNum);
const TagValue titleValue = qstringToTagValue(title, TagTextEncoding::Utf16LittleEndian); const TagValue titleValue = qstringToTagValue(title, TagTextEncoding::Utf16LittleEndian);
foreachTagEdit([&titleValue] (TagEdit *edit) { foreachTagEdit([&titleValue] (TagEdit *edit) {
for(const Tag *tag : edit->tags()) { for(const Tag *tag : edit->tags()) {
@ -738,9 +739,11 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh)
m_currentPath = path; m_currentPath = path;
m_fileInfo.setSaveFilePath(string()); m_fileInfo.setSaveFilePath(string());
m_fileInfo.setPath(path.toLocal8Bit().data()); m_fileInfo.setPath(path.toLocal8Bit().data());
// update directory // update file name and directory
QFileInfo fileInfo(path);
m_lastDir = m_currentDir; m_lastDir = m_currentDir;
m_currentDir = QString::fromLocal8Bit(m_fileInfo.containingDirectory().c_str()); m_currentDir = fileInfo.absolutePath();
m_fileName = fileInfo.fileName();
} }
// update availability of making results // update availability of making results
m_makingResultsAvailable &= sameFile; m_makingResultsAvailable &= sameFile;
@ -748,7 +751,7 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh)
m_originalNotifications.clear(); m_originalNotifications.clear();
} }
// show filename // show filename
m_ui->fileNameLabel->setText(QString::fromLocal8Bit(m_fileInfo.fileName().c_str())); m_ui->fileNameLabel->setText(m_fileName);
// define function to parse the file // define function to parse the file
auto startThread = [this] { auto startThread = [this] {
char result; char result;
@ -829,7 +832,7 @@ void TagEditorWidget::showFile(char result)
auto msgBox = new QMessageBox(this); auto msgBox = new QMessageBox(this);
msgBox->setIcon(QMessageBox::Critical); msgBox->setIcon(QMessageBox::Critical);
msgBox->setAttribute(Qt::WA_DeleteOnClose, true); msgBox->setAttribute(Qt::WA_DeleteOnClose, true);
msgBox->setWindowTitle(tr("Opening file - %1").arg(QCoreApplication::applicationName())); msgBox->setWindowTitle(tr("Opening file - ") + QCoreApplication::applicationName());
msgBox->setText(statusMsg); msgBox->setText(statusMsg);
msgBox->setInformativeText(tr("Opening file: ") + m_currentPath); msgBox->setInformativeText(tr("Opening file: ") + m_currentPath);
msgBox->show(); msgBox->show();
@ -911,9 +914,11 @@ void TagEditorWidget::showFile(char result)
updateTagEditsAndAttachmentEdits(); updateTagEditsAndAttachmentEdits();
updateTagSelectionComboBox(); updateTagSelectionComboBox();
updateTagManagementMenu(); updateTagManagementMenu();
emit tagValuesLoaded();
insertTitleFromFilename(); insertTitleFromFilename();
emit statusMessage(tr("The file %1 has been opened.").arg(m_currentPath));
updateFileStatusStatus(); updateFileStatusStatus();
emit statusMessage(tr("The file %1 has been opened.").arg(m_currentPath));
emit fileShown();
} }
} }

View File

@ -85,10 +85,16 @@ signals:
void nextFileSelected(); void nextFileSelected();
/// \brief Emitted to show a status message. /// \brief Emitted to show a status message.
void statusMessage(const QString &message, int timeout = 0); void statusMessage(const QString &message, int timeout = 0);
/// \brief Emmited when the file status (opened/closed) has changed. /// \brief Emitted when the file status (opened/closed) has changed.
void fileStatusChanged(bool opened, bool hasTag); void fileStatusChanged(bool opened, bool hasTag);
/// \brief Emitted when the current path has changed; always emitted a saving. /// \brief Emitted when the current path has changed; always emitted a saving.
void currentPathChanged(const QString &newPath); void currentPathChanged(const QString &newPath);
/// \brief Emitted when all tag values have been parsed and loaded into tag edits.
/// \remarks In particular, this is emitted *before* any additional data is inserted (like title from file name).
void tagValuesLoaded();
/// \brief Emitted when a file has been shown (file is parsed and all widgets have been updated accordingly).
/// \remarks In particular, this is emitted *after* additional data (like title from file name) might have been inserted.
void fileShown();
protected: protected:
bool event(QEvent *event); bool event(QEvent *event);
@ -142,6 +148,7 @@ private:
Media::MediaFileInfo m_fileInfo; Media::MediaFileInfo m_fileInfo;
std::vector<Media::Tag *> m_tags; std::vector<Media::Tag *> m_tags;
QByteArray m_fileInfoHtml; QByteArray m_fileInfoHtml;
QString m_fileName;
QString m_currentDir; QString m_currentDir;
QString m_lastDir; QString m_lastDir;
QString m_saveFilePath; QString m_saveFilePath;
@ -162,7 +169,7 @@ inline bool TagEditorWidget::fileOperationOngoing() const
} }
/*! /*!
* \brief Returns the current path. * \brief Returns the path of the currently opened file including filename.
*/ */
inline const QString &TagEditorWidget::currentPath() const inline const QString &TagEditorWidget::currentPath() const
{ {
@ -170,8 +177,8 @@ inline const QString &TagEditorWidget::currentPath() const
} }
/*! /*!
* \brief Returns the current directory. * \brief Returns the path of the currently opened file excluding filename.
* \remarks This is the actual direcotry of the opened file which may differ from the directory selected in the tree view of the main window. * \remarks This is the actual directory of the opened file which may differ from the directory selected in the tree view of the main window.
*/ */
inline const QString &TagEditorWidget::currentDir() const inline const QString &TagEditorWidget::currentDir() const
{ {