Add info about auto-correction when opening file
This commit is contained in:
parent
ef82a88a97
commit
cf71ac5dca
|
@ -92,16 +92,19 @@ PicturePreviewSelection::~PicturePreviewSelection()
|
|||
*
|
||||
* Used for editing tags programmatically, eg. in TagEditorWidget::insertTitleFromFilename() and DbQueryWidget::applyResults().
|
||||
*/
|
||||
void PicturePreviewSelection::setValue(const TagValue &value, PreviousValueHandling previousValueHandling)
|
||||
bool PicturePreviewSelection::setValue(const TagValue &value, PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
assert(m_currentTypeIndex < m_values.size());
|
||||
TagValue ¤tValue = m_values[m_currentTypeIndex];
|
||||
bool updated = false;
|
||||
if ((previousValueHandling == PreviousValueHandling::Clear || !value.isEmpty())
|
||||
&& (previousValueHandling != PreviousValueHandling::Keep || currentValue.isEmpty())) {
|
||||
currentValue = value; // TODO: move(value);
|
||||
updated = true;
|
||||
emit pictureChanged();
|
||||
}
|
||||
updatePreview(m_currentTypeIndex);
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -153,7 +156,7 @@ int fetchId3v2CoverValues(
|
|||
/*!
|
||||
* \brief Sets the widget up.
|
||||
*/
|
||||
void PicturePreviewSelection::setup(PreviousValueHandling previousValueHandling)
|
||||
bool PicturePreviewSelection::setup(PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
if (previousValueHandling == PreviousValueHandling::Auto) {
|
||||
previousValueHandling = PreviousValueHandling::Update;
|
||||
|
@ -161,7 +164,7 @@ void PicturePreviewSelection::setup(PreviousValueHandling previousValueHandling)
|
|||
m_currentTypeIndex = 0;
|
||||
if (!m_tag) {
|
||||
setEnabled(false);
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
if (m_field == KnownField::Cover && (m_tag->type() == TagType::Id3v2Tag || m_tag->type() == TagType::VorbisComment)) {
|
||||
m_ui->switchTypeComboBox->setHidden(false);
|
||||
|
@ -219,6 +222,7 @@ void PicturePreviewSelection::setup(PreviousValueHandling previousValueHandling)
|
|||
updatePreview(m_currentTypeIndex);
|
||||
updateDescription(m_currentTypeIndex);
|
||||
setEnabled(true);
|
||||
return true;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -42,8 +42,8 @@ public:
|
|||
TagParser::KnownField field() const;
|
||||
|
||||
public slots:
|
||||
void setTagField(TagParser::Tag *tag, TagParser::KnownField field, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
void setValue(const TagParser::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
bool setTagField(TagParser::Tag *tag, TagParser::KnownField field, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
bool setValue(const TagParser::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
|
||||
void apply();
|
||||
void clear();
|
||||
|
@ -77,7 +77,7 @@ private slots:
|
|||
void showContextMenu();
|
||||
|
||||
private:
|
||||
void setup(PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
bool setup(PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
void updateSizeAndMimeType(std::size_t fileSize, const QSize &resolution, const QString &mimeType);
|
||||
|
||||
std::unique_ptr<Ui::PicturePreviewSelection> m_ui;
|
||||
|
@ -118,11 +118,11 @@ inline TagParser::KnownField PicturePreviewSelection::field() const
|
|||
*
|
||||
* If \a tag is nullptr the widget is disabled. The widget will be re-setup.
|
||||
*/
|
||||
inline void PicturePreviewSelection::setTagField(TagParser::Tag *tag, TagParser::KnownField field, PreviousValueHandling previousValueHandling)
|
||||
inline bool PicturePreviewSelection::setTagField(TagParser::Tag *tag, TagParser::KnownField field, PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
m_tag = tag;
|
||||
m_field = field;
|
||||
setup(previousValueHandling);
|
||||
return setup(previousValueHandling);
|
||||
}
|
||||
|
||||
} // namespace QtGui
|
||||
|
|
|
@ -174,6 +174,16 @@ bool TagEdit::hasField(KnownField field) const
|
|||
return false;
|
||||
}
|
||||
|
||||
bool TagEdit::hasAutoCorrectionBeenApplied() const
|
||||
{
|
||||
for (auto i = m_widgets.constBegin(), end = m_widgets.constEnd(); i != end; ++i) {
|
||||
if (i.value()->hasAutoCorrectionBeenApplied()) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Generates a label for the currently assigned tags.
|
||||
*
|
||||
|
|
|
@ -44,6 +44,7 @@ public:
|
|||
void setPreviousValueHandling(PreviousValueHandling previousValueHandling);
|
||||
TagFieldEdit *tagFieldEdit(TagParser::KnownField field) const;
|
||||
QString generateLabel() const;
|
||||
bool hasAutoCorrectionBeenApplied() const;
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
|
|
@ -262,6 +262,7 @@ bool TagEditorWidget::event(QEvent *event)
|
|||
return true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:;
|
||||
}
|
||||
|
@ -332,6 +333,7 @@ void TagEditorWidget::updateTagEditsAndAttachmentEdits(bool updateUi, PreviousVa
|
|||
break;
|
||||
default:;
|
||||
}
|
||||
|
||||
// define helper function to fetch next edit
|
||||
TagEdit *edit; // holds current edit
|
||||
int widgetIndex = 0; // holds index of current edit in the stacked widget
|
||||
|
@ -348,6 +350,7 @@ void TagEditorWidget::updateTagEditsAndAttachmentEdits(bool updateUi, PreviousVa
|
|||
// apply settings
|
||||
edit->setPreviousValueHandling(previousValueHandling);
|
||||
};
|
||||
|
||||
// add/update TagEdit widgets
|
||||
if (m_tags.size()) {
|
||||
// create a lists of the targets and tags
|
||||
|
@ -364,12 +367,16 @@ void TagEditorWidget::updateTagEditsAndAttachmentEdits(bool updateUi, PreviousVa
|
|||
}
|
||||
}
|
||||
// create a singe editor per target or seperate editors for each tag depending on the settings
|
||||
bool hasAutoCorrectionBeenApplied = false;
|
||||
switch (Settings::values().editor.multipleTagHandling) {
|
||||
case Settings::MultipleTagHandling::SingleEditorPerTarget:
|
||||
// iterate through all targets in both cases
|
||||
for (int targetIndex = 0, targetCount = targets.size(); targetIndex < targetCount; ++targetIndex) {
|
||||
fetchNextEdit();
|
||||
edit->setTags(tagsByTarget.at(targetIndex), updateUi); // set all tags with the same target to a single edit
|
||||
if (!hasAutoCorrectionBeenApplied) {
|
||||
hasAutoCorrectionBeenApplied = edit->hasAutoCorrectionBeenApplied();
|
||||
}
|
||||
++widgetIndex;
|
||||
}
|
||||
break;
|
||||
|
@ -379,17 +386,24 @@ void TagEditorWidget::updateTagEditsAndAttachmentEdits(bool updateUi, PreviousVa
|
|||
for (Tag *tag : tagsByTarget.at(targetIndex)) {
|
||||
fetchNextEdit();
|
||||
edit->setTag(tag, updateUi); // use a separate edit for each tag
|
||||
if (!hasAutoCorrectionBeenApplied) {
|
||||
hasAutoCorrectionBeenApplied = edit->hasAutoCorrectionBeenApplied();
|
||||
}
|
||||
++widgetIndex;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (hasAutoCorrectionBeenApplied) {
|
||||
addParsingNotificationLine(tr("Some values have been changed by the auto-correction."));
|
||||
}
|
||||
} else {
|
||||
// there are no tags -> leave one edit existend but ensure no tags are assigned
|
||||
fetchNextEdit();
|
||||
edit->setTag(nullptr, false);
|
||||
++widgetIndex;
|
||||
}
|
||||
|
||||
// add/update AttachmentsEdit widget
|
||||
if (m_fileInfo.areAttachmentsSupported()) {
|
||||
AttachmentsEdit *edit;
|
||||
|
@ -406,6 +420,7 @@ void TagEditorWidget::updateTagEditsAndAttachmentEdits(bool updateUi, PreviousVa
|
|||
}
|
||||
++widgetIndex;
|
||||
}
|
||||
|
||||
// remove surplus edits
|
||||
while (widgetIndex < m_ui->stackedWidget->count()) {
|
||||
QWidget *toRemove = m_ui->stackedWidget->widget(widgetIndex);
|
||||
|
@ -609,19 +624,26 @@ void TagEditorWidget::updateKeepPreviousValuesButton()
|
|||
*/
|
||||
void TagEditorWidget::insertTitleFromFilename()
|
||||
{
|
||||
if (!m_tags.empty() && Settings::values().editor.autoCompletition.insertTitleFromFilename) {
|
||||
QString title;
|
||||
int trackNum;
|
||||
parseFileName(m_fileName, title, trackNum);
|
||||
const TagValue titleValue = qstringToTagValue(title, TagTextEncoding::Utf16LittleEndian);
|
||||
foreachTagEdit([&titleValue](TagEdit *edit) {
|
||||
for (const Tag *tag : edit->tags()) {
|
||||
if (tag->supportsTarget() && tag->isTargetingLevel(TagTargetLevel::Part)) {
|
||||
return;
|
||||
}
|
||||
if (m_tags.empty() || !Settings::values().editor.autoCompletition.insertTitleFromFilename) {
|
||||
return;
|
||||
}
|
||||
QString title;
|
||||
int trackNum;
|
||||
parseFileName(m_fileName, title, trackNum);
|
||||
const auto titleValue = qstringToTagValue(title, TagTextEncoding::Utf16LittleEndian);
|
||||
auto updated = false;
|
||||
foreachTagEdit([&titleValue, &updated](TagEdit *const edit) {
|
||||
for (const auto *const tag : edit->tags()) {
|
||||
if (tag->supportsTarget() && tag->isTargetingLevel(TagTargetLevel::Part)) {
|
||||
return;
|
||||
}
|
||||
edit->setValue(KnownField::Title, titleValue, PreviousValueHandling::Keep);
|
||||
});
|
||||
}
|
||||
if (edit->setValue(KnownField::Title, titleValue, PreviousValueHandling::Keep)) {
|
||||
updated = true;
|
||||
}
|
||||
});
|
||||
if (updated) {
|
||||
addParsingNotificationLine(tr("Inserted title from filename."));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1414,6 +1436,11 @@ void TagEditorWidget::applySettingsFromDialog()
|
|||
updateInfoView();
|
||||
}
|
||||
|
||||
void TagEditorWidget::addParsingNotificationLine(const QString &line)
|
||||
{
|
||||
m_ui->parsingNotificationWidget->appendLine(line);
|
||||
}
|
||||
|
||||
/*!
|
||||
* \brief Adds a tag (using the specified \a createTag function) to the currently opened file.
|
||||
*
|
||||
|
|
|
@ -75,6 +75,7 @@ public slots:
|
|||
void openFileInfoInBrowser();
|
||||
// misc
|
||||
void applySettingsFromDialog();
|
||||
void addParsingNotificationLine(const QString &line);
|
||||
|
||||
signals:
|
||||
/// \brief Emitted when loading the next file has been triggered.
|
||||
|
|
|
@ -170,11 +170,11 @@ TagValue TagFieldEdit::value(TagTextEncoding encoding, bool includeDescription)
|
|||
*/
|
||||
bool TagFieldEdit::setValue(const TagValue &value, PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
updateValue(value, previousValueHandling, false);
|
||||
bool updated = updateValue(value, previousValueHandling, false);
|
||||
if (m_pictureSelection) {
|
||||
m_pictureSelection->setValue(value, previousValueHandling);
|
||||
updated = m_pictureSelection->setValue(value, previousValueHandling) || updated;
|
||||
}
|
||||
return true;
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -510,7 +510,7 @@ QLabel *TagFieldEdit::setupTypeNotSupportedLabel()
|
|||
*
|
||||
* The new value is read from the assigned tag(s).
|
||||
*/
|
||||
void TagFieldEdit::updateValue(PreviousValueHandling previousValueHandling)
|
||||
bool TagFieldEdit::updateValue(PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
// use the values from the last tag which has the specified field
|
||||
for (auto i = tags().crbegin(), end = tags().crend(); i != end; ++i) {
|
||||
|
@ -521,19 +521,20 @@ void TagFieldEdit::updateValue(PreviousValueHandling previousValueHandling)
|
|||
continue;
|
||||
}
|
||||
|
||||
updateValue(value, previousValueHandling);
|
||||
bool updated = updateValue(value, previousValueHandling);
|
||||
if (m_pictureSelection) {
|
||||
m_pictureSelection->setTagField(tag, m_field, previousValueHandling);
|
||||
updated = m_pictureSelection->setTagField(tag, m_field, previousValueHandling) || updated;
|
||||
}
|
||||
return;
|
||||
return updated;
|
||||
}
|
||||
|
||||
// set an empty value
|
||||
updateValue(TagValue(), previousValueHandling);
|
||||
bool updated = updateValue(TagValue(), previousValueHandling);
|
||||
if (m_pictureSelection) {
|
||||
// pass the last tag if present so the picture selection can operate on that tag instance and won't be disabled
|
||||
m_pictureSelection->setTagField(m_tags->isEmpty() ? nullptr : m_tags->back(), m_field, previousValueHandling);
|
||||
updated = m_pictureSelection->setTagField(m_tags->isEmpty() ? nullptr : m_tags->back(), m_field, previousValueHandling) || updated;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -542,12 +543,13 @@ void TagFieldEdit::updateValue(PreviousValueHandling previousValueHandling)
|
|||
* \param previousValueHandling Specifies how to deal with the previous value.
|
||||
* \remarks If \a tag is nullptr, the new value is empty.
|
||||
*/
|
||||
void TagFieldEdit::updateValue(Tag *tag, PreviousValueHandling previousValueHandling)
|
||||
bool TagFieldEdit::updateValue(Tag *tag, PreviousValueHandling previousValueHandling)
|
||||
{
|
||||
updateValue(tag ? tag->value(m_field) : TagValue::empty(), previousValueHandling);
|
||||
bool updated = updateValue(tag ? tag->value(m_field) : TagValue::empty(), previousValueHandling);
|
||||
if (m_pictureSelection) {
|
||||
m_pictureSelection->setTagField(tag, m_field, previousValueHandling);
|
||||
updated = m_pictureSelection->setTagField(tag, m_field, previousValueHandling) || updated;
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -557,8 +559,9 @@ void TagFieldEdit::updateValue(Tag *tag, PreviousValueHandling previousValueHand
|
|||
* \param updateRestoreButton Specifies whether the "restore button" should be updated.
|
||||
* \remarks Does not update the picture preview selection.
|
||||
*/
|
||||
void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling previousValueHandling, bool updateRestoreButton)
|
||||
bool TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling previousValueHandling, bool updateRestoreButton)
|
||||
{
|
||||
bool autoCorrectionApplied = false;
|
||||
bool conversionError = false;
|
||||
bool updated = false;
|
||||
concretizePreviousValueHandling(previousValueHandling);
|
||||
|
@ -567,9 +570,12 @@ void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling prev
|
|||
if (m_lineEdit || m_comboBox || m_plainTextEdit) {
|
||||
const auto text([&] {
|
||||
try {
|
||||
auto text(Utility::tagValueToQString(value));
|
||||
applyAutoCorrection(text);
|
||||
return text;
|
||||
const auto text(Utility::tagValueToQString(value));
|
||||
const auto correctedText = applyAutoCorrection(text);
|
||||
if (correctedText != text) {
|
||||
autoCorrectionApplied = true;
|
||||
}
|
||||
return correctedText;
|
||||
} catch (const ConversionException &) {
|
||||
conversionError = true;
|
||||
return QString();
|
||||
|
@ -651,10 +657,13 @@ void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling prev
|
|||
m_descriptionLineEdit->setEnabled(true);
|
||||
if (previousValueHandling != PreviousValueHandling::Keep || m_descriptionLineEdit->isCleared()) {
|
||||
try {
|
||||
auto desc = Utility::stringToQString(value.description(), value.descriptionEncoding());
|
||||
applyAutoCorrection(desc);
|
||||
if (!m_isLocked || desc.isEmpty()) {
|
||||
m_descriptionLineEdit->setText(desc);
|
||||
const auto desc = Utility::stringToQString(value.description(), value.descriptionEncoding());
|
||||
const auto correctedDesc = applyAutoCorrection(desc);
|
||||
if (correctedDesc != desc) {
|
||||
autoCorrectionApplied = true;
|
||||
}
|
||||
if (!m_isLocked || correctedDesc.isEmpty()) {
|
||||
m_descriptionLineEdit->setText(correctedDesc);
|
||||
}
|
||||
} catch (const ConversionException &) {
|
||||
conversionError = true;
|
||||
|
@ -673,6 +682,7 @@ void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling prev
|
|||
if (updated) {
|
||||
setLocked(false);
|
||||
}
|
||||
m_autoCorrectionApplied = updated && autoCorrectionApplied;
|
||||
|
||||
// setup info button
|
||||
const auto widgets = initializer_list<ButtonOverlay *>{ m_lineEdit, m_comboBox, m_spinBoxes.first, m_spinBoxes.second };
|
||||
|
@ -683,7 +693,7 @@ void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling prev
|
|||
overlay->disableInfoButton();
|
||||
}
|
||||
}
|
||||
return;
|
||||
return updated;
|
||||
}
|
||||
const auto pixmap(
|
||||
QIcon::fromTheme(QStringLiteral("emblem-error"), QIcon(QStringLiteral(":/qtutilities/icons/hicolor/48x48/actions/edit-error.png")))
|
||||
|
@ -706,6 +716,7 @@ void TagFieldEdit::updateValue(const TagValue &value, PreviousValueHandling prev
|
|||
overlay->enableInfoButton(pixmap, text);
|
||||
}
|
||||
}
|
||||
return updated;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
@ -756,8 +767,9 @@ void TagFieldEdit::showRestoreButton()
|
|||
/*!
|
||||
* \brief Applies auto correction (according to the settings) for the specified \a textValue.
|
||||
*/
|
||||
void TagFieldEdit::applyAutoCorrection(QString &textValue)
|
||||
QString TagFieldEdit::applyAutoCorrection(const QString &textValue)
|
||||
{
|
||||
QString correctedValue = textValue;
|
||||
const auto &settings = Settings::values().editor.autoCompletition;
|
||||
auto &fields = settings.fields.items();
|
||||
auto i = find_if(fields.constBegin(), fields.constEnd(), [this](const ChecklistItem &item) {
|
||||
|
@ -766,17 +778,18 @@ void TagFieldEdit::applyAutoCorrection(QString &textValue)
|
|||
});
|
||||
// if current field is in the list of auto correction fields and auto correction should be applied
|
||||
if (i == fields.constEnd() || !i->isChecked()) {
|
||||
return;
|
||||
return correctedValue;
|
||||
}
|
||||
if (settings.trimWhitespaces) {
|
||||
textValue = textValue.trimmed();
|
||||
}
|
||||
if (settings.fixUmlauts) {
|
||||
textValue = Utility::fixUmlauts(textValue);
|
||||
correctedValue = correctedValue.trimmed();
|
||||
}
|
||||
if (settings.formatNames) {
|
||||
textValue = Utility::formatName(textValue);
|
||||
correctedValue = Utility::formatName(correctedValue);
|
||||
}
|
||||
if (settings.fixUmlauts) {
|
||||
correctedValue = Utility::fixUmlauts(correctedValue);
|
||||
}
|
||||
return correctedValue;
|
||||
}
|
||||
|
||||
/*!
|
||||
|
|
|
@ -49,6 +49,7 @@ public:
|
|||
bool isLocked() const;
|
||||
void setLocked(bool locked);
|
||||
void toggleLocked();
|
||||
bool hasAutoCorrectionBeenApplied() const;
|
||||
|
||||
public slots:
|
||||
void clear();
|
||||
|
@ -79,14 +80,14 @@ private:
|
|||
QWidget *setupFileSelection();
|
||||
Widgets::ClearLineEdit *setupDescriptionLineEdit();
|
||||
QLabel *setupTypeNotSupportedLabel();
|
||||
void updateValue(PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
void updateValue(TagParser::Tag *tag, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
void updateValue(
|
||||
bool updateValue(PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
bool updateValue(TagParser::Tag *tag, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear);
|
||||
bool updateValue(
|
||||
const TagParser::TagValue &value, PreviousValueHandling previousValueHandling = PreviousValueHandling::Clear, bool resetRestoreButton = true);
|
||||
Widgets::IconButton *setupRestoreButton();
|
||||
Widgets::IconButton *setupLockButton();
|
||||
void showRestoreButton();
|
||||
void applyAutoCorrection(QString &textValue);
|
||||
QString applyAutoCorrection(const QString &textValue);
|
||||
void concretizePreviousValueHandling(PreviousValueHandling &previousValueHandling);
|
||||
|
||||
QVBoxLayout *m_layout;
|
||||
|
@ -103,6 +104,7 @@ private:
|
|||
Widgets::IconButton *m_restoreButton;
|
||||
Widgets::IconButton *m_lockButton;
|
||||
bool m_isLocked;
|
||||
bool m_autoCorrectionApplied;
|
||||
};
|
||||
|
||||
inline const QList<TagParser::Tag *> &TagFieldEdit::tags() const
|
||||
|
@ -125,6 +127,11 @@ inline void TagFieldEdit::toggleLocked()
|
|||
setLocked(!isLocked());
|
||||
}
|
||||
|
||||
inline bool TagFieldEdit::hasAutoCorrectionBeenApplied() const
|
||||
{
|
||||
return m_autoCorrectionApplied;
|
||||
}
|
||||
|
||||
} // namespace QtGui
|
||||
|
||||
#endif // QTGUI_TAGFIELDLINEEDIT_H
|
||||
|
|
Loading…
Reference in New Issue