diff --git a/core/utilities/setup/metadata/namespaceeditdlg.cpp b/core/utilities/setup/metadata/namespaceeditdlg.cpp index 1694b99dca..9b88a4ea2b 100644 --- a/core/utilities/setup/metadata/namespaceeditdlg.cpp +++ b/core/utilities/setup/metadata/namespaceeditdlg.cpp @@ -1,683 +1,683 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2015-07-03 * Description : dialog to edit and create digiKam xmp namespaces * * Copyright (C) 2015 by Veaceslav Munteanu * * This program 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, or (at your option) * any later version. * * This program 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. * * ============================================================ */ #include "namespaceeditdlg.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // Local includes #include "dxmlguiwindow.h" #include "digikam_debug.h" namespace Digikam { class Q_DECL_HIDDEN NamespaceEditDlg::Private { public: explicit Private() : buttons(nullptr), create(0), topLabel(nullptr), logo(nullptr), gridLayout(nullptr), page(nullptr), - subspaceCombo(nullptr), // NamespaceEntry variables + subspaceCombo(nullptr), ///< NamespaceEntry variables specialOptsCombo(nullptr), altSpecialOptsCombo(nullptr), namespaceName(nullptr), alternativeName(nullptr), nameSpaceSeparator(nullptr), isPath(nullptr), ratingMappings(nullptr), zeroStars(nullptr), oneStar(nullptr), twoStars(nullptr), threeStars(nullptr), fourStars(nullptr), fiveStars(nullptr), - tagTipLabel(nullptr), // Labels + tagTipLabel(nullptr), ///< Labels ratingTipLabel(nullptr), commentTipLabel(nullptr), subspaceLabel(nullptr), titleLabel(nullptr), specialOptsLabel(nullptr), alternativeNameLabel(nullptr), altspecialOptsLabel(nullptr), isTagLabel(nullptr), separatorLabel(nullptr), tipLabel2(nullptr), nsType(NamespaceEntry::TAGS) { } QDialogButtonBox* buttons; bool create; QLabel* topLabel; QLabel* logo; QGridLayout* gridLayout; QWidget* page; - // NamespaceEntry variables + /// NamespaceEntry variables QComboBox* subspaceCombo; QComboBox* specialOptsCombo; QComboBox* altSpecialOptsCombo; QLineEdit* namespaceName; QLineEdit* alternativeName; QLineEdit* nameSpaceSeparator; QCheckBox* isPath; QGroupBox* ratingMappings; QSpinBox* zeroStars; QSpinBox* oneStar; QSpinBox* twoStars; QSpinBox* threeStars; QSpinBox* fourStars; QSpinBox* fiveStars; - // Labels + /// Labels QLabel* tagTipLabel; QLabel* ratingTipLabel; QLabel* commentTipLabel; QLabel* subspaceLabel; QLabel* titleLabel; QLabel* specialOptsLabel; QLabel* alternativeNameLabel; QLabel* altspecialOptsLabel; QLabel* isTagLabel; QLabel* separatorLabel; QLabel* tipLabel2; NamespaceEntry::NamespaceType nsType; }; NamespaceEditDlg::NamespaceEditDlg(bool create, NamespaceEntry& entry, QWidget* const parent) : QDialog(parent), d(new Private()) { setModal(true); d->buttons = new QDialogButtonBox(QDialogButtonBox::Help | QDialogButtonBox::Ok | QDialogButtonBox::Cancel, this); d->buttons->button(QDialogButtonBox::Ok)->setDefault(true); if (create) { setWindowTitle(i18n("New Xmp Namespace")); } else { setWindowTitle(i18n("Edit Xmp Namespace")); } d->create = create; d->nsType = entry.nsType; setupTagGui(entry); // --- NOTE: use dynamic binding as slots below are virtual method which can be re-implemented in derived classes. connect(d->buttons->button(QDialogButtonBox::Ok), &QPushButton::clicked, this, &NamespaceEditDlg::accept); connect(d->buttons->button(QDialogButtonBox::Cancel), &QPushButton::clicked, this, &NamespaceEditDlg::reject); connect(d->buttons->button(QDialogButtonBox::Help), &QPushButton::clicked, this, &NamespaceEditDlg::slotHelp); // -------------------------------------------------------- if (!d->create) { populateFields(entry); } setType(entry.nsType); if (entry.isDefault) { makeReadOnly(); } qCDebug(DIGIKAM_GENERAL_LOG) << "Entry type" << entry.nsType << "subspace" << entry.subspace << entry.isDefault; adjustSize(); } NamespaceEditDlg::~NamespaceEditDlg() { delete d; } bool NamespaceEditDlg::create(QWidget* const parent, NamespaceEntry& entry) { QPointer dlg = new NamespaceEditDlg(true,entry,parent); qCDebug(DIGIKAM_GENERAL_LOG) << "Name before save: " << entry.namespaceName; bool valRet = dlg->exec(); if (valRet == QDialog::Accepted) { dlg->saveData(entry); } qCDebug(DIGIKAM_GENERAL_LOG) << "Name after save: " << entry.namespaceName; delete dlg; return valRet; } bool NamespaceEditDlg::edit(QWidget* const parent, NamespaceEntry& entry) { QPointer dlg = new NamespaceEditDlg(false, entry, parent); qCDebug(DIGIKAM_GENERAL_LOG) << "Name before save: " << entry.namespaceName; bool valRet = dlg->exec(); if (valRet == QDialog::Accepted && !entry.isDefault) { dlg->saveData(entry); } qCDebug(DIGIKAM_GENERAL_LOG) << "Name before save: " << entry.namespaceName; delete dlg; return valRet; } void NamespaceEditDlg::setupTagGui(NamespaceEntry& entry) { d->page = new QWidget(this); d->gridLayout = new QGridLayout(d->page); d->logo = new QLabel(d->page); d->logo->setPixmap(QIcon::fromTheme(QLatin1String("digikam")).pixmap(QSize(48,48))); d->topLabel = new QLabel(d->page); d->topLabel->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); d->topLabel->setWordWrap(false); d->topLabel->setText(i18n("Add metadata namespace")); d->subspaceCombo = new QComboBox(this); d->subspaceLabel = new QLabel(d->page); d->subspaceLabel->setText(i18n("Metadata Subspace")); d->subspaceCombo->addItem(QLatin1String("EXIF"), (int)NamespaceEntry::EXIF); d->subspaceCombo->addItem(QLatin1String("IPTC"), (int)NamespaceEntry::IPTC); d->subspaceCombo->addItem(QLatin1String("XMP"), (int)NamespaceEntry::XMP); d->subspaceCombo->setCurrentIndex((int)entry.subspace); qCDebug(DIGIKAM_GENERAL_LOG) << "Entry subspace" << (int)entry.subspace; // -------------------Tag Elements--------------------------------- d->titleLabel = new QLabel(d->page); d->titleLabel->setText(i18n("Name:")); d->namespaceName = new QLineEdit(this); //----------------- Tip Labels -------------------------------------- d->tagTipLabel = new QLabel(d->page); d->tagTipLabel->setTextFormat(Qt::RichText); d->tagTipLabel->setWordWrap(true); d->tagTipLabel->setText(i18n("

To create new namespaces, you need to specify parameters:

" "

  • Namespace name with dots.
    " "Ex.: \"Xmp.digiKam.TagsList\"
  • " "
  • Separator parameter, used by tag paths
    " "Ex.: \"City/Paris\" or \"City|Paris\"
  • " "
  • Specify if only keyword or the whole path must be written.

" )); d->ratingTipLabel = new QLabel(d->page); d->ratingTipLabel->setTextFormat(Qt::RichText); d->ratingTipLabel->setWordWrap(true); d->ratingTipLabel->setText(i18n("

To create new rating namespaces, you need to specify parameters:

" "

  • Namespace name with dots.
    " "Ex.: \"Xmp.xmp.Rating\"
  • " "
  • Rating mappings, if namespace need other values than 0-5
    " "Ex.: Microsoft uses 0 1 25 50 75 99
  • " "
  • Select the correct namespace option from list.

