File indexing completed on 2024-05-12 04:19:48

0001 // vim: set tabstop=4 shiftwidth=4 expandtab:
0002 /*
0003 Gwenview: an image viewer
0004 Copyright 2008 Aurélien Gâteau <agateau@kde.org>
0005 
0006 This program is free software; you can redistribute it and/or
0007 modify it under the terms of the GNU General Public License
0008 as published by the Free Software Foundation; either version 2
0009 of the License, or (at your option) any later version.
0010 
0011 This program is distributed in the hope that it will be useful,
0012 but WITHOUT ANY WARRANTY; without even the implied warranty of
0013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0014 GNU General Public License for more details.
0015 
0016 You should have received a copy of the GNU General Public License
0017 along with this program; if not, write to the Free Software
0018 Foundation, Inc., 51 Franklin Street, Fifth Floor, Cambridge, MA 02110-1301, USA.
0019 
0020 */
0021 // Self
0022 #include "tagmodel.h"
0023 
0024 // Qt
0025 #include <QIcon>
0026 
0027 // KF
0028 
0029 // Local
0030 #include "abstractsemanticinfobackend.h"
0031 
0032 namespace Gwenview
0033 {
0034 struct TagModelPrivate {
0035     AbstractSemanticInfoBackEnd *mBackEnd;
0036 };
0037 
0038 static QStandardItem *createItem(const SemanticInfoTag &tag, const QString &label, TagModel::AssignmentStatus status)
0039 {
0040     auto item = new QStandardItem(label);
0041     item->setData(tag, TagModel::TagRole);
0042     item->setData(label.toLower(), TagModel::SortRole);
0043     item->setData(status, TagModel::AssignmentStatusRole);
0044     item->setData(QIcon::fromTheme(QStringLiteral("mail-tagged")), Qt::DecorationRole);
0045     return item;
0046 }
0047 
0048 TagModel::TagModel(QObject *parent)
0049     : QStandardItemModel(parent)
0050     , d(new TagModelPrivate)
0051 {
0052     d->mBackEnd = nullptr;
0053     setSortRole(SortRole);
0054 }
0055 
0056 TagModel::~TagModel()
0057 {
0058     delete d;
0059 }
0060 
0061 void TagModel::setSemanticInfoBackEnd(AbstractSemanticInfoBackEnd *backEnd)
0062 {
0063     d->mBackEnd = backEnd;
0064 }
0065 
0066 void TagModel::setTagSet(const TagSet &set)
0067 {
0068     clear();
0069     for (const SemanticInfoTag &tag : set) {
0070         QString label = d->mBackEnd->labelForTag(tag);
0071         QStandardItem *item = createItem(tag, label, TagModel::FullyAssigned);
0072         appendRow(item);
0073     }
0074     sort(0);
0075 }
0076 
0077 void TagModel::addTag(const SemanticInfoTag &tag, const QString &_label, TagModel::AssignmentStatus status)
0078 {
0079     int row;
0080     QString label = _label.isEmpty() ? d->mBackEnd->labelForTag(tag) : _label;
0081 
0082     const QString sortLabel = label.toLower();
0083     // This is not optimal, implement dichotomic search if necessary
0084     for (row = 0; row < rowCount(); ++row) {
0085         const QModelIndex idx = index(row, 0);
0086         if (idx.data(SortRole).toString().compare(sortLabel) > 0) {
0087             break;
0088         }
0089     }
0090     if (row > 0) {
0091         QStandardItem *_item = item(row - 1);
0092         Q_ASSERT(_item);
0093         if (_item->data(TagRole).toString() == tag) {
0094             // Update, do not add
0095             _item->setData(label.toLower(), SortRole);
0096             _item->setData(status, AssignmentStatusRole);
0097             return;
0098         }
0099     }
0100     QStandardItem *_item = createItem(tag, label, status);
0101     insertRow(row, _item);
0102 }
0103 
0104 void TagModel::removeTag(const SemanticInfoTag &tag)
0105 {
0106     // This is not optimal, implement dichotomic search if necessary
0107     for (int row = 0; row < rowCount(); ++row) {
0108         if (index(row, 0).data(TagRole).toString() == tag) {
0109             removeRow(row);
0110             return;
0111         }
0112     }
0113 }
0114 
0115 TagModel *TagModel::createAllTagsModel(QObject *parent, AbstractSemanticInfoBackEnd *backEnd)
0116 {
0117     auto tagModel = new TagModel(parent);
0118     tagModel->setSemanticInfoBackEnd(backEnd);
0119     tagModel->setTagSet(backEnd->allTags());
0120     connect(backEnd, SIGNAL(tagAdded(SemanticInfoTag, QString)), tagModel, SLOT(addTag(SemanticInfoTag, QString)));
0121     return tagModel;
0122 }
0123 
0124 } // namespace
0125 
0126 #include "moc_tagmodel.cpp"