diff --git a/core/libs/widgets/history/filtershistorywidget.cpp b/core/libs/widgets/history/filtershistorywidget.cpp index 7a4a238b3f..69917bead2 100644 --- a/core/libs/widgets/history/filtershistorywidget.cpp +++ b/core/libs/widgets/history/filtershistorywidget.cpp @@ -1,170 +1,170 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-08-03 * Description : Widget displaying filters history used on an image * * Copyright (C) 2010 by Martin Klapetek * * 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 "filtershistorywidget.h" // Qt includes #include #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "itemfiltershistorymodel.h" #include "itemfiltershistorytreeitem.h" #include "itemfiltershistoryitemdelegate.h" namespace Digikam { RemoveFilterAction::RemoveFilterAction(const QString& label, const QModelIndex& index, QObject* const parent) : QAction(label, parent) { m_index = index; } // ------------------------------------------------------------------------------------------------------- class Q_DECL_HIDDEN FiltersHistoryWidget::Private { public: explicit Private() + : view(nullptr), + model(nullptr), + layout(nullptr), + delegate(nullptr), + headerLabel(nullptr) { - view = nullptr; - model = nullptr; - layout = nullptr; - delegate = nullptr; - headerLabel = nullptr; } - QTreeView* view; + QTreeView* view; ItemFiltersHistoryModel* model; - QGridLayout* layout; + QGridLayout* layout; ItemFiltersHistoryItemDelegate* delegate; - QLabel* headerLabel; + QLabel* headerLabel; }; FiltersHistoryWidget::FiltersHistoryWidget(QWidget* const parent) : QWidget(parent), d(new Private) { d->layout = new QGridLayout(this); d->view = new QTreeView(this); d->delegate = new ItemFiltersHistoryItemDelegate(this); d->model = new ItemFiltersHistoryModel(nullptr, QUrl()); d->headerLabel = new QLabel(this); d->headerLabel->setText(i18n("Used filters")); d->layout->addWidget(d->headerLabel); d->layout->addWidget(d->view); d->view->setItemDelegate(d->delegate); d->view->setModel(d->model); d->view->setRootIsDecorated(false); d->view->setContextMenuPolicy(Qt::CustomContextMenu); d->view->setHeaderHidden(true); connect(d->view, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showCustomContextMenu(QPoint))); } FiltersHistoryWidget::~FiltersHistoryWidget() { delete d->model; delete d->delegate; delete d; } void FiltersHistoryWidget::setCurrentURL(const QUrl& url) { d->model->setUrl(url); d->view->setModel(d->model); d->view->update(); } void FiltersHistoryWidget::showCustomContextMenu(const QPoint& position) { QList actions; if (d->view->indexAt(position).isValid()) { QModelIndex index = d->view->indexAt(position); QString s(i18n("Remove filter")); RemoveFilterAction* removeFilterAction = new RemoveFilterAction(s, index, nullptr); removeFilterAction->setDisabled(true); if (!index.model()->parent(index).isValid()) { actions.append(removeFilterAction); connect(removeFilterAction, SIGNAL(triggered()), removeFilterAction, SLOT(triggerSlot())); connect(removeFilterAction, SIGNAL(actionTriggered(QModelIndex)), d->model, SLOT(removeEntry(QModelIndex))); } } if (actions.count() > 0) { QMenu::exec(actions, d->view->mapToGlobal(position)); } } void FiltersHistoryWidget::setHistory(const DImageHistory& history) { d->model->setupModelData(history.entries()); } void FiltersHistoryWidget::setEnabledEntries(int count) { d->model->setEnabledEntries(count); } void FiltersHistoryWidget::disableEntries(int count) { d->model->disableEntries(count); } void FiltersHistoryWidget::enableEntries(int count) { d->model->enableEntries(count); } void FiltersHistoryWidget::clearData() { d->model->removeRows(0, d->model->rowCount(), d->model->index(0, 0)); } } // namespace Digikam diff --git a/core/libs/widgets/history/itemfiltershistoryitemdelegate.cpp b/core/libs/widgets/history/itemfiltershistoryitemdelegate.cpp index 3b824ae369..faf477b721 100644 --- a/core/libs/widgets/history/itemfiltershistoryitemdelegate.cpp +++ b/core/libs/widgets/history/itemfiltershistoryitemdelegate.cpp @@ -1,157 +1,158 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-07-02 * Description : delegate for custom painting of used filters view * * Copyright (C) 2010 by Martin Klapetek * * 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 "itemfiltershistoryitemdelegate.h" // Qt includes #include #include #include #include #include #include // KDE includes #include // Local includes #include "digikam_debug.h" #include "dimgfiltermanager.h" namespace Digikam { ItemFiltersHistoryItemDelegate::ItemFiltersHistoryItemDelegate(QObject* const parent) : QStyledItemDelegate(parent) { } ItemFiltersHistoryItemDelegate::~ItemFiltersHistoryItemDelegate() { } QSize ItemFiltersHistoryItemDelegate::sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const { // Add padding of 6px + QSize size = QStyledItemDelegate::sizeHint(option, index); if (!size.isNull()) { return QSize(size.width(), size.height() + 12); } return size; } void ItemFiltersHistoryItemDelegate::paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const { if (!(option.state & QStyle::State_Enabled)) { // If disabled, use italic font + QStyleOptionViewItem o(option); QFont font(o.font); font.setItalic(true); o.font = font; QStyledItemDelegate::paint(painter, o, index); } else { QStyledItemDelegate::paint(painter, option, index); } // draw 1px border + QPen oldPen = painter->pen(); QPen pen(option.palette.windowText(), 0); painter->setPen(pen); painter->drawRect(option.rect); painter->setPen(oldPen); /* painter->save(); painter->setRenderHint(QPainter::Antialiasing, true); QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &option, painter); KColorScheme sysColors(QPalette::Normal); QPen thinLinePen; thinLinePen.setWidth(0); thinLinePen.setCosmetic(true); thinLinePen.setBrush(sysColors.foreground()); Qt::ItemFlags flags = index.flags(); if (!index.model()->parent(index).isValid()) { painter->setPen(thinLinePen); painter->setRenderHint(QPainter::Antialiasing, false); painter->drawRect(option.rect); painter->setRenderHint(QPainter::Antialiasing, true); QPixmap icon = QIcon::fromTheme(index.data(Qt::DecorationRole).toString()).pixmap(22, (flags & Qt::ItemIsEnabled) ? QIcon::Normal : QIcon::Disabled ); painter->drawPixmap(option.rect.left()+4, option.rect.top()+5, icon); } QRect textRect = option.rect; textRect.setLeft(textRect.left() + 32); if (!flags & Qt::ItemIsEnabled) { QFont disabledFont(QApplication::font()); disabledFont.setItalic(true); QPalette disabledColor; painter->setFont(disabledFont); painter->setPen(disabledColor.color(QPalette::Disabled, QPalette::WindowText)); } if (!index.data(Qt::DisplayRole).toString().isEmpty()) { painter->drawText(textRect, Qt::AlignVCenter, index.data(Qt::DisplayRole).toString()); } else { //infoIcon.setToolTip(i18n("This filter's name is unknown, so you see only its identifier")); //FIXME: better string? painter->drawPixmap(option.rect.right() - 22, option.rect.top() + 8, QIcon::fromTheme(QLatin1String("dialog-information")).pixmap(style()->pixelMetric(QStyle::PM_SmallIconSize))); painter->drawText(textRect, Qt::AlignVCenter, index.data(Qt::DecorationRole).toString()); } - / * if (entryDisabled) { //painter->fillRect(option.rect, QColor(200,200,200,160)); } - * / painter->restore(); */ } } //namespace Digikam diff --git a/core/libs/widgets/history/itemfiltershistoryitemdelegate.h b/core/libs/widgets/history/itemfiltershistoryitemdelegate.h index 77f52a3b6b..1645db4e58 100644 --- a/core/libs/widgets/history/itemfiltershistoryitemdelegate.h +++ b/core/libs/widgets/history/itemfiltershistoryitemdelegate.h @@ -1,47 +1,47 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-07-02 * Description : delegate for custom painting of used filters view * * Copyright (C) 2010 by Martin Klapetek * * 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. * * ============================================================ */ #ifndef DIGIKAM_ITEM_FILTERS_HISTORY_ITEM_DELEGATE_H #define DIGIKAM_ITEM_FILTERS_HISTORY_ITEM_DELEGATE_H // Qt includes #include namespace Digikam { class ItemFiltersHistoryItemDelegate : public QStyledItemDelegate { public: explicit ItemFiltersHistoryItemDelegate(QObject* const parent = nullptr); ~ItemFiltersHistoryItemDelegate(); virtual void paint(QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; - virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; + virtual QSize sizeHint(const QStyleOptionViewItem& option, const QModelIndex& index) const; }; } //namespace Digikam #endif // DIGIKAM_ITEM_FILTERS_HISTORY_ITEM_DELEGATE_H diff --git a/core/libs/widgets/history/itemfiltershistorymodel.cpp b/core/libs/widgets/history/itemfiltershistorymodel.cpp index 7389b67c9a..7fe1d3317c 100644 --- a/core/libs/widgets/history/itemfiltershistorymodel.cpp +++ b/core/libs/widgets/history/itemfiltershistorymodel.cpp @@ -1,373 +1,390 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-06-23 * Description : model for view with used filters on currently loaded image * * Copyright (C) 2010 by Martin Klapetek * * 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 "itemfiltershistorymodel.h" // Qt includes #include #include #include #include // Local includes #include "digikam_debug.h" #include "dimgfiltermanager.h" #include "dmetadata.h" #include "itemfiltershistorytreeitem.h" namespace Digikam { class Q_DECL_HIDDEN ItemFiltersHistoryModel::Private { public: explicit Private() : rootItem(nullptr), disabledEntries(0) { } ItemFiltersHistoryTreeItem* rootItem; QList filterStack; QUrl lastUrl; int disabledEntries; }; ItemFiltersHistoryModel::ItemFiltersHistoryModel(QObject* const parent, const QUrl& url) : QAbstractItemModel(parent), d(new Private) { if (!url.isEmpty()) { //qCDebug(DIGIKAM_WIDGETS_LOG) << "Creating model with url" << url.toLocalFile(); + d->rootItem = new ItemFiltersHistoryTreeItem(url.fileName()); d->lastUrl = url; DMetadata metadata(url.toLocalFile()); QString xml = metadata.getItemHistory(); DImageHistory h = DImageHistory::fromXml(xml); setupModelData(h.entries(), d->rootItem); } else { //qCDebug(DIGIKAM_WIDGETS_LOG) << "Creating empty model"; + d->rootItem = new ItemFiltersHistoryTreeItem(QLatin1String("Generic")); } } ItemFiltersHistoryModel::~ItemFiltersHistoryModel() { delete d->rootItem; delete d; } void ItemFiltersHistoryModel::setUrl(const QUrl& url) { if (!url.isEmpty()) { - //delete the current model data + // delete the current model data + delete d->rootItem; d->rootItem = new ItemFiltersHistoryTreeItem(url.fileName()); d->lastUrl = url; + //qCDebug(DIGIKAM_WIDGETS_LOG) << "Updating model data with url" << rootData.first(); + DMetadata metadata(url.toLocalFile()); setupModelData(DImageHistory::fromXml(metadata.getItemHistory()).entries(), d->rootItem); } /* else { qCDebug(DIGIKAM_WIDGETS_LOG) << "Model not updated; url is" << url.pathOrUrl(); } */ } int ItemFiltersHistoryModel::columnCount(const QModelIndex& /*parent*/) const { return 1; /* if (parent.isValid()) + { return static_cast(parent.internalPointer())->columnCount(); + } else + { return d->rootItem->columnCount(); + } */ } QVariant ItemFiltersHistoryModel::data(const QModelIndex& index, int role) const { if (!index.isValid()) { return QVariant(); } ItemFiltersHistoryTreeItem* item = nullptr; - if (role == Qt::DecorationRole) + if (role == Qt::DecorationRole) { item = static_cast(index.internalPointer()); + return item->data(1); } else if (role == Qt::DisplayRole) { item = static_cast(index.internalPointer()); + return item->data(0); } return QVariant(); } Qt::ItemFlags ItemFiltersHistoryModel::flags(const QModelIndex& index) const { if (!index.isValid()) { return nullptr; } Qt::ItemFlags flags = Qt::ItemIsSelectable; if (!static_cast(index.internalPointer())->isDisabled()) { flags |= Qt::ItemIsEnabled; } return flags; } QVariant ItemFiltersHistoryModel::headerData(int section, Qt::Orientation orientation, int role) const { - if (orientation == Qt::Horizontal && role == Qt::DisplayRole) + if ((orientation == Qt::Horizontal) && (role == Qt::DisplayRole)) { return d->rootItem->data(section); } return QVariant(); } QModelIndex ItemFiltersHistoryModel::index(int row, int column, const QModelIndex& parent) const { if (!hasIndex(row, column, parent)) { return QModelIndex(); } ItemFiltersHistoryTreeItem* parentItem = nullptr; if (!parent.isValid()) { parentItem = d->rootItem; } else { parentItem = static_cast(parent.internalPointer()); } ItemFiltersHistoryTreeItem* const childItem = parentItem->child(row); if (childItem) { return createIndex(row, column, childItem); } else { return QModelIndex(); } } QModelIndex ItemFiltersHistoryModel::parent(const QModelIndex& index) const { if (!index.isValid()) { return QModelIndex(); } ItemFiltersHistoryTreeItem* const childItem = static_cast(index.internalPointer()); ItemFiltersHistoryTreeItem* const parentItem = childItem->parent(); if (parentItem == d->rootItem) { return QModelIndex(); } return createIndex(parentItem->row(), 0, parentItem); } int ItemFiltersHistoryModel::rowCount(const QModelIndex& parent) const { ItemFiltersHistoryTreeItem* parentItem = nullptr; if (parent.column() > 0) { return 0; } if (!parent.isValid()) { parentItem = d->rootItem; } else { parentItem = static_cast(parent.internalPointer()); } return parentItem->childCount(); } void ItemFiltersHistoryModel::setupModelData(const QList& entries, ItemFiltersHistoryTreeItem* parent) { beginResetModel(); if (!parent || entries.isEmpty()) { delete d->rootItem; d->rootItem = new ItemFiltersHistoryTreeItem(d->lastUrl.fileName()); parent = d->rootItem; if (entries.isEmpty()) { endResetModel(); return; } } //qCDebug(DIGIKAM_WIDGETS_LOG) << "Initializing model data, got" << entries.count() << "entries"; + QList parents; QList filters; parents << parent; QList itemData; d->filterStack.clear(); - for (int i = 0; i < entries.count(); ++i) + for (int i = 0 ; i < entries.count() ; ++i) { // the first entry, for the original, may not have an Action + if (entries.at(i).action.isNull()) { continue; } d->filterStack.append(entries.at(i).action); itemData.append(DImgFilterManager::instance()->i18nDisplayableName(entries.at(i).action)); QString iconName = DImgFilterManager::instance()->filterIcon(entries.at(i).action); QPixmap icon = QIcon::fromTheme(iconName).pixmap(22); itemData.append(icon); //qCDebug(DIGIKAM_WIDGETS_LOG) << "Adding an entry: " << itemData; + parents.first()->appendChild(new ItemFiltersHistoryTreeItem(itemData, parents.first())); filters << parents.last()->child(parents.last()->childCount()-1); /* QHashIterator iter(entries.at(i).action.parameters()); + while (iter.hasNext()) { QList columnData; iter.next(); columnData << iter.key() << iter.value(); filters.last()->appendChild(new ItemFiltersHistoryTreeItem(columnData, filters.last())); } */ itemData.clear(); } d->disabledEntries = 0; endResetModel(); } void ItemFiltersHistoryModel::removeEntry(const QModelIndex& index) { removeRow(index.row(), index.parent()); } bool ItemFiltersHistoryModel::removeRows(int row, int /*count*/, const QModelIndex& parent) { if (!parent.isValid()) { beginResetModel(); d->rootItem->removeChild(row); d->filterStack.removeAt(row); endResetModel(); + //TODO: emit signal starting FilterManager + return true; } return false; } void ItemFiltersHistoryModel::setEnabledEntries(int count) { - for (int i=0; irootItem->childCount(); ++i) + for (int i = 0 ; i < d->rootItem->childCount() ; ++i) { d->rootItem->child(i)->setDisabled(i >= count); } d->disabledEntries = qMax(rowCount() - count, 0); emit dataChanged(index(0, 0), index(rowCount() - 1, 0)); } void ItemFiltersHistoryModel::disableEntries(int count) { if (count > rowCount()) { count = rowCount(); } d->disabledEntries += count; while (count > 0) { d->rootItem->child(rowCount() - d->disabledEntries - 1 + count)->setDisabled(true); --count; } emit dataChanged(index(0, 0), index(rowCount() - 1, 0)); } void ItemFiltersHistoryModel::enableEntries(int count) { if (count > rowCount()) { count = rowCount(); } int tmp = count; while (count > 0) { d->rootItem->child(rowCount()-d->disabledEntries-1+count)->setDisabled(false); --count; } d->disabledEntries -= tmp; emit dataChanged(index(0, 0), index(rowCount() - 1, 0)); } } // namespace Digikam diff --git a/core/libs/widgets/history/itemfiltershistorytreeitem.cpp b/core/libs/widgets/history/itemfiltershistorytreeitem.cpp index b40f152d95..4bfc0c7c69 100644 --- a/core/libs/widgets/history/itemfiltershistorytreeitem.cpp +++ b/core/libs/widgets/history/itemfiltershistorytreeitem.cpp @@ -1,126 +1,126 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-06-23 * Description : widget for displaying an item in view with used filters on current image * * Copyright (C) 2010 by Martin Klapetek * * 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 "itemfiltershistorytreeitem.h" namespace Digikam { class Q_DECL_HIDDEN ItemFiltersHistoryTreeItem::Private { public: explicit Private() + : parentItem(nullptr), + disabled(false) { - parentItem = nullptr; - disabled = false; } QList childItems; - QList itemData; + QList itemData; ItemFiltersHistoryTreeItem* parentItem; - bool disabled; + bool disabled; }; ItemFiltersHistoryTreeItem::ItemFiltersHistoryTreeItem(const QList& data, ItemFiltersHistoryTreeItem* const parent) : d(new Private) { d->parentItem = parent; d->itemData = data; } ItemFiltersHistoryTreeItem::ItemFiltersHistoryTreeItem(const QString& data, ItemFiltersHistoryTreeItem* const parent) : d(new Private) { d->parentItem = parent; d->itemData.append(data); } ItemFiltersHistoryTreeItem::ItemFiltersHistoryTreeItem(const ItemFiltersHistoryTreeItem& other) : d(new Private(*other.d)) { } ItemFiltersHistoryTreeItem::~ItemFiltersHistoryTreeItem() { qDeleteAll(d->childItems); delete d; } void ItemFiltersHistoryTreeItem::appendChild(ItemFiltersHistoryTreeItem* const item) { d->childItems.append(item); } ItemFiltersHistoryTreeItem* ItemFiltersHistoryTreeItem::child(int row) const { return d->childItems.value(row); } int ItemFiltersHistoryTreeItem::childCount() const { return d->childItems.count(); } int ItemFiltersHistoryTreeItem::columnCount() const { return d->itemData.count(); } QVariant ItemFiltersHistoryTreeItem::data(int column) const { return d->itemData.value(column); } ItemFiltersHistoryTreeItem* ItemFiltersHistoryTreeItem::parent() const { return d->parentItem; } int ItemFiltersHistoryTreeItem::row() const { if (d->parentItem) { return d->parentItem->d->childItems.indexOf(const_cast(this)); } return 0; } void ItemFiltersHistoryTreeItem::removeChild(int row) { delete child(row); d->childItems.removeAt(row); } bool ItemFiltersHistoryTreeItem::isDisabled() const { return d->disabled; } void ItemFiltersHistoryTreeItem::setDisabled(bool disabled) const { d->disabled = disabled; } } // namespace Digikam diff --git a/core/libs/widgets/history/itemfiltershistorytreeitem.h b/core/libs/widgets/history/itemfiltershistorytreeitem.h index f6753395d7..88f183cfc9 100644 --- a/core/libs/widgets/history/itemfiltershistorytreeitem.h +++ b/core/libs/widgets/history/itemfiltershistorytreeitem.h @@ -1,73 +1,73 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-06-23 * Description : widget for displaying an item in view with used filters on current image * * Copyright (C) 2010 by Martin Klapetek * * 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. * * ============================================================ */ #ifndef DIGIKAM_ITEM_FILTERS_HISTORY_TREE_ITEM_H #define DIGIKAM_ITEM_FILTERS_HISTORY_TREE_ITEM_H // Qt includes #include #include // Local includes #include "digikam_export.h" namespace Digikam { class ItemFiltersHistoryTreeItem { public: explicit ItemFiltersHistoryTreeItem(const QList& data, ItemFiltersHistoryTreeItem* const parent = nullptr); explicit ItemFiltersHistoryTreeItem(const QString& data, ItemFiltersHistoryTreeItem* const parent = nullptr); ~ItemFiltersHistoryTreeItem(); void appendChild(ItemFiltersHistoryTreeItem* const child); void removeChild(int row); - ItemFiltersHistoryTreeItem* child(int row) const; - int childCount() const; - int columnCount() const; - QVariant data(int column) const; - int row() const; - ItemFiltersHistoryTreeItem* parent() const; - void setDisabled(bool disabled) const; - bool isDisabled() const; + ItemFiltersHistoryTreeItem* child(int row) const; + int childCount() const; + int columnCount() const; + QVariant data(int column) const; + int row() const; + ItemFiltersHistoryTreeItem* parent() const; + void setDisabled(bool disabled) const; + bool isDisabled() const; private: // Hidden copy constructor and assignment operator. ItemFiltersHistoryTreeItem(const ItemFiltersHistoryTreeItem&); ItemFiltersHistoryTreeItem& operator=(const ItemFiltersHistoryTreeItem&); private: class Private; Private* const d; }; } // namespace Digikam #endif // DIGIKAM_ITEM_FILTERS_HISTORY_TREE_ITEM_H diff --git a/core/libs/widgets/history/versionswidget.cpp b/core/libs/widgets/history/versionswidget.cpp index b01a592d42..599b34a1e7 100644 --- a/core/libs/widgets/history/versionswidget.cpp +++ b/core/libs/widgets/history/versionswidget.cpp @@ -1,281 +1,290 @@ /* ============================================================ * * This file is a part of digiKam project * https://www.digikam.org * * Date : 2010-08-03 * Description : widget displaying all image versions in a list * * Copyright (C) 2010 by Martin Klapetek * * 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 "versionswidget.h" // Qt includes #include #include #include #include #include #include #include #include #include // KDE includes #include #include // Local includes #include "digikam_debug.h" #include "applicationsettings.h" #include "dimagehistory.h" #include "itemhistorygraphmodel.h" #include "iteminfo.h" #include "itemlistmodel.h" #include "thumbnailloadthread.h" #include "versionsdelegate.h" #include "versionmanagersettings.h" #include "versionsoverlays.h" #include "versionstreeview.h" namespace Digikam { class Q_DECL_HIDDEN VersionsWidget::Private { public: explicit Private() : view(nullptr), model(nullptr), delegate(nullptr), showHideOverlay(nullptr), viewButtonGroup(nullptr), listModeButton(nullptr), treeModeButton(nullptr), combinedModeButton(nullptr) { } VersionsTreeView* view; - ItemHistoryGraphModel* model; + ItemHistoryGraphModel* model; VersionsDelegate* delegate; ShowHideVersionsOverlay* showHideOverlay; QButtonGroup* viewButtonGroup; QToolButton* listModeButton; QToolButton* treeModeButton; QToolButton* combinedModeButton; static const QString configCurrentMode; }; const QString VersionsWidget::Private::configCurrentMode(QLatin1String("Version Properties View Mode")); VersionsWidget::VersionsWidget(QWidget* const parent) : QWidget(parent), d(new Private) { QGridLayout* const layout = new QGridLayout; d->viewButtonGroup = new QButtonGroup(this); d->listModeButton = new QToolButton; d->listModeButton->setIcon(QIcon::fromTheme(QLatin1String("view-list-icons"))); d->listModeButton->setCheckable(true); d->listModeButton->setToolTip(i18n("Show available versions in a list")); d->viewButtonGroup->addButton(d->listModeButton, ItemHistoryGraphModel::ImagesListMode); d->treeModeButton = new QToolButton; d->treeModeButton->setIcon(QIcon::fromTheme(QLatin1String("view-list-tree"))); d->treeModeButton->setCheckable(true); d->treeModeButton->setToolTip(i18n("Show available versions as a tree")); d->viewButtonGroup->addButton(d->treeModeButton, ItemHistoryGraphModel::ImagesTreeMode); d->combinedModeButton = new QToolButton; d->combinedModeButton->setIcon(QIcon::fromTheme(QLatin1String("view-list-details"))); d->combinedModeButton->setCheckable(true); d->combinedModeButton->setToolTip(i18n("Show available versions and the applied filters in a combined list")); d->viewButtonGroup->addButton(d->combinedModeButton, ItemHistoryGraphModel::CombinedTreeMode); QHBoxLayout* const buttonLayout = new QHBoxLayout; buttonLayout->addWidget(d->listModeButton); buttonLayout->addWidget(d->treeModeButton); buttonLayout->addWidget(d->combinedModeButton); d->model = new ItemHistoryGraphModel(this); d->model->imageModel()->setThumbnailLoadThread(ThumbnailLoadThread::defaultIconViewThread()); d->view = new VersionsTreeView; d->view->setModel(d->model); d->view->setWordWrap(true); d->view->setRootIsDecorated(false); d->view->setHeaderHidden(true); d->view->setSelectionMode(QAbstractItemView::SingleSelection); //d->view->setFrameShape(QFrame::NoFrame); d->view->setFrameShadow(QFrame::Plain); layout->addLayout(buttonLayout, 0, 1); layout->addWidget(d->view, 1, 0, 1, 2); layout->setColumnStretch(0, 1); layout->setRowStretch(1, 1); setLayout(layout); connect(d->view->delegate(), SIGNAL(animationStateChanged()), d->view->viewport(), SLOT(update())); connect(d->view->selectionModel(), SIGNAL(currentChanged(QModelIndex,QModelIndex)), this, SLOT(slotViewCurrentChanged(QModelIndex,QModelIndex))); connect(d->viewButtonGroup, SIGNAL(buttonClicked(int)), this, SLOT(slotViewModeChanged(int))); connect(ApplicationSettings::instance(), SIGNAL(setupChanged()), this, SLOT(slotSetupChanged())); slotSetupChanged(); } VersionsWidget::~VersionsWidget() { delete d; } void VersionsWidget::readSettings(const KConfigGroup& group) { int mode = group.readEntry(d->configCurrentMode, (int)ItemHistoryGraphModel::CombinedTreeMode); switch (mode) { case ItemHistoryGraphModel::ImagesListMode: d->listModeButton->setChecked(true); break; + case ItemHistoryGraphModel::ImagesTreeMode: d->treeModeButton->setChecked(true); break; + case ItemHistoryGraphModel::CombinedTreeMode: default: d->combinedModeButton->setChecked(true); break; } slotViewModeChanged(mode); } VersionsTreeView* VersionsWidget::view() const { return d->view; } VersionsDelegate* VersionsWidget::delegate() const { return d->delegate; } ActionVersionsOverlay* VersionsWidget::addActionOverlay(const QIcon& icon, const QString& text, const QString& tip) { ActionVersionsOverlay* const overlay = new ActionVersionsOverlay(this, icon, text, tip); d->view->addOverlay(overlay); + return overlay; } ShowHideVersionsOverlay* VersionsWidget::addShowHideOverlay() { d->showHideOverlay = new ShowHideVersionsOverlay(this); d->showHideOverlay->setSettings(ApplicationSettings::instance()->getVersionManagerSettings()); d->view->addOverlay(d->showHideOverlay); + return d->showHideOverlay; } void VersionsWidget::writeSettings(KConfigGroup& group) { group.writeEntry(d->configCurrentMode, d->viewButtonGroup->checkedId()); } void VersionsWidget::setCurrentItem(const ItemInfo& info) { d->model->setHistory(info); applyViewMode(); } void VersionsWidget::slotViewCurrentChanged(const QModelIndex& current, const QModelIndex& previous) { ItemInfo info = d->model->imageInfo(current); if (!info.isNull()) { emit imageSelected(info); } switch (d->model->mode()) { case ItemHistoryGraphModel::ImagesListMode: case ItemHistoryGraphModel::ImagesTreeMode: break; + case ItemHistoryGraphModel::CombinedTreeMode: + // toplevel image index + if (!info.isNull() && !current.parent().isValid()) { d->view->expand(current); } if (previous.isValid() && d->model->isImage(previous) && !previous.parent().isValid()) { d->view->collapse(previous); } break; } } void VersionsWidget::slotViewModeChanged(int mode) { d->model->setMode((ItemHistoryGraphModel::Mode)mode); applyViewMode(); } void VersionsWidget::applyViewMode() { switch (d->model->mode()) { case ItemHistoryGraphModel::ImagesListMode: break; + case ItemHistoryGraphModel::ImagesTreeMode: d->view->expandAll(); break; + case ItemHistoryGraphModel::CombinedTreeMode: d->view->collapseAll(); break; } QModelIndex subjectIndex = d->model->indexForInfo(d->model->subject()); d->view->scrollTo(subjectIndex, QAbstractItemView::PositionAtCenter); d->view->setCurrentIndex(subjectIndex); } void VersionsWidget::slotSetupChanged() { d->view->setToolTipEnabled(ApplicationSettings::instance()->showToolTipsIsValid()); if (d->showHideOverlay) { d->showHideOverlay->setSettings(ApplicationSettings::instance()->getVersionManagerSettings()); } } } // namespace Digikam