" )); d->commentTipLabel = new QLabel(d->page); d->commentTipLabel->setTextFormat(Qt::RichText); d->commentTipLabel->setWordWrap(true); d->commentTipLabel->setText(i18n("

To create new comment namespaces, you need to specify parameters:

" "

  • Namespace name with dots.
    " "Ex.: \"Xmp.xmp.Rating\"
  • " "
  • Select the correct namespace option from list.

" )); // ------------------------------------------------------- d->specialOptsLabel = new QLabel(d->page); d->specialOptsLabel->setText(i18n("Special Options")); d->specialOptsCombo = new QComboBox(d->page); d->specialOptsCombo->addItem(QLatin1String("NO_OPTS"), (int)NamespaceEntry::NO_OPTS); if (entry.nsType == NamespaceEntry::COMMENT) { d->specialOptsCombo->addItem(QLatin1String("COMMENT_ALTLANG"), NamespaceEntry::COMMENT_ALTLANG); d->specialOptsCombo->addItem(QLatin1String("COMMENT_ALTLANGLIST"), NamespaceEntry::COMMENT_ATLLANGLIST); d->specialOptsCombo->addItem(QLatin1String("COMMENT_XMP"), NamespaceEntry::COMMENT_XMP); d->specialOptsCombo->addItem(QLatin1String("COMMENT_JPEG"), NamespaceEntry::COMMENT_JPEG); } if (entry.nsType == NamespaceEntry::TAGS) { d->specialOptsCombo->addItem(QLatin1String("TAG_XMPBAG"), NamespaceEntry::TAG_XMPBAG); d->specialOptsCombo->addItem(QLatin1String("TAG_XMPSEQ"), NamespaceEntry::TAG_XMPSEQ); d->specialOptsCombo->addItem(QLatin1String("TAG_ACDSEE"), NamespaceEntry::TAG_ACDSEE); } d->alternativeNameLabel = new QLabel(d->page); d->alternativeNameLabel->setText(i18n("Alternative name")); d->alternativeName = new QLineEdit(d->page); d->altspecialOptsLabel = new QLabel(d->page); d->altspecialOptsLabel->setText(i18n("Alternative special options")); d->altSpecialOptsCombo = new QComboBox(d->page); d->altSpecialOptsCombo->addItem(QLatin1String("NO_OPTS"), (int)NamespaceEntry::NO_OPTS); if (entry.nsType == NamespaceEntry::COMMENT) { d->altSpecialOptsCombo->addItem(QLatin1String("COMMENT_ALTLANG"), NamespaceEntry::COMMENT_ALTLANG); d->altSpecialOptsCombo->addItem(QLatin1String("COMMENT_ALTLANGLIST"), NamespaceEntry::COMMENT_ATLLANGLIST); d->altSpecialOptsCombo->addItem(QLatin1String("COMMENT_XMP"), NamespaceEntry::COMMENT_XMP); d->altSpecialOptsCombo->addItem(QLatin1String("COMMENT_JPEG"), NamespaceEntry::COMMENT_JPEG); } if (entry.nsType == NamespaceEntry::TAGS) { d->altSpecialOptsCombo->addItem(QLatin1String("TAG_XMPBAG"), NamespaceEntry::TAG_XMPBAG); d->altSpecialOptsCombo->addItem(QLatin1String("TAG_XMPSEQ"), NamespaceEntry::TAG_XMPSEQ); d->altSpecialOptsCombo->addItem(QLatin1String("TAG_ACDSEE"), NamespaceEntry::TAG_ACDSEE); } // -------------------------------------------------------- d->separatorLabel = new QLabel(d->page); d->separatorLabel->setText(i18n("Separator:")); d->nameSpaceSeparator = new QLineEdit(this); // -------------------------------------------------------- d->isTagLabel = new QLabel(d->page); d->isTagLabel->setText(i18n("Set Tags Path:")); d->isPath = new QCheckBox(this); d->tipLabel2 = new QLabel(d->page); d->tipLabel2->setTextFormat(Qt::RichText); d->tipLabel2->setWordWrap(true); QPalette sample_palette; sample_palette.setColor(QPalette::Window, QColor(255, 51, 51, 150)); sample_palette.setColor(QPalette::WindowText, Qt::black); d->tipLabel2->setAutoFillBackground(true); d->tipLabel2->setPalette(sample_palette); d->tipLabel2->hide(); // ----------------------Rating Elements---------------------------------- d->ratingMappings = new QGroupBox(this); d->ratingMappings->setFlat(true); QGridLayout* const ratingMappingsLayout = new QGridLayout(d->ratingMappings); QLabel* const ratingLabel = new QLabel(d->page); ratingLabel->setText(i18n("Rating Mapping:")); d->zeroStars = new QSpinBox(this); d->zeroStars->setValue(0); d->oneStar = new QSpinBox(this); d->oneStar->setValue(1); d->twoStars = new QSpinBox(this); d->twoStars->setValue(2); d->threeStars = new QSpinBox(this); d->threeStars->setValue(3); d->fourStars = new QSpinBox(this); d->fourStars->setValue(4); d->fiveStars = new QSpinBox(this); d->fiveStars->setValue(5); const int spacing = QApplication::style()->pixelMetric(QStyle::PM_DefaultLayoutSpacing); const int cmargin = QApplication::style()->pixelMetric(QStyle::PM_DefaultChildMargin); ratingMappingsLayout->addWidget(ratingLabel, 0, 0, 1, 2); ratingMappingsLayout->addWidget(d->zeroStars, 1, 0, 1, 1); ratingMappingsLayout->addWidget(d->oneStar, 1, 1, 1, 1); ratingMappingsLayout->addWidget(d->twoStars, 1, 2, 1, 1); ratingMappingsLayout->addWidget(d->threeStars, 1, 3, 1, 1); ratingMappingsLayout->addWidget(d->fourStars, 1, 4, 1, 1); ratingMappingsLayout->addWidget(d->fiveStars, 1, 5, 1, 1); d->gridLayout->addWidget(d->logo, 0, 0, 1, 2); d->gridLayout->addWidget(d->topLabel, 0, 1, 1, 4); d->gridLayout->addWidget(d->tagTipLabel, 1, 0, 1, 6); d->gridLayout->addWidget(d->ratingTipLabel, 2, 0, 1, 6); d->gridLayout->addWidget(d->commentTipLabel, 3, 0, 1, 6); d->gridLayout->addWidget(d->subspaceLabel, 5, 0, 1, 2); d->gridLayout->addWidget(d->subspaceCombo, 5, 2, 1, 4); d->gridLayout->addWidget(d->titleLabel, 6, 0, 1, 2); d->gridLayout->addWidget(d->namespaceName, 6, 2, 1, 4); d->gridLayout->addWidget(d->specialOptsLabel, 7, 0, 1, 2); d->gridLayout->addWidget(d->specialOptsCombo, 7, 2, 1, 4); d->gridLayout->addWidget(d->alternativeNameLabel, 8, 0, 1, 2); d->gridLayout->addWidget(d->alternativeName, 8, 2, 1, 4); d->gridLayout->addWidget(d->altspecialOptsLabel, 9, 0, 1, 2); d->gridLayout->addWidget(d->altSpecialOptsCombo, 9, 2, 1, 4); - d->gridLayout->addWidget(d->separatorLabel, 10, 0, 1, 2); - d->gridLayout->addWidget(d->nameSpaceSeparator, 10, 2, 1, 4); - d->gridLayout->addWidget(d->isTagLabel, 11, 0, 1, 2); - d->gridLayout->addWidget(d->isPath, 11, 2, 1, 3); + d->gridLayout->addWidget(d->separatorLabel, 10, 0, 1, 2); + d->gridLayout->addWidget(d->nameSpaceSeparator, 10, 2, 1, 4); + d->gridLayout->addWidget(d->isTagLabel, 11, 0, 1, 2); + d->gridLayout->addWidget(d->isPath, 11, 2, 1, 3); - d->gridLayout->addWidget(d->ratingMappings, 12, 0, 2, 6); - d->gridLayout->addWidget(d->tipLabel2, 14, 0, 1, 6); + d->gridLayout->addWidget(d->ratingMappings, 12, 0, 2, 6); + d->gridLayout->addWidget(d->tipLabel2, 14, 0, 1, 6); d->gridLayout->setContentsMargins(cmargin, cmargin, cmargin, cmargin); d->gridLayout->setSpacing(spacing); QVBoxLayout* const vbx = new QVBoxLayout(this); vbx->addWidget(d->page); vbx->addWidget(d->buttons); } void NamespaceEditDlg::populateFields(NamespaceEntry& entry) { d->namespaceName->setText(entry.namespaceName); d->nameSpaceSeparator->setText(entry.separator); if (entry.tagPaths == NamespaceEntry::TAGPATH) { d->isPath->setChecked(true); } else { d->isPath->setChecked(false); } d->alternativeName->setText(entry.alternativeName); d->specialOptsCombo->setCurrentIndex(d->specialOptsCombo->findData(entry.specialOpts)); d->altSpecialOptsCombo->setCurrentIndex(d->altSpecialOptsCombo->findData(entry.secondNameOpts)); if (entry.convertRatio.size() == 6) { d->zeroStars->setValue(entry.convertRatio.at(0)); d->oneStar->setValue(entry.convertRatio.at(1)); d->twoStars->setValue(entry.convertRatio.at(2)); d->threeStars->setValue(entry.convertRatio.at(3)); d->fourStars->setValue(entry.convertRatio.at(4)); d->fiveStars->setValue(entry.convertRatio.at(5)); } } void NamespaceEditDlg::setType(NamespaceEntry::NamespaceType type) { switch (type) { case NamespaceEntry::TAGS: qCDebug(DIGIKAM_GENERAL_LOG) << "Setting up tags"; d->ratingTipLabel->hide(); d->commentTipLabel->hide(); d->ratingMappings->hide(); - // disable IPTC and EXIV for tags + // disable IPTC and EXIF for tags d->subspaceCombo->setItemData(0, 0, Qt::UserRole -1); d->subspaceCombo->setItemData(1, 0, Qt::UserRole -1); break; case NamespaceEntry::RATING: d->tagTipLabel->hide(); d->commentTipLabel->hide(); d->isPath->hide(); d->isTagLabel->hide(); d->separatorLabel->hide(); d->nameSpaceSeparator->hide(); break; case NamespaceEntry::COMMENT: d->tagTipLabel->hide(); d->ratingTipLabel->hide(); d->isPath->hide(); d->isTagLabel->hide(); d->separatorLabel->hide(); d->nameSpaceSeparator->hide(); d->ratingMappings->hide(); break; default: break; } } void NamespaceEditDlg::makeReadOnly() { QString txt = i18n("This is a default namespace. Default namespaces can only be disabled"); d->tipLabel2->setText(txt); d->tipLabel2->show(); d->subspaceCombo->setDisabled(true); d->specialOptsCombo->setDisabled(true); d->altSpecialOptsCombo->setDisabled(true); d->namespaceName->setDisabled(true); d->alternativeName->setDisabled(true); d->nameSpaceSeparator->setDisabled(true); d->isPath->setDisabled(true); d->ratingMappings->setDisabled(true); d->zeroStars->setDisabled(true); d->oneStar->setDisabled(true); d->twoStars->setDisabled(true); d->threeStars->setDisabled(true); d->fourStars->setDisabled(true); d->fiveStars->setDisabled(true); } bool NamespaceEditDlg::validifyCheck(QString& errMsg) { // bool result = true; NOT USED if (d->namespaceName->text().isEmpty()) { errMsg = i18n("The namespace name is required"); return false; } switch (d->subspaceCombo->currentData().toInt()) { case NamespaceEntry::EXIF: if (d->namespaceName->text().split(QLatin1Char('.')).first() != QLatin1String("Exif")) { errMsg = i18n("EXIF namespace name must start with \"Exif\"."); return false; } if (!d->alternativeName->text().isEmpty() && - d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Exif")) + (d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Exif"))) { errMsg = i18n("EXIF alternative namespace name must start with \"Exif\"."); return false; } break; case NamespaceEntry::IPTC: if (d->namespaceName->text().split(QLatin1Char('.')).first() != QLatin1String("Iptc")) { errMsg = i18n("IPTC namespace name must start with \"Iptc\"."); return false; } if (!d->alternativeName->text().isEmpty() && - d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Iptc")) + (d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Iptc"))) { errMsg = i18n("IPTC alternative namespace name must start with \"Iptc\"."); return false; } break; case NamespaceEntry::XMP: if (d->namespaceName->text().split(QLatin1Char('.')).first() != QLatin1String("Xmp")) { errMsg = i18n("XMP namespace name must start with \"Xmp\"."); return false; } if (!d->alternativeName->text().isEmpty() && - d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Xmp")) + (d->alternativeName->text().split(QLatin1Char('.')).first() != QLatin1String("Xmp"))) { errMsg = i18n("XMP alternative namespace name must start with \"Xmp\"."); return false; } break; default: break; } switch (d->nsType) { case NamespaceEntry::TAGS: if (d->nameSpaceSeparator->text().isEmpty()) { errMsg = i18n("Tag Path separator is required"); return false; } if (d->nameSpaceSeparator->text().size() > 1) { errMsg = i18n("Only one character is now supported as tag path separator"); return false; } break; case NamespaceEntry::RATING: break; case NamespaceEntry::COMMENT: break; default: break; } return true; } void NamespaceEditDlg::saveData(NamespaceEntry& entry) { entry.namespaceName = d->namespaceName->text(); entry.separator = d->nameSpaceSeparator->text(); if (d->isPath->isChecked()) { entry.tagPaths = NamespaceEntry::TAGPATH; } else { entry.tagPaths = NamespaceEntry::TAG; } entry.alternativeName = d->alternativeName->text(); entry.specialOpts = (NamespaceEntry::SpecialOptions)d->specialOptsCombo->currentData().toInt(); entry.secondNameOpts = (NamespaceEntry::SpecialOptions)d->altSpecialOptsCombo->currentData().toInt(); entry.subspace = (NamespaceEntry::NsSubspace)d->subspaceCombo->currentData().toInt(); entry.convertRatio.clear(); entry.convertRatio.append(d->zeroStars->value()); entry.convertRatio.append(d->oneStar->value()); entry.convertRatio.append(d->twoStars->value()); entry.convertRatio.append(d->threeStars->value()); entry.convertRatio.append(d->fourStars->value()); entry.convertRatio.append(d->fiveStars->value()); } void NamespaceEditDlg::accept() { QString errMsg; if (validifyCheck(errMsg)) { QDialog::accept(); } else { d->tipLabel2->setText(errMsg); d->tipLabel2->show(); } } void NamespaceEditDlg::slotHelp() { DXmlGuiWindow::openHandbook(); } } // namespace Digikam diff --git a/core/utilities/setup/metadata/namespacelistview.cpp b/core/utilities/setup/metadata/namespacelistview.cpp index 5bd0322f7b..e7064b043a 100644 --- a/core/utilities/setup/metadata/namespacelistview.cpp +++ b/core/utilities/setup/metadata/namespacelistview.cpp @@ -1,180 +1,180 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2013-08-22 * Description : Reimplemented QListView for metadata setup, with support for * drag-n-drop * * Copyright (C) 2013-2015 by Veaceslav Munteanu * * This program 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, or (at your option) * any later version. * * This program 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. * * ============================================================ */ #include "namespacelistview.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" namespace Digikam { NamespaceListView::NamespaceListView(QWidget* const parent) : QListView(parent) { setAlternatingRowColors(true); setAcceptDrops(true); setDragEnabled(true); setDragDropMode(QAbstractItemView::InternalMove); setSelectionMode(QAbstractItemView::SingleSelection); } void NamespaceListView::startDrag(Qt::DropActions supportedActions) { QListView::startDrag(supportedActions); } QModelIndexList NamespaceListView::mySelectedIndexes() { return selectedIndexes(); } void NamespaceListView::dropEvent(QDropEvent* e) { QListView::dropEvent(e); emit signalItemsChanged(); } QModelIndex NamespaceListView::indexVisuallyAt(const QPoint& p) { if (viewport()->rect().contains(p)) { QModelIndex index = indexAt(p); if (index.isValid() && visualRect(index).contains(p)) { return index; } } return QModelIndex(); } void NamespaceListView::slotDeleteSelected() { QModelIndexList sel = selectionModel()->selectedIndexes(); if (sel.isEmpty()) { return; } QStandardItemModel* const model = dynamic_cast(this->model()); if (!model) { qCDebug(DIGIKAM_GENERAL_LOG) << "Error! no model available!"; return; } foreach (const QModelIndex& index, sel) { QStandardItem* const root = model->invisibleRootItem(); root->removeRow(index.row()); } emit signalItemsChanged(); } void NamespaceListView::slotMoveItemDown() { QModelIndexList sel = selectionModel()->selectedIndexes(); if (sel.isEmpty()) { return; } QStandardItemModel* const model = dynamic_cast(this->model()); if (!model) { qCDebug(DIGIKAM_GENERAL_LOG) << "Error! no model available!"; return; } QModelIndex index = sel.first(); QStandardItem* const root = model->invisibleRootItem(); - if (index.row() == root->rowCount() - 1) + if (index.row() == (root->rowCount() - 1)) { return; } root->insertRow(index.row() + 1, root->takeRow(index.row())); setCurrentIndex(model->index(index.row() + 1, index.column(), index.parent())); emit signalItemsChanged(); } void NamespaceListView::slotMoveItemUp() { QModelIndexList sel = selectionModel()->selectedIndexes(); if (sel.isEmpty()) { return; } QStandardItemModel* const model = dynamic_cast(this->model()); if (!model) { qCDebug(DIGIKAM_GENERAL_LOG) << "Error! no model available!"; return; } QModelIndex index = sel.first(); QStandardItem* const root = model->invisibleRootItem(); if (index.row() == 0) { return; } root->insertRow(index.row() - 1, root->takeRow(index.row())); setCurrentIndex(model->index(index.row() - 1, index.column(), index.parent())); emit signalItemsChanged(); } } // namespace Digikam diff --git a/core/utilities/setup/metadata/setupmetadata.cpp b/core/utilities/setup/metadata/setupmetadata.cpp index f65da440b3..877526c386 100644 --- a/core/utilities/setup/metadata/setupmetadata.cpp +++ b/core/utilities/setup/metadata/setupmetadata.cpp @@ -1,919 +1,921 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2003-08-03 * Description : setup Metadata tab. * * Copyright (C) 2003-2004 by Ralf Holzer * Copyright (C) 2003-2020 by Gilles Caulier * Copyright (C) 2009-2012 by Marcel Wiesweg * Copyright (C) 2017 by Simon Frei * * This program 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, or (at your option) * any later version. * * This program 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. * * ============================================================ */ #include "setupmetadata.h" // Qt includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // KDE includes #include // Local includes #include "advancedmetadatatab.h" #include "applicationsettings.h" #include "dactivelabel.h" #include "digikam_config.h" #include "digikam_debug.h" #include "metaengine.h" #include "metadatapanel.h" #include "metaenginesettings.h" #include "setuputils.h" namespace Digikam { class Q_DECL_HIDDEN SetupMetadata::Private { public: explicit Private() : exifAutoRotateOriginal(false), exifAutoRotateShowedInfo(false), clearMetadataShowedInfo(false), fieldsGroup(nullptr), readWriteGroup(nullptr), rotationGroup(nullptr), rotationAdvGroup(nullptr), saveTagsBox(nullptr), saveCommentsBox(nullptr), saveRatingBox(nullptr), savePickLabelBox(nullptr), saveColorLabelBox(nullptr), saveDateTimeBox(nullptr), saveTemplateBox(nullptr), saveFaceTags(nullptr), useLazySync(nullptr), writeRawFilesBox(nullptr), writeXMPSidecarBox(nullptr), readXMPSidecarBox(nullptr), sidecarFileNameBox(nullptr), updateFileTimeStampBox(nullptr), rescanImageIfModifiedBox(nullptr), clearMetadataIfRescanBox(nullptr), writingModeCombo(nullptr), rotateByFlag(nullptr), rotateByContents(nullptr), allowRotateByMetadata(nullptr), allowLossyRotate(nullptr), exifRotateBox(nullptr), exifSetOrientationBox(nullptr), saveToBalooBox(nullptr), readFromBalooBox(nullptr), tab(nullptr), displaySubTab(nullptr), tagsCfgPanel(nullptr), advTab(nullptr), extensionsEdit(nullptr) { } bool exifAutoRotateOriginal; bool exifAutoRotateShowedInfo; bool clearMetadataShowedInfo; QGroupBox* fieldsGroup; QGroupBox* readWriteGroup; QGroupBox* rotationGroup; QGroupBox* rotationAdvGroup; QCheckBox* saveTagsBox; QCheckBox* saveCommentsBox; QCheckBox* saveRatingBox; QCheckBox* savePickLabelBox; QCheckBox* saveColorLabelBox; QCheckBox* saveDateTimeBox; QCheckBox* saveTemplateBox; QCheckBox* saveFaceTags; QCheckBox* useLazySync; QCheckBox* writeRawFilesBox; QCheckBox* writeXMPSidecarBox; QCheckBox* readXMPSidecarBox; QCheckBox* sidecarFileNameBox; QCheckBox* updateFileTimeStampBox; QCheckBox* rescanImageIfModifiedBox; QCheckBox* clearMetadataIfRescanBox; QComboBox* writingModeCombo; QRadioButton* rotateByFlag; QRadioButton* rotateByContents; QCheckBox* allowRotateByMetadata; QCheckBox* allowLossyRotate; QCheckBox* exifRotateBox; QCheckBox* exifSetOrientationBox; QCheckBox* saveToBalooBox; QCheckBox* readFromBalooBox; QTabWidget* tab; QTabWidget* displaySubTab; MetadataPanel* tagsCfgPanel; AdvancedMetadataTab* advTab; QLineEdit* extensionsEdit; }; SetupMetadata::SetupMetadata(QWidget* const parent) : QScrollArea(parent), d(new Private) { d->tab = new QTabWidget(viewport()); setWidget(d->tab); setWidgetResizable(true); QWidget* const panel = new QWidget; QVBoxLayout* const mainLayout = new QVBoxLayout; // -------------------------------------------------------- d->fieldsGroup = new QGroupBox; QGridLayout* const fieldsLayout = new QGridLayout; d->fieldsGroup->setWhatsThis(xi18nc("@info:whatsthis", "In addition to the pixel content, image files usually " "contain a variety of metadata. A lot of the parameters you can use " "in digiKam to manage files, such as rating or comment, can be written " "to the files' metadata. " "Storing in metadata allows one to preserve this information " "when moving or sending the files to different systems.")); QLabel* const fieldsIconLabel = new QLabel; fieldsIconLabel->setPixmap(QIcon::fromTheme(QLatin1String("format-list-unordered")).pixmap(32)); QLabel* const fieldsLabel = new QLabel(i18nc("@label", "Write This Information to the Metadata")); - d->saveTagsBox = new QCheckBox; + d->saveTagsBox = new QCheckBox; d->saveTagsBox->setText(i18nc("@option:check", "Image tags")); d->saveTagsBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item tags " "in the XMP and IPTC tags.")); - d->saveCommentsBox = new QCheckBox; + d->saveCommentsBox = new QCheckBox; d->saveCommentsBox->setText(i18nc("@option:check", "Captions and title")); d->saveCommentsBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store item caption and title " "in the JFIF Comment section, the EXIF tag, the XMP tag, " "and the IPTC tag.")); - d->saveRatingBox = new QCheckBox; + d->saveRatingBox = new QCheckBox; d->saveRatingBox->setText(i18nc("@option:check", "Rating")); d->saveRatingBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item rating " "in the EXIF tag and the XMP tags.")); - d->savePickLabelBox = new QCheckBox; + d->savePickLabelBox = new QCheckBox; d->savePickLabelBox->setText(i18nc("@option:check", "Pick label")); d->savePickLabelBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item pick label " "in the XMP tags.")); d->saveColorLabelBox = new QCheckBox; d->saveColorLabelBox->setText(i18nc("@option:check", "Color label")); d->saveColorLabelBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item color label " "in the XMP tags.")); d->saveDateTimeBox = new QCheckBox; d->saveDateTimeBox->setText(i18nc("@option:check", "Timestamps")); d->saveDateTimeBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the item date and time " "in the EXIF, XMP, and IPTC tags.")); d->saveTemplateBox = new QCheckBox; d->saveTemplateBox->setText(i18nc("@option:check", "Metadata templates (Copyright etc.)")); d->saveTemplateBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store the metadata " "template in the XMP and the IPTC tags. " "You can set template values to Template setup page.")); - d->saveFaceTags = new QCheckBox; + d->saveFaceTags = new QCheckBox; d->saveFaceTags->setText(i18nc("@option:check", "Face Tags (including face areas)")); d->saveFaceTags->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to store face tags " "with face rectangles in the XMP tags.")); fieldsLayout->addWidget(fieldsIconLabel, 0, 0, 2, 3); fieldsLayout->addWidget(fieldsLabel, 0, 1, 2, 3); fieldsLayout->addWidget(d->saveTagsBox, 2, 0, 1, 3); fieldsLayout->addWidget(d->saveCommentsBox, 3, 0, 1, 3); fieldsLayout->addWidget(d->saveRatingBox, 4, 0, 1, 3); fieldsLayout->addWidget(d->savePickLabelBox, 5, 0, 1, 3); fieldsLayout->addWidget(d->saveColorLabelBox, 6, 0, 1, 3); fieldsLayout->addWidget(d->saveDateTimeBox, 7, 0, 1, 3); fieldsLayout->addWidget(d->saveTemplateBox, 8, 0, 1, 3); fieldsLayout->addWidget(d->saveFaceTags, 9 ,0, 1, 3); fieldsLayout->setColumnStretch(3, 10); d->fieldsGroup->setLayout(fieldsLayout); // -------------------------------------------------------- d->readWriteGroup = new QGroupBox; QGridLayout* const readWriteLayout = new QGridLayout; QLabel* const readWriteIconLabel = new QLabel; readWriteIconLabel->setPixmap(QIcon::fromTheme(QLatin1String("document-open")).pixmap(32)); QLabel* const readWriteLabel = new QLabel(i18nc("@label", "Reading and Writing Metadata")); d->useLazySync = new QCheckBox; d->useLazySync->setText(i18nc("@option:check", "Use lazy synchronization")); d->useLazySync->setWhatsThis(i18nc("@info:whatsthis", "Instead of synchronizing metadata, just schedule it for synchronization." "Synchronization can be done later by triggering the apply pending, or at digikam exit")); - d->writeRawFilesBox = new QCheckBox; + d->writeRawFilesBox = new QCheckBox; d->writeRawFilesBox->setText(i18nc("@option:check", "If possible write Metadata to RAW files (experimental)")); d->writeRawFilesBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to write metadata into RAW TIFF/EP files. " "This feature requires the Exiv2 shared library, version >= 0.18.0. It is still " "experimental, and is disabled by default.")); d->writeRawFilesBox->setEnabled(MetaEngine::supportMetadataWritting(QLatin1String("image/x-raw"))); d->updateFileTimeStampBox = new QCheckBox; d->updateFileTimeStampBox->setText(i18nc("@option:check", "&Update file modification timestamp when files are modified")); d->updateFileTimeStampBox->setWhatsThis(i18nc("@info:whatsthis", "Turn off this option to not update file timestamps when files are changed as " "when you update metadata or image data. Note: disabling this option can " "introduce some dysfunctions with applications which use file timestamps " "properties to detect file modifications automatically.")); d->rescanImageIfModifiedBox = new QCheckBox; d->rescanImageIfModifiedBox->setText(i18nc("@option:check", "&Rescan file when files are modified")); d->rescanImageIfModifiedBox->setWhatsThis(i18nc("@info:whatsthis", "Turning this option on, will force digiKam to rescan files that has been " "modified outside digiKam. If a file has changed it is file size or if " "the last modified timestamp has changed, a rescan of that " "file will be performed when digiKam starts.")); d->clearMetadataIfRescanBox = new QCheckBox; d->clearMetadataIfRescanBox->setText(i18nc("@option:check", "&Clean up the metadata from the database when rescan files")); d->clearMetadataIfRescanBox->setWhatsThis(i18nc("@info:whatsthis", "Turning this option on, will force digiKam to delete the file metadata " "contained in the database before the file is rescanned. WARNING: " "if your metadata has been written to the database only and not " "to the file or sidecar, you will be able to lose inserted " "metadata such as tags, keywords, or geographic coordinates.")); readWriteLayout->addWidget(readWriteIconLabel, 0, 0, 2, 3); readWriteLayout->addWidget(readWriteLabel, 0, 1, 2, 3); readWriteLayout->addWidget(d->useLazySync, 2, 0, 1, 3); readWriteLayout->addWidget(d->writeRawFilesBox, 3, 0, 1, 3); readWriteLayout->addWidget(d->updateFileTimeStampBox, 4, 0, 1, 3); readWriteLayout->addWidget(d->rescanImageIfModifiedBox, 5, 0, 1, 3); readWriteLayout->addWidget(d->clearMetadataIfRescanBox, 6, 0, 1, 3); readWriteLayout->setColumnStretch(3, 10); d->readWriteGroup->setLayout(readWriteLayout); // -------------------------------------------------------- QFrame* const infoBox = new QFrame; QGridLayout* const infoBoxGrid = new QGridLayout; infoBox->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); DActiveLabel* const exiv2LogoLabel = new DActiveLabel(QUrl(QLatin1String("https://www.exiv2.org")), QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("digikam/data/logo-exiv2.png")), infoBox); exiv2LogoLabel->setWhatsThis(i18n("Visit Exiv2 project website")); QLabel* const explanation = new QLabel(infoBox); explanation->setOpenExternalLinks(true); explanation->setWordWrap(true); QString txt; txt.append(i18n("

