Warning, file /office/calligra/libs/widgets/KoResourceTaggingManager.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* 0002 * This file is part of the KDE project 0003 * Copyright (c) 2002 Patrick Julien <freak@codepimps.org> 0004 * Copyright (c) 2007 Jan Hambrecht <jaham@gmx.net> 0005 * Copyright (c) 2007 Sven Langkamp <sven.langkamp@gmail.com> 0006 * Copyright (C) 2011 Srikanth Tiyyagura <srikanth.tulasiram@gmail.com> 0007 * Copyright (c) 2011 José Luis Vergara <pentalis@gmail.com> 0008 * Copyright (c) 2013 Sascha Suelzer <s.suelzer@gmail.com> 0009 * 0010 * This library is free software; you can redistribute it and/or 0011 * modify it under the terms of the GNU Library General Public 0012 * License as published by the Free Software Foundation; either 0013 * version 2 of the License, or (at your option) any later version. 0014 * 0015 * This library is distributed in the hope that it will be useful, 0016 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0017 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0018 * Library General Public License for more details. 0019 * 0020 * You should have received a copy of the GNU Library General Public License 0021 * along with this library; see the file COPYING.LIB. If not, write to 0022 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0023 * Boston, MA 02110-1301, USA. 0024 */ 0025 0026 #include "KoResourceTaggingManager.h" 0027 0028 #include <QInputDialog> 0029 #include <QMessageBox> 0030 #include <QPointer> 0031 0032 #include <WidgetsDebug.h> 0033 0034 #include <klocalizedstring.h> 0035 #include <ksharedconfig.h> 0036 0037 #include "KoTagFilterWidget.h" 0038 #include "KoTagChooserWidget.h" 0039 #include "KoResourceModel.h" 0040 #include "KoResource.h" 0041 #include "KoResourceItemChooserContextMenu.h" 0042 0043 #include <kconfiggroup.h> 0044 0045 class TaggedResourceSet 0046 { 0047 public: 0048 TaggedResourceSet() 0049 {} 0050 0051 TaggedResourceSet(const QString& tagName, const QList<KoResource*>& resources) 0052 : tagName(tagName) 0053 , resources(resources) 0054 {} 0055 0056 QString tagName; 0057 QList<KoResource*> resources; 0058 }; 0059 0060 0061 class KoResourceTaggingManager::Private 0062 { 0063 public: 0064 QString currentTag; 0065 QList<KoResource*> originalResources; 0066 TaggedResourceSet lastDeletedTag; 0067 0068 KoTagChooserWidget* tagChooser; 0069 KoTagFilterWidget* tagFilter; 0070 0071 QCompleter* tagCompleter; 0072 0073 QPointer<KoResourceModel> model; 0074 }; 0075 0076 0077 KoResourceTaggingManager::KoResourceTaggingManager(KoResourceModel *model, QWidget* parent) 0078 : QObject(parent) 0079 , d(new Private()) 0080 { 0081 d->model = model; 0082 0083 d->tagChooser = new KoTagChooserWidget(parent); 0084 d->tagChooser->addReadOnlyItem("All"); // not translatable until other tags made translatable! 0085 d->tagChooser->addItems(d->model->tagNamesList()); 0086 0087 d->tagFilter = new KoTagFilterWidget(parent); 0088 0089 connect(d->tagChooser, SIGNAL(tagChosen(QString)), 0090 this, SLOT(tagChooserIndexChanged(QString))); 0091 connect(d->tagChooser, SIGNAL(newTagRequested(QString)), 0092 this, SLOT(contextCreateNewTag(QString))); 0093 connect(d->tagChooser, SIGNAL(tagDeletionRequested(QString)), 0094 this, SLOT(removeTagFromComboBox(QString))); 0095 connect(d->tagChooser, SIGNAL(tagRenamingRequested(QString,QString)), 0096 this, SLOT(renameTag(QString,QString))); 0097 connect(d->tagChooser, SIGNAL(tagUndeletionRequested(QString)), 0098 this, SLOT(undeleteTag(QString))); 0099 connect(d->tagChooser, SIGNAL(tagUndeletionListPurgeRequested()), 0100 this, SLOT(purgeTagUndeleteList())); 0101 0102 connect(d->tagFilter, SIGNAL(saveButtonClicked()), 0103 this, SLOT(tagSaveButtonPressed())); 0104 connect(d->tagFilter, SIGNAL(filterTextChanged(QString)), 0105 this, SLOT(tagSearchLineEditTextChanged(QString))); 0106 0107 connect(d->model, SIGNAL(tagBoxEntryAdded(QString)), 0108 this, SLOT(syncTagBoxEntryAddition(QString))); 0109 connect(d->model, SIGNAL(tagBoxEntryRemoved(QString)), 0110 this, SLOT(syncTagBoxEntryRemoval(QString))); 0111 connect(d->model, SIGNAL(tagBoxEntryModified()), 0112 this, SLOT(syncTagBoxEntries())); 0113 0114 // FIXME: fix tag completer 0115 // d->tagCompleter = new QCompleter(this); 0116 // d->tagSearchLineEdit->setCompleter(d->tagCompleter); 0117 0118 syncTagBoxEntries(); 0119 } 0120 0121 KoResourceTaggingManager::~KoResourceTaggingManager() 0122 { 0123 delete d; 0124 } 0125 0126 void KoResourceTaggingManager::showTaggingBar(bool show) 0127 { 0128 show ? d->tagFilter->show() : d->tagFilter->hide(); 0129 show ? d->tagChooser->show() : d->tagChooser->hide(); 0130 0131 blockSignals(!show); 0132 0133 QString tag("All"); 0134 if (show) { 0135 KConfigGroup group = KSharedConfig::openConfig()->group("SelectedTags"); 0136 tag = group.readEntry<QString>(d->model->serverType(), "All"); 0137 } 0138 0139 d->tagChooser->setCurrentIndex(d->tagChooser->findIndexOf(tag)); 0140 } 0141 0142 void KoResourceTaggingManager::purgeTagUndeleteList() 0143 { 0144 d->lastDeletedTag = TaggedResourceSet(); 0145 d->tagChooser->setUndeletionCandidate(QString()); 0146 } 0147 0148 void KoResourceTaggingManager::undeleteTag(const QString & tagToUndelete) 0149 { 0150 QString tagName = tagToUndelete; 0151 QStringList allTags = availableTags(); 0152 0153 if (allTags.contains(tagName)) { 0154 bool ok; 0155 tagName = QInputDialog::getText( 0156 d->tagChooser, i18n("Unable to undelete tag"), 0157 i18n("<qt>The tag you are trying to undelete already exists in tag list.<br>Please enter a new, unique name for it.</qt>"), 0158 QLineEdit::Normal, 0159 tagName, &ok); 0160 0161 if (!ok || allTags.contains(tagName) || tagName.isEmpty()) { 0162 QMessageBox msgBox; 0163 msgBox.setIcon(QMessageBox::Warning); 0164 msgBox.setText(i18n("Tag was not undeleted.")); 0165 msgBox.exec(); 0166 return; 0167 } 0168 } 0169 0170 QList<KoResource*> serverResources = d->model->serverResources(); 0171 0172 foreach(KoResource * resource, d->lastDeletedTag.resources) { 0173 if (serverResources.contains(resource)) { 0174 addResourceTag(resource, tagName); 0175 } 0176 } 0177 d->model->tagCategoryAdded(tagName); 0178 d->tagChooser->setCurrentIndex(d->tagChooser->findIndexOf(tagName)); 0179 d->tagChooser->setUndeletionCandidate(QString()); 0180 d->lastDeletedTag = TaggedResourceSet(); 0181 } 0182 0183 QStringList KoResourceTaggingManager::availableTags() const 0184 { 0185 return d->tagChooser->allTags(); 0186 } 0187 0188 void KoResourceTaggingManager::addResourceTag(KoResource* resource, const QString& tagName) 0189 { 0190 QStringList tagsList = d->model->assignedTagsList(resource); 0191 if (tagsList.isEmpty()) { 0192 d->model->addTag(resource, tagName); 0193 } else { 0194 foreach(const QString & tag, tagsList) { 0195 if (tag.compare(tagName)) { 0196 d->model->addTag(resource, tagName); 0197 } 0198 } 0199 } 0200 } 0201 0202 void KoResourceTaggingManager::syncTagBoxEntryAddition(const QString& tag) 0203 { 0204 d->tagChooser->insertItem(tag); 0205 } 0206 0207 void KoResourceTaggingManager::contextCreateNewTag(const QString& tag) 0208 { 0209 if (!tag.isEmpty()) { 0210 d->model->addTag(0, tag); 0211 d->model->tagCategoryAdded(tag); 0212 d->tagChooser->setCurrentIndex(d->tagChooser->findIndexOf(tag)); 0213 updateTaggedResourceView(); 0214 } 0215 } 0216 0217 void KoResourceTaggingManager::contextCreateNewTag(KoResource* resource , const QString& tag) 0218 { 0219 if (!tag.isEmpty()) { 0220 d->model->tagCategoryAdded(tag); 0221 if (resource) { 0222 addResourceTag(resource, tag); 0223 } 0224 } 0225 } 0226 0227 void KoResourceTaggingManager::syncTagBoxEntryRemoval(const QString& tag) 0228 { 0229 d->tagChooser->removeItem(tag); 0230 } 0231 0232 void KoResourceTaggingManager::syncTagBoxEntries() 0233 { 0234 QStringList tags = d->model->tagNamesList(); 0235 0236 foreach (const QString &tag, tags) { 0237 d->tagChooser->insertItem(tag); 0238 } 0239 } 0240 0241 void KoResourceTaggingManager::contextAddTagToResource(KoResource* resource, const QString& tag) 0242 { 0243 addResourceTag(resource, tag); 0244 d->model->tagCategoryMembersChanged(); 0245 updateTaggedResourceView(); 0246 } 0247 0248 void KoResourceTaggingManager::contextRemoveTagFromResource(KoResource* resource, const QString& tag) 0249 { 0250 removeResourceTag(resource, tag); 0251 d->model->tagCategoryMembersChanged(); 0252 updateTaggedResourceView(); 0253 } 0254 0255 void KoResourceTaggingManager::removeTagFromComboBox(const QString &tag) 0256 { 0257 QList<KoResource*> resources = d->model->currentlyVisibleResources(); 0258 foreach(KoResource * resource, resources) { 0259 removeResourceTag(resource, tag); 0260 } 0261 d->model->tagCategoryRemoved(tag); 0262 d->lastDeletedTag = TaggedResourceSet(tag, resources); 0263 d->tagChooser->setUndeletionCandidate(tag); 0264 } 0265 0266 void KoResourceTaggingManager::removeResourceTag(KoResource* resource, const QString& tagName) 0267 { 0268 QStringList tagsList = d->model->assignedTagsList(resource); 0269 0270 foreach(const QString & oldName, tagsList) { 0271 if (!oldName.compare(tagName)) { 0272 d->model->deleteTag(resource, oldName); 0273 } 0274 } 0275 } 0276 0277 void KoResourceTaggingManager::renameTag(const QString &oldName, const QString& newName) 0278 { 0279 if (!d->model->tagNamesList().contains(newName)) { 0280 QList<KoResource*> resources = d->model->currentlyVisibleResources(); 0281 0282 foreach(KoResource * resource, resources) { 0283 removeResourceTag(resource, oldName); 0284 addResourceTag(resource, newName); 0285 } 0286 contextCreateNewTag(newName); 0287 d->model->tagCategoryRemoved(oldName); 0288 d->model->tagCategoryAdded(newName); 0289 } 0290 } 0291 0292 void KoResourceTaggingManager::updateTaggedResourceView() 0293 { 0294 d->model->setCurrentTag(d->currentTag); 0295 d->model->updateServer(); 0296 d->originalResources = d->model->currentlyVisibleResources(); 0297 } 0298 0299 void KoResourceTaggingManager::tagChooserIndexChanged(const QString& lineEditText) 0300 { 0301 if (!d->tagChooser->selectedTagIsReadOnly()) { 0302 d->currentTag = lineEditText; 0303 d->tagFilter->allowSave(true); 0304 d->model->enableResourceFiltering(true); 0305 } else { 0306 d->model->enableResourceFiltering(false); 0307 d->tagFilter->allowSave(false); 0308 d->currentTag.clear(); 0309 } 0310 0311 d->tagFilter->clear(); 0312 updateTaggedResourceView(); 0313 } 0314 0315 QString KoResourceTaggingManager::currentTag() 0316 { 0317 return d->tagChooser->currentlySelectedTag(); 0318 } 0319 0320 void KoResourceTaggingManager::tagSearchLineEditTextChanged(const QString& lineEditText) 0321 { 0322 if (d->tagChooser->selectedTagIsReadOnly()) { 0323 d->model->enableResourceFiltering(!lineEditText.isEmpty()); 0324 } else { 0325 d->model->enableResourceFiltering(true); 0326 } 0327 0328 d->model->searchTextChanged(lineEditText); 0329 d->model->updateServer(); 0330 0331 ///FIXME: fix completer 0332 // d->tagCompleter = new QCompleter(tagNamesList(lineEditText),this); 0333 // d->tagSearchLineEdit->setCompleter(d->tagCompleter); 0334 } 0335 0336 void KoResourceTaggingManager::tagSaveButtonPressed() 0337 { 0338 if (!d->tagChooser->selectedTagIsReadOnly()) { 0339 QList<KoResource*> newResources = d->model->currentlyVisibleResources(); 0340 foreach(KoResource * oldRes, d->originalResources) { 0341 if (!newResources.contains(oldRes)) 0342 removeResourceTag(oldRes, d->currentTag); 0343 } 0344 foreach(KoResource * newRes, newResources) { 0345 if (!d->originalResources.contains(newRes)) 0346 addResourceTag(newRes, d->currentTag); 0347 } 0348 d->model->tagCategoryMembersChanged(); 0349 } 0350 updateTaggedResourceView(); 0351 } 0352 0353 void KoResourceTaggingManager::contextMenuRequested(KoResource* resource, const QStringList& resourceTags, const QPoint& pos) 0354 { 0355 /* no visible tag chooser usually means no intended tag interaction, 0356 * context menu makes no sense then either */ 0357 if (!resource || !d->tagChooser->isVisible()) 0358 return; 0359 0360 KoResourceItemChooserContextMenu menu(resource, 0361 resourceTags, 0362 d->tagChooser->currentlySelectedTag(), 0363 d->tagChooser->allTags()); 0364 0365 connect(&menu, SIGNAL(resourceTagAdditionRequested(KoResource*,QString)), 0366 this, SLOT(contextAddTagToResource(KoResource*,QString))); 0367 0368 connect(&menu, SIGNAL(resourceTagRemovalRequested(KoResource*,QString)), 0369 this, SLOT(contextRemoveTagFromResource(KoResource*,QString))); 0370 0371 connect(&menu, SIGNAL(resourceAssignmentToNewTagRequested(KoResource*,QString)), 0372 this, SLOT(contextCreateNewTag(KoResource*,QString))); 0373 menu.exec(pos); 0374 } 0375 0376 void KoResourceTaggingManager::contextMenuRequested(KoResource* currentResource, QPoint pos) 0377 { 0378 if (currentResource) { 0379 contextMenuRequested(currentResource, d->model->assignedTagsList(currentResource), pos); 0380 } 0381 } 0382 0383 KoTagChooserWidget* KoResourceTaggingManager::tagChooserWidget() 0384 { 0385 return d->tagChooser; 0386 } 0387 0388 KoTagFilterWidget* KoResourceTaggingManager::tagFilterWidget() 0389 { 0390 return d->tagFilter; 0391 } 0392