]> cloud.milkyroute.net Git - dolphin.git/blob - src/tagcloud/resourcetaggingwidget.cpp
1e3fffe8f6b5172379b02b33b7a4a4ba43c8fdba
[dolphin.git] / src / tagcloud / resourcetaggingwidget.cpp
1 /*
2 This file is part of the Nepomuk KDE project.
3 Copyright (C) 2007 Sebastian Trueg <trueg@kde.org>
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License version 2 as published by the Free Software Foundation.
8
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
18 */
19
20 #include "resourcetaggingwidget.h"
21 #include "tagcloud.h"
22 #include "taggingpopup.h"
23 #include "../nepomukmassupdatejob.h"
24
25 #include <QtGui/QVBoxLayout>
26 #include <QtGui/QContextMenuEvent>
27 #include <QtGui/QCursor>
28 #include <QtGui/QLabel>
29 #include <QtCore/QSet>
30
31 #include <KLocale>
32
33 namespace Nepomuk {
34 inline uint qHash( const Tag& res )
35 {
36 return qHash( res.resourceUri().toString() );
37 }
38 }
39
40
41 class Nepomuk::ResourceTaggingWidget::Private
42 {
43 public:
44 QList<Nepomuk::Resource> resources;
45
46 TagCloud* resourceTagCloud;
47 TaggingPopup* popup;
48
49 QList<Tag> resourceTags;
50
51 void showTaggingPopup( const QPoint& );
52 void _k_slotShowTaggingPopup();
53 void _k_metadataUpdateDone();
54 static QList<Tag> intersectTags( const QList<Resource>& );
55
56 ResourceTaggingWidget* q;
57 };
58
59
60 void Nepomuk::ResourceTaggingWidget::Private::showTaggingPopup( const QPoint& pos )
61 {
62 popup->showAllTags();
63 resourceTags = intersectTags( resources );
64 Q_FOREACH( const Tag &tag, resourceTags ) {
65 popup->setTagSelected( tag, true );
66 }
67
68 popup->exec( pos );
69
70 MassUpdateJob* job = MassUpdateJob::tagResources( resources, resourceTags );
71 connect( job, SIGNAL( result( KJob* ) ),
72 q, SLOT( _k_metadataUpdateDone() ) );
73 q->setEnabled( false ); // no updates during execution
74 job->start();
75
76 resourceTagCloud->showTags( resourceTags );
77 }
78
79
80 void Nepomuk::ResourceTaggingWidget::Private::_k_slotShowTaggingPopup()
81 {
82 showTaggingPopup( QCursor::pos() );
83 }
84
85
86 void Nepomuk::ResourceTaggingWidget::Private::_k_metadataUpdateDone()
87 {
88 q->setEnabled( true );
89 }
90
91
92 QList<Nepomuk::Tag> Nepomuk::ResourceTaggingWidget::Private::intersectTags( const QList<Resource>& res )
93 {
94 if ( res.count() == 1 ) {
95 return res.first().tags();
96 }
97 else if ( !res.isEmpty() ) {
98 // determine the tags used for all resources
99 QSet<Tag> tags = QSet<Tag>::fromList( res.first().tags() );
100 QList<Resource>::const_iterator it = res.begin();
101 for ( ++it; it != res.end(); ++it ) {
102 tags.intersect( QSet<Tag>::fromList( (*it).tags() ) );
103 }
104 return tags.values();
105 }
106 else {
107 return QList<Tag>();
108 }
109 }
110
111
112 Nepomuk::ResourceTaggingWidget::ResourceTaggingWidget( QWidget* parent )
113 : QWidget( parent ),
114 d( new Private() )
115 {
116 d->q = this;
117
118 QVBoxLayout* layout = new QVBoxLayout( this );
119 layout->setMargin( 0 );
120 d->resourceTagCloud = new TagCloud( this );
121 layout->addWidget( d->resourceTagCloud );
122 QLabel* changeTagsLabel = new QLabel( "<p align=center><a style=\"font-size:small;\" href=\"dummy\">" + i18nc( "@label", "Change Tags..." ) + "</a>", this );
123 connect( changeTagsLabel, SIGNAL( linkActivated( const QString ) ),
124 this, SLOT( _k_slotShowTaggingPopup() ) );
125 layout->addWidget( changeTagsLabel );
126
127 // the popup tag cloud
128 d->popup = new TaggingPopup;
129 d->popup->setSelectionEnabled( true );
130 d->popup->setNewTagButtonEnabled( true );
131
132 connect( d->popup, SIGNAL( tagToggled( const Nepomuk::Tag&, bool ) ),
133 this, SLOT( slotTagToggled( const Nepomuk::Tag&, bool ) ) );
134 connect( d->popup, SIGNAL( tagAdded( const Nepomuk::Tag& ) ),
135 this, SLOT( slotTagAdded( const Nepomuk::Tag& ) ) );
136
137 connect( d->resourceTagCloud, SIGNAL( tagClicked( const Nepomuk::Tag& ) ),
138 this, SIGNAL( tagClicked( const Nepomuk::Tag& ) ) );
139 }
140
141
142 Nepomuk::ResourceTaggingWidget::~ResourceTaggingWidget()
143 {
144 delete d->popup;
145 delete d;
146 }
147
148
149 void Nepomuk::ResourceTaggingWidget::setResource( const Nepomuk::Resource& res )
150 {
151 setResources( QList<Resource>() << res );
152 }
153
154
155 void Nepomuk::ResourceTaggingWidget::setResources( const QList<Nepomuk::Resource>& resList )
156 {
157 d->resources = resList;
158 d->resourceTagCloud->showTags( d->intersectTags( resList ) );
159 }
160
161
162 void Nepomuk::ResourceTaggingWidget::slotTagToggled( const Nepomuk::Tag& tag, bool enabled )
163 {
164 if ( enabled ) {
165 d->resourceTags.append( tag );
166 }
167 else {
168 d->resourceTags.removeAll( tag );
169 }
170 d->popup->hide();
171 }
172
173
174 void Nepomuk::ResourceTaggingWidget::slotTagAdded( const Nepomuk::Tag& tag )
175 {
176 // assign it right away
177 d->resourceTags.append( tag );
178 // d->resource.addTag( tag );
179 }
180
181
182 void Nepomuk::ResourceTaggingWidget::contextMenuEvent( QContextMenuEvent* e )
183 {
184 d->showTaggingPopup( e->globalPos() );
185 }
186
187
188 void Nepomuk::ResourceTaggingWidget::showTagPopup( const QPoint& pos )
189 {
190 d->showTaggingPopup( pos );
191 }
192
193 #include "resourcetaggingwidget.moc"