EXIF - " "a standard used by most digital cameras today to store technical " "information (like aperture and shutter speed) about an image.

")); txt.append(i18n("

IPTC - " "an older standard used in digital photography to store " "photographer information in images.

")); if (MetaEngine::supportXmp()) + { txt.append(i18n("

XMP - " "a new standard used in digital photography, designed to replace IPTC.

")); + } explanation->setText(txt); infoBoxGrid->addWidget(exiv2LogoLabel, 0, 0, 1, 1); infoBoxGrid->addWidget(explanation, 0, 1, 1, 2); infoBoxGrid->setColumnStretch(1, 10); infoBoxGrid->setRowStretch(1, 10); infoBoxGrid->setSpacing(0); infoBox->setLayout(infoBoxGrid); // -------------------------------------------------------- mainLayout->addWidget(d->fieldsGroup); mainLayout->addWidget(d->readWriteGroup); mainLayout->addWidget(infoBox); panel->setLayout(mainLayout); d->tab->insertTab(Behavior, panel, i18nc("@title:tab", "Behavior")); // -------------------------------------------------------- QWidget* const rotationPanel = new QWidget(d->tab); QVBoxLayout* const rotationLayout = new QVBoxLayout; d->rotationGroup = new QGroupBox; QGridLayout* const rotationGroupLayout = new QGridLayout; QLabel* const rotationExplanation = new QLabel(i18nc("@label", "When rotating a file")); QLabel* const rotationIcon = new QLabel; rotationIcon->setPixmap(QIcon::fromTheme(QLatin1String("transform-rotate")).pixmap(32)); d->rotateByFlag = new QRadioButton(i18nc("@option:radio", "Rotate by only setting a flag")); d->rotateByContents = new QRadioButton(i18nc("@option:radio", "Rotate by changing the content if possible")); d->allowLossyRotate = new QCheckBox(i18nc("@option:check", "Even allow lossy rotation if necessary")); d->allowRotateByMetadata = new QCheckBox(i18nc("@option:check", "Write flag to metadata if possible")); connect(d->rotateByContents, SIGNAL(toggled(bool)), d->allowLossyRotate, SLOT(setEnabled(bool))); d->rotateByFlag->setChecked(false); d->rotateByContents->setChecked(false); d->allowLossyRotate->setEnabled(false); d->allowLossyRotate->setChecked(false); d->allowRotateByMetadata->setChecked(true); d->rotateByFlag->setToolTip(i18nc("@info:tooltip", "Rotate files only by changing a flag, not touching the pixel data")); d->rotateByFlag->setWhatsThis(xi18nc("@info:whatsthis", "A file can be rotated in two ways: " "You can change the contents, rearranging the individual pixels of the image data. " "Or you can set a flag that the file is to be rotated before it is shown. " "Select this option if you always want to set only a flag. " "This is less obtrusive, but requires support if the file is accessed with another software. " "Ensure to allow setting the flag in the metadata if you want to share your files " "outside digiKam.")); d->rotateByContents->setToolTip(i18nc("@info:tooltip", "If possible rotate files by changing the pixel data")); d->rotateByContents->setWhatsThis(xi18nc("@info:whatsthis", "A file can be rotated in two ways: " "You can change the contents, rearranging the individual pixels of the image data. " "Or you can set a flag that the file is to be rotated before it is shown. " "Select this option if you want the file to be rotated by changing the content. " "This is a lossless operation for JPEG files. For other formats it is a lossy operation, " "which you need to enable explicitly. " "It is not support for RAW and other read-only formats, " "which will be rotated by flag only.")); d->allowLossyRotate->setToolTip(i18nc("@info:tooltip", "Rotate files by changing the pixel data even if the operation will incur quality loss")); d->allowLossyRotate->setWhatsThis(i18nc("@info:whatsthis", "For some file formats which apply lossy compression, " "data will be lost each time the content is rotated. " "Check this option to allow lossy rotation. " "If not enabled, these files will be rotated by flag.")); d->allowRotateByMetadata->setToolTip(i18nc("@info:tooltip", "When rotating a file by setting a flag, also change this flag in the file's metadata")); d->allowRotateByMetadata->setWhatsThis(i18nc("@info:whatsthis", "File metadata typically contains a flag describing " "that a file shall be shown rotated. " "Enable this option to allow editing this field. ")); rotationGroupLayout->addWidget(rotationIcon, 0, 0, 1, 1); rotationGroupLayout->addWidget(rotationExplanation, 0, 1, 1, 2); rotationGroupLayout->addWidget(d->rotateByFlag, 1, 0, 1, 3); rotationGroupLayout->addWidget(d->rotateByContents, 2, 0, 1, 3); rotationGroupLayout->addWidget(d->allowLossyRotate, 3, 2, 1, 1); rotationGroupLayout->addWidget(d->allowRotateByMetadata, 4, 0, 1, 3); rotationGroupLayout->setColumnStretch(3, 10); d->rotationGroup->setLayout(rotationGroupLayout); // -------------------------------------------------------- d->rotationAdvGroup = new QGroupBox; QGridLayout* const rotationAdvLayout = new QGridLayout; QLabel* const rotationAdvExpl = new QLabel(i18nc("@label", "Rotate actions")); QLabel* const rotationAdvIcon = new QLabel; rotationAdvIcon->setPixmap(QIcon::fromTheme(QLatin1String("configure")).pixmap(32)); d->exifRotateBox = new QCheckBox; d->exifRotateBox->setText(i18n("Show images/thumbnails &rotated according to orientation tag.")); d->exifSetOrientationBox = new QCheckBox; d->exifSetOrientationBox->setText(i18n("Set orientation tag to normal after rotate/flip.")); rotationAdvLayout->addWidget(rotationAdvIcon, 0, 0, 1, 1); rotationAdvLayout->addWidget(rotationAdvExpl, 0, 1, 1, 1); rotationAdvLayout->addWidget(d->exifRotateBox, 1, 0, 1, 3); rotationAdvLayout->addWidget(d->exifSetOrientationBox, 2, 0, 1, 3); rotationAdvLayout->setColumnStretch(2, 10); d->rotationAdvGroup->setLayout(rotationAdvLayout); // -------------------------------------------------------- QLabel* const rotationNote = new QLabel(i18n("Note: These settings affect the album view " "and not the image editor. The image editor always " "changes the image data during the rotation.")); rotationNote->setWordWrap(true); rotationNote->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); // -------------------------------------------------------- rotationLayout->addWidget(d->rotationGroup); rotationLayout->addWidget(d->rotationAdvGroup); rotationLayout->addWidget(rotationNote); rotationLayout->addStretch(); rotationPanel->setLayout(rotationLayout); d->tab->insertTab(Rotation, rotationPanel, i18nc("@title:tab", "Rotation")); // -------------------------------------------------------- QWidget* const displayPanel = new QWidget; QGridLayout* const displayLayout = new QGridLayout; QLabel* const displayLabel = new QLabel(i18nc("@info:label", "Select Metadata Fields to Be Displayed")); QLabel* const displayIcon = new QLabel; displayIcon->setPixmap(QIcon::fromTheme(QLatin1String("view-list-tree")).pixmap(32)); d->displaySubTab = new QTabWidget; d->tagsCfgPanel = new MetadataPanel(d->displaySubTab); displayLayout->addWidget(displayIcon, 0, 0); displayLayout->addWidget(displayLabel, 0, 1); displayLayout->addWidget(d->displaySubTab, 1, 0, 1, 3); displayLayout->setColumnStretch(2, 1); displayPanel->setLayout(displayLayout); d->tab->insertTab(Display, displayPanel, i18nc("@title:tab", "Views")); // -------------------------------------------------------- #ifdef HAVE_KFILEMETADATA QWidget* const balooPanel = new QWidget(d->tab); QVBoxLayout* const balooLayout = new QVBoxLayout(balooPanel); QGroupBox* const balooGroup = new QGroupBox(i18n("Baloo Desktop Search"), balooPanel); QVBoxLayout* const gLayout3 = new QVBoxLayout(balooGroup); d->saveToBalooBox = new QCheckBox; d->saveToBalooBox->setText(i18n("Store metadata from digiKam in Baloo")); d->saveToBalooBox->setWhatsThis(i18n("Turn on this option to push rating, comments and tags " "from digiKam into the Baloo storage")); d->readFromBalooBox = new QCheckBox; d->readFromBalooBox->setText(i18n("Read metadata from Baloo")); d->readFromBalooBox->setWhatsThis(i18n("Turn on this option if you want to apply changes to " "rating, comments and tags made in Baloo to digiKam's metadata storage. " "Please note that image metadata will not be edited automatically.")); gLayout3->addWidget(d->saveToBalooBox); gLayout3->addWidget(d->readFromBalooBox); d->tab->insertTab(Baloo, balooPanel, i18nc("@title:tab", "Baloo")); // -------------------------------------------------------- QFrame* const balooBox = new QFrame(balooPanel); QGridLayout* const balooGrid = new QGridLayout(balooBox); balooBox->setFrameStyle(QFrame::StyledPanel | QFrame::Raised); QLabel* const balooLogoLabel = new QLabel; balooLogoLabel->setPixmap(QIcon::fromTheme(QLatin1String("baloo")).pixmap(48)); QLabel* const balooExplanation = new QLabel(balooBox); balooExplanation->setOpenExternalLinks(true); balooExplanation->setWordWrap(true); QString balootxt; balootxt.append(i18n("

