diff --git a/gui/dbquerywidget.cpp b/gui/dbquerywidget.cpp index f9cdde8..8af57d5 100644 --- a/gui/dbquerywidget.cpp +++ b/gui/dbquerywidget.cpp @@ -281,6 +281,10 @@ void DbQueryWidget::applyMatchingResults() */ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit) { + if(!m_model) { + return; + } + // determine already present title, album and artist const TagValue givenTitle = tagEdit->value(KnownField::Title); const TagValue givenAlbum = tagEdit->value(KnownField::Album); @@ -291,6 +295,7 @@ void DbQueryWidget::applyMatchingResults(TagEdit *tagEdit) try { givenTrack = tagEdit->value(KnownField::TrackPosition).toPositionInSet().position(); } catch (const ConversionException &) { + givenTrack = 0; } if(!givenTrack) { 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 for(int row = 0, rowCount = m_model->rowCount(); row != rowCount; ++row) { if((!givenTitle.isEmpty() && givenTitle != m_model->fieldValue(row, KnownField::Title)) || (!givenAlbum.isEmpty() && givenAlbum != m_model->fieldValue(row, KnownField::Album)) || (!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; } @@ -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. * \remarks diff --git a/gui/dbquerywidget.h b/gui/dbquerywidget.h index 7365a4a..2d4c2c6 100644 --- a/gui/dbquerywidget.h +++ b/gui/dbquerywidget.h @@ -43,6 +43,7 @@ public slots: void applySelectedResults(); void applyMatchingResults(); void applyMatchingResults(TagEdit *tagEdit); + void autoInsertMatchingResults(); void insertSearchTermsFromActiveTagEdit(); void clearSearchCriteria(); diff --git a/gui/dbquerywidget.ui b/gui/dbquerywidget.ui index 89aa403..bf59107 100644 --- a/gui/dbquerywidget.ui +++ b/gui/dbquerywidget.ui @@ -208,14 +208,31 @@ - - - Override existing values - - - true - - + + + + + Whether existing values of selected "Fields to be used" should be overridden with values from search result + + + Override existing values + + + true + + + + + + + Whether matching values for selected "Fields to be used" from the search result should be inserted automatically when opening a file + + + Insert automatically + + + + @@ -267,6 +284,9 @@ 0 + + Aborts the current query + Abort @@ -280,6 +300,9 @@ 0 + + Searches MusicBrainz for meta data matching the specified "Search criteria" + Search MusicBrainz @@ -298,6 +321,9 @@ MusicBrainz 0 + + Searches LyricWikia for meta data matching the specified "Search criteria" + Search LyricWikia @@ -320,7 +346,7 @@ LyricWikia - Inserts the selected result into the current tag (doesn't save anything) + Inserts values of "Fields to be used" from the selected result into the current tag but does not save anything Use selected diff --git a/gui/mainwindow.cpp b/gui/mainwindow.cpp index 9bfe4c4..c8139f6 100644 --- a/gui/mainwindow.cpp +++ b/gui/mainwindow.cpp @@ -111,7 +111,7 @@ MainWindow::MainWindow(QWidget *parent) : // dbquery dock widget if(settings.dbQuery.widgetShown) { - m_ui->dbQueryDockWidget->setWidget(m_dbQueryWidget = new DbQueryWidget(m_ui->tagEditorWidget, this)); + initDbQueryWidget(); } // 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(&DbQueryWidget::autoInsertMatchingResults), Qt::DirectConnection); + } +} + /*! * \brief Toggles visibility of the database query widget. */ void MainWindow::toggleDbQueryWidget() { - if(!m_dbQueryWidget) { - m_ui->dbQueryDockWidget->setWidget(m_dbQueryWidget = new DbQueryWidget(m_ui->tagEditorWidget, this)); - } + initDbQueryWidget(); m_ui->dbQueryDockWidget->setVisible(m_ui->dbQueryDockWidget->isHidden()); } diff --git a/gui/mainwindow.h b/gui/mainwindow.h index fbbf464..44726e3 100644 --- a/gui/mainwindow.h +++ b/gui/mainwindow.h @@ -76,6 +76,7 @@ private slots: void showAboutDlg(); void showRenameFilesDlg(); void spawnExternalPlayer(); + void initDbQueryWidget(); void toggleDbQueryWidget(); private: diff --git a/gui/tagedit.cpp b/gui/tagedit.cpp index 375b86e..bd6b4f0 100644 --- a/gui/tagedit.cpp +++ b/gui/tagedit.cpp @@ -55,10 +55,10 @@ TagEdit::TagEdit(QWidget *parent) : * \brief Returns the current value for the specified \a field. * \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)) { - return edit->value(TagTextEncoding::Utf16LittleEndian, false); + return edit->value(encoding, false); } else { return TagValue(); } diff --git a/gui/tagedit.h b/gui/tagedit.h index ecc8a15..e77fbc3 100644 --- a/gui/tagedit.h +++ b/gui/tagedit.h @@ -3,7 +3,7 @@ #include "./previousvaluehandling.h" -#include +#include #include #include @@ -32,7 +32,7 @@ class TagEdit : public QWidget public: explicit TagEdit(QWidget *parent = nullptr); const QList &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 setTags(const QList &tags, bool updateUi = true); bool setValue(Media::KnownField field, const Media::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear); diff --git a/gui/tageditorwidget.cpp b/gui/tageditorwidget.cpp index 4daa174..ba533b7 100644 --- a/gui/tageditorwidget.cpp +++ b/gui/tageditorwidget.cpp @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include @@ -558,14 +559,14 @@ void TagEditorWidget::updateTagManagementMenu() /*! * \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() { if(!m_tags.empty() && Settings::values().editor.autoCompletition.insertTitleFromFilename) { QString title; int trackNum; - parseFileName(QString::fromLocal8Bit(m_fileInfo.fileName().c_str()), title, trackNum); + parseFileName(m_fileName, title, trackNum); const TagValue titleValue = qstringToTagValue(title, TagTextEncoding::Utf16LittleEndian); foreachTagEdit([&titleValue] (TagEdit *edit) { for(const Tag *tag : edit->tags()) { @@ -738,9 +739,11 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh) m_currentPath = path; m_fileInfo.setSaveFilePath(string()); m_fileInfo.setPath(path.toLocal8Bit().data()); - // update directory + // update file name and directory + QFileInfo fileInfo(path); 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 m_makingResultsAvailable &= sameFile; @@ -748,7 +751,7 @@ bool TagEditorWidget::startParsing(const QString &path, bool forceRefresh) m_originalNotifications.clear(); } // 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 auto startThread = [this] { char result; @@ -829,7 +832,7 @@ void TagEditorWidget::showFile(char result) auto msgBox = new QMessageBox(this); msgBox->setIcon(QMessageBox::Critical); 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->setInformativeText(tr("Opening file: ") + m_currentPath); msgBox->show(); @@ -911,9 +914,11 @@ void TagEditorWidget::showFile(char result) updateTagEditsAndAttachmentEdits(); updateTagSelectionComboBox(); updateTagManagementMenu(); + emit tagValuesLoaded(); insertTitleFromFilename(); - emit statusMessage(tr("The file %1 has been opened.").arg(m_currentPath)); updateFileStatusStatus(); + emit statusMessage(tr("The file %1 has been opened.").arg(m_currentPath)); + emit fileShown(); } } diff --git a/gui/tageditorwidget.h b/gui/tageditorwidget.h index 4fbcf5a..7f34e78 100644 --- a/gui/tageditorwidget.h +++ b/gui/tageditorwidget.h @@ -85,10 +85,16 @@ signals: void nextFileSelected(); /// \brief Emitted to show a status message. 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); /// \brief Emitted when the current path has changed; always emitted a saving. 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: bool event(QEvent *event); @@ -142,6 +148,7 @@ private: Media::MediaFileInfo m_fileInfo; std::vector m_tags; QByteArray m_fileInfoHtml; + QString m_fileName; QString m_currentDir; QString m_lastDir; 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 { @@ -170,8 +177,8 @@ inline const QString &TagEditorWidget::currentPath() const } /*! - * \brief Returns the current directory. - * \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. + * \brief Returns the path of the currently opened file excluding filename. + * \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 {