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"