Baloo " "provides the basis to handle all kinds of metadata on the KDE desktop in a generic fashion. " "It allows you to tag, rate and comment your files in KDE applications like Dolphin.

" "

Please set here if you want to synchronize the metadata stored by digiKam desktop-wide with the " "Baloo Desktop Search.

")); balooExplanation->setText(balootxt); balooGrid->addWidget(balooLogoLabel, 0, 0, 1, 1); balooGrid->addWidget(balooExplanation, 0, 1, 1, 2); balooGrid->setColumnStretch(1, 10); balooGrid->setSpacing(0); // -------------------------------------------------------- balooLayout->addWidget(balooGroup); balooLayout->addWidget(balooBox); /* balooLayout->addWidget(d->resyncButton, 0, Qt::AlignRight); */ balooLayout->addStretch(); #endif // HAVE_KFILEMETADATA //--------------Advanced Metadata Configuration -------------- d->advTab = new AdvancedMetadataTab(this); d->tab->insertTab(AdvancedConfig, d->advTab, i18nc("@title:tab", "Advanced")); //------------------------Sidecars------------------------- QWidget* const sidecarsPanel = new QWidget(d->tab); QVBoxLayout* const sidecarsLayout = new QVBoxLayout(sidecarsPanel); // -------------------------------------------------------- QGroupBox* rwSidecarsGroup = new QGroupBox; QGridLayout* const rwSidecarsLayout = new QGridLayout; QLabel* const rwSidecarsLabel = new QLabel(i18nc("@label", "Reading and Writing to Sidecars")); d->readXMPSidecarBox = new QCheckBox; d->readXMPSidecarBox->setText(i18nc("@option:check", "Read from sidecar files")); d->readXMPSidecarBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to read metadata from XMP sidecar files when reading metadata.")); d->readXMPSidecarBox->setEnabled(MetaEngine::supportXmp()); d->writeXMPSidecarBox = new QCheckBox; d->writeXMPSidecarBox->setText(i18nc("@option:check", "Write to sidecar files")); d->writeXMPSidecarBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to save, as specified, metadata to XMP sidecar files.")); d->writeXMPSidecarBox->setEnabled(MetaEngine::supportXmp()); d->writingModeCombo = new QComboBox; d->writingModeCombo->addItem(i18n("Write to XMP sidecar for read-only item only"), MetaEngine::WRITE_TO_SIDECAR_ONLY_FOR_READ_ONLY_FILES); d->writingModeCombo->addItem(i18n("Write to XMP sidecar only"), MetaEngine::WRITE_TO_SIDECAR_ONLY); d->writingModeCombo->addItem(i18n("Write to item and XMP Sidecar"), MetaEngine::WRITE_TO_SIDECAR_AND_FILE); d->writingModeCombo->setToolTip(i18nc("@info:tooltip", "Specify the exact mode of XMP sidecar writing")); d->writingModeCombo->setEnabled(false); d->sidecarFileNameBox = new QCheckBox; d->sidecarFileNameBox->setText(i18nc("@option:check", "Sidecar file names are compatible with commercial programs")); d->sidecarFileNameBox->setWhatsThis(i18nc("@info:whatsthis", "Turn on this option to create the XMP sidecar files with a compatible " "file name (BASENAME.xmp) used by many commercial programs. " "For Darktable do not enable this option.")); d->sidecarFileNameBox->setEnabled(false); connect(d->writeXMPSidecarBox, SIGNAL(toggled(bool)), d->writingModeCombo, SLOT(setEnabled(bool))); connect(d->writeXMPSidecarBox, SIGNAL(toggled(bool)), d->sidecarFileNameBox, SLOT(setEnabled(bool))); rwSidecarsLayout->addWidget(rwSidecarsLabel, 0, 0, 1, 3); rwSidecarsLayout->addWidget(d->readXMPSidecarBox, 1, 0, 1, 3); rwSidecarsLayout->addWidget(d->writeXMPSidecarBox, 2, 0, 1, 3); rwSidecarsLayout->addWidget(d->writingModeCombo, 3, 1, 1, 2); rwSidecarsLayout->addWidget(d->sidecarFileNameBox, 4, 0, 1, 3); rwSidecarsLayout->setColumnStretch(3, 10); rwSidecarsGroup->setLayout(rwSidecarsLayout); // -------------------------------------------------------- QGroupBox* const extensionsGroup = new QGroupBox(sidecarsPanel); QGridLayout* const extensionsGrid = new QGridLayout(extensionsGroup); QLabel* extensionsGroupLabel = new QLabel( i18n("

Add file types to be recognised as sidecars.

" "

digiKam (optionally) writes metadata to *.xmp sidecar " "files. Other programs might use different types, which " "can be specified below. digiKam will neither display these " "nor read from or write to them. But whenever a matching album " "item (e.g. \"image.dng\" for \"image.dng.pp3\") is renamed, " "moved, copied or deleted, the same operation will be done " "on these sidecar files.

" "

Multiple extensions must be separated by a semicolon " "or a space.

")); extensionsGroupLabel->setWordWrap(true); QLabel* const extensionsLogo = new QLabel(extensionsGroup); extensionsLogo->setPixmap(QIcon::fromTheme(QLatin1String("text-x-texinfo")).pixmap(48)); - d->extensionsEdit = new QLineEdit(extensionsGroup); + d->extensionsEdit = new QLineEdit(extensionsGroup); d->extensionsEdit->setWhatsThis(i18n("

Here you can add extra extensions " "of sidecars files to be processed alongside " "regular items. These files will not be visible, " "but regarded as an extension of the main file. " "Just write \"xyz abc\" to support files with " "the *.xyz and *.abc extensions. The internally " "used sidecars type *.xmp is always included.

")); d->extensionsEdit->setClearButtonEnabled(true); d->extensionsEdit->setPlaceholderText(i18n("Enter additional sidecars file extensions.")); QLabel* const extensionsLabel = new QLabel(extensionsGroup); extensionsLabel->setText(i18n("Additional &sidecar file extensions")); extensionsLabel->setBuddy(d->extensionsEdit); extensionsGrid->addWidget(extensionsGroupLabel, 0, 0, 1, -1); extensionsGrid->addWidget(extensionsLogo, 1, 0, 2, 1); extensionsGrid->addWidget(extensionsLabel, 1, 1, 1, -1); extensionsGrid->addWidget(d->extensionsEdit, 2, 1, 1, -1); extensionsGrid->setColumnStretch(1, 10); // -------------------------------------------------------- sidecarsLayout->addWidget(rwSidecarsGroup); sidecarsLayout->addWidget(extensionsGroup); sidecarsLayout->addStretch(); d->tab->insertTab(Sidecars, sidecarsPanel, i18nc("@title:tab", "Sidecars")); // -------------------------------------------------------- readSettings(); connect(d->exifRotateBox, SIGNAL(toggled(bool)), this, SLOT(slotExifAutoRotateToggled(bool))); connect(d->clearMetadataIfRescanBox, SIGNAL(toggled(bool)), this, SLOT(slotClearMetadataToggled(bool))); connect(d->writeRawFilesBox, SIGNAL(toggled(bool)), this, SLOT(slotWriteRawFilesToggled(bool))); } SetupMetadata::~SetupMetadata() { delete d; } void SetupMetadata::setActiveMainTab(MetadataTab tab) { d->tab->setCurrentIndex(tab); } void SetupMetadata::setActiveSubTab(int tab) { d->displaySubTab->setCurrentIndex(tab); } void SetupMetadata::applySettings() { MetaEngineSettings* const mSettings = MetaEngineSettings::instance(); if (!mSettings) { return; } MetaEngineSettingsContainer set; set.rotationBehavior = MetaEngineSettingsContainer::RotateByInternalFlag; if (d->allowRotateByMetadata->isChecked()) { set.rotationBehavior |= MetaEngineSettingsContainer::RotateByMetadataFlag; } if (d->rotateByContents->isChecked()) { set.rotationBehavior |= MetaEngineSettingsContainer::RotateByLosslessRotation; if (d->allowLossyRotate->isChecked()) { set.rotationBehavior |= MetaEngineSettingsContainer::RotateByLossyRotation; } } set.exifRotate = d->exifRotateBox->isChecked(); set.exifSetOrientation = d->exifSetOrientationBox->isChecked(); set.saveComments = d->saveCommentsBox->isChecked(); set.saveDateTime = d->saveDateTimeBox->isChecked(); set.savePickLabel = d->savePickLabelBox->isChecked(); set.saveColorLabel = d->saveColorLabelBox->isChecked(); set.saveRating = d->saveRatingBox->isChecked(); set.saveTags = d->saveTagsBox->isChecked(); set.saveTemplate = d->saveTemplateBox->isChecked(); set.saveFaceTags = d->saveFaceTags->isChecked(); set.useLazySync = d->useLazySync->isChecked(); set.writeRawFiles = d->writeRawFilesBox->isChecked(); set.useXMPSidecar4Reading = d->readXMPSidecarBox->isChecked(); set.useCompatibleFileName = d->sidecarFileNameBox->isChecked(); if (d->writeXMPSidecarBox->isChecked()) { set.metadataWritingMode = (MetaEngine::MetadataWritingMode) d->writingModeCombo->itemData(d->writingModeCombo->currentIndex()).toInt(); } else { set.metadataWritingMode = MetaEngine::WRITE_TO_FILE_ONLY; } set.updateFileTimeStamp = d->updateFileTimeStampBox->isChecked(); set.rescanImageIfModified = d->rescanImageIfModifiedBox->isChecked(); set.clearMetadataIfRescan = d->clearMetadataIfRescanBox->isChecked(); set.sidecarExtensions = cleanUserFilterString(d->extensionsEdit->text()); set.sidecarExtensions.removeAll(QLatin1String("xmp")); set.sidecarExtensions.removeDuplicates(); mSettings->setSettings(set); #ifdef HAVE_KFILEMETADATA ApplicationSettings* const aSettings = ApplicationSettings::instance(); if (!aSettings) { return; } aSettings->setSyncDigikamToBaloo(d->saveToBalooBox->isChecked()); aSettings->setSyncBalooToDigikam(d->readFromBalooBox->isChecked()); aSettings->saveSettings(); #endif // HAVE_KFILEMETADATA d->tagsCfgPanel->applySettings(); d->advTab->applySettings(); } void SetupMetadata::readSettings() { MetaEngineSettings* const mSettings = MetaEngineSettings::instance(); if (!mSettings) { return; } MetaEngineSettingsContainer set = mSettings->settings(); if (set.rotationBehavior & MetaEngineSettingsContainer::RotatingPixels) { d->rotateByContents->setChecked(true); } else { d->rotateByFlag->setChecked(true); } d->allowRotateByMetadata->setChecked(set.rotationBehavior & MetaEngineSettingsContainer::RotateByMetadataFlag); d->allowLossyRotate->setChecked(set.rotationBehavior & MetaEngineSettingsContainer::RotateByLossyRotation); - d->exifAutoRotateOriginal = set.exifRotate; + d->exifAutoRotateOriginal = set.exifRotate; d->exifRotateBox->setChecked(d->exifAutoRotateOriginal); d->exifSetOrientationBox->setChecked(set.exifSetOrientation); d->saveTagsBox->setChecked(set.saveTags); d->saveCommentsBox->setChecked(set.saveComments); d->saveRatingBox->setChecked(set.saveRating); d->savePickLabelBox->setChecked(set.savePickLabel); d->saveColorLabelBox->setChecked(set.saveColorLabel); d->saveDateTimeBox->setChecked(set.saveDateTime); d->saveTemplateBox->setChecked(set.saveTemplate); d->saveFaceTags->setChecked(set.saveFaceTags); d->useLazySync->setChecked(set.useLazySync); d->writeRawFilesBox->setChecked(set.writeRawFiles); d->readXMPSidecarBox->setChecked(set.useXMPSidecar4Reading); d->sidecarFileNameBox->setChecked(set.useCompatibleFileName); d->updateFileTimeStampBox->setChecked(set.updateFileTimeStamp); d->rescanImageIfModifiedBox->setChecked(set.rescanImageIfModified); d->clearMetadataIfRescanBox->setChecked(set.clearMetadataIfRescan); if (set.metadataWritingMode == MetaEngine::WRITE_TO_FILE_ONLY) { d->writeXMPSidecarBox->setChecked(false); } else { d->writeXMPSidecarBox->setChecked(true); d->writingModeCombo->setCurrentIndex(d->writingModeCombo->findData(set.metadataWritingMode)); } d->extensionsEdit->setText(set.sidecarExtensions.join(QLatin1Char(' '))); #ifdef HAVE_KFILEMETADATA ApplicationSettings* const aSettings = ApplicationSettings::instance(); if (!aSettings) { return; } d->saveToBalooBox->setChecked(aSettings->getSyncDigikamToBaloo()); d->readFromBalooBox->setChecked(aSettings->getSyncBalooToDigikam()); #endif // HAVE_KFILEMETADATA } bool SetupMetadata::exifAutoRotateHasChanged() const { return (d->exifAutoRotateOriginal != d->exifRotateBox->isChecked()); } void SetupMetadata::slotExifAutoRotateToggled(bool b) { // Show info if rotation was switched off, and only once. if (!b && !d->exifAutoRotateShowedInfo && exifAutoRotateHasChanged()) { d->exifAutoRotateShowedInfo = true; QMessageBox::information(this, qApp->applicationName(), i18nc("@info", "Switching off exif auto rotation will most probably show " "your images in a wrong orientation, so only change this " "option if you explicitly require this.")); } } void SetupMetadata::slotClearMetadataToggled(bool b) { // Show info if delete metadata from the database was switched on, and only once. if (b && !d->clearMetadataShowedInfo) { d->clearMetadataShowedInfo = true; QMessageBox::information(this, qApp->applicationName(), i18nc("@info", "Switching on this option and your metadata has been written to the " "database only and not to the file or sidecar, you will be able to " "lose inserted metadata such as tags, keywords, or geographic " "coordinates.")); } } void SetupMetadata::slotWriteRawFilesToggled(bool b) { // Show info if write metadata to raw files was switched on if (b) { QApplication::beep(); QPointer msgBox = new QMessageBox(QMessageBox::Warning, qApp->applicationName(), i18n("

Do you really want to enable metadata writing to RAW files?

" "

DigiKam delegates this task to the Exiv2 library. With different RAW " "formats, problems are known which can lead to the destruction of RAW " "files. If you decide to do so, make a backup of your RAW files.

" "

We strongly recommend not to enable this option.

"), QMessageBox::Yes | QMessageBox::No, this); msgBox->button(QMessageBox::Yes)->setText(i18n("Yes I understand")); msgBox->setDefaultButton(QMessageBox::No); - int result = msgBox->exec(); + int result1 = msgBox->exec(); delete msgBox; - if (result == QMessageBox::Yes) + if (result1 == QMessageBox::Yes) { QPointer msgBox = new QMessageBox(QMessageBox::Warning, qApp->applicationName(), i18n("You would rather disable writing metadata to RAW files?"), QMessageBox::Yes | QMessageBox::No, this); - int result = msgBox->exec(); + int result2 = msgBox->exec(); delete msgBox; - if (result == QMessageBox::No) + if (result2 == QMessageBox::No) { return; } } d->writeRawFilesBox->setChecked(false); } } } // namespace Digikam