23 #include "messagecore/nepomukutil/asyncnepomukresourceretriever.h"
25 #include "mailcommon/tag/addtagdialog.h"
27 #include <Nepomuk2/Tag>
28 #include <Nepomuk2/ResourceManager>
29 #include <Nepomuk2/Query/QueryServiceClient>
30 #include <Nepomuk2/Query/Result>
31 #include <Nepomuk2/Query/ResourceTypeTerm>
34 #include <KActionCollection>
35 #include <KActionMenu>
37 #include <KToggleAction>
38 #include <KXMLGUIClient>
39 #include <KMessageBox>
43 #include <QSignalMapper>
45 #include <soprano/nao.h>
46 #include <nepomuk2/resourcewatcher.h>
48 using namespace KMail;
55 mActionCollection( actionCollection ),
56 mMessageActions( messageActions ),
57 mMessageTagToggleMapper( 0 ),
58 mGUIClient( guiClient ),
59 mSeparatorMoreAction( 0 ),
60 mSeparatorNewTagAction( 0 ),
66 connect( Nepomuk2::ResourceManager::instance(), SIGNAL(nepomukSystemStarted()),
67 SLOT(tagsChanged()) );
68 connect( Nepomuk2::ResourceManager::instance(), SIGNAL(nepomukSystemStopped()),
69 SLOT(tagsChanged()) );
71 Nepomuk2::ResourceWatcher* watcher =
new Nepomuk2::ResourceWatcher(
this);
72 watcher->addType(Soprano::Vocabulary::NAO::Tag());
73 connect(watcher, SIGNAL(resourceCreated(Nepomuk2::Resource,
QList<QUrl>)),
this, SLOT(resourceCreated(Nepomuk2::Resource,
QList<QUrl>)));
75 connect(watcher, SIGNAL(propertyChanged(Nepomuk2::Resource,Nepomuk2::Types::Property,QVariantList,QVariantList)),
this,SLOT(propertyChanged(Nepomuk2::Resource)));
78 QVector<QUrl> properties;
79 properties << Soprano::Vocabulary::NAO::hasTag();
81 mAsyncNepomukRetriver =
new MessageCore::AsyncNepomukResourceRetriever(properties,
this);
82 connect(mAsyncNepomukRetriver, SIGNAL(resourceReceived(QUrl,Nepomuk2::Resource)),
83 this, SLOT(slotLoadedResourceForUpdateActionStates(QUrl,Nepomuk2::Resource)));
93 if ( !mToolbarActions.isEmpty() ) {
94 if ( mGUIClient->factory() ) {
95 mGUIClient->unplugActionList( QLatin1String(
"toolbar_messagetag_actions") );
97 mToolbarActions.clear();
102 foreach( KAction *action, mTagActions ) {
106 mActionCollection->removeAction( action );
109 if ( mSeparatorMoreAction ) {
113 if ( mSeparatorNewTagAction ) {
117 if ( mNewTagAction ) {
127 delete mMessageTagToggleMapper;
128 mMessageTagToggleMapper = 0;
131 void TagActionManager::createTagAction(
const MailCommon::Tag::Ptr &tag,
bool addToMenu )
133 QString cleanName( i18n(
"Message Tag %1", tag->tagName ) );
134 cleanName.replace(QLatin1Char(
'&'), QLatin1String(
"&&"));
135 KToggleAction *
const tagAction =
new KToggleAction( KIcon( tag->iconName ),
137 tagAction->setShortcut( tag->shortcut );
138 tagAction->setIconText( tag->tagName );
139 tagAction->setChecked( tag->nepomukResourceUri == mNewTagUri );
141 mActionCollection->addAction( tag->nepomukResourceUri.toString(), tagAction );
142 connect( tagAction, SIGNAL(triggered(
bool)),
143 mMessageTagToggleMapper, SLOT(map()) );
148 tagAction->setShortcutConfigurable(
false );
149 mMessageTagToggleMapper->setMapping( tagAction, tag->nepomukResourceUri.toString() );
151 mTagActions.insert( tag->nepomukResourceUri.toString(), tagAction );
155 if ( tag->inToolbar ) {
156 mToolbarActions.append( tagAction );
162 if( mTagQueryClient )
166 if ( mTags.isEmpty() ) {
167 mTagQueryClient =
new Nepomuk2::Query::QueryServiceClient(
this);
170 connect( mTagQueryClient, SIGNAL(finishedListing()),
171 this, SLOT(finishedTagListing()) );
172 Nepomuk2::Query::ResourceTypeTerm term( Soprano::Vocabulary::NAO::Tag() );
173 Nepomuk2::Query::Query query( term );
174 mTagQueryClient->query(query);
180 void TagActionManager::createTagActions()
183 mMessageTagToggleMapper =
new QSignalMapper(
this );
184 connect( mMessageTagToggleMapper, SIGNAL(mapped(QString)),
189 bool needToAddMoreAction =
false;
190 const int numberOfTag(mTags.count());
191 foreach(
const MailCommon::Tag::Ptr &tag, mTags ) {
194 if ( tag->nepomukResourceUri.toString().isEmpty() )
197 createTagAction( tag,
true );
200 if ( tag->inToolbar || !tag->shortcut.isEmpty() ) {
201 createTagAction( tag,
false );
206 needToAddMoreAction =
true;
213 if(!mSeparatorNewTagAction) {
214 mSeparatorNewTagAction =
new QAction(
this );
215 mSeparatorNewTagAction->setSeparator(
true );
217 mMessageActions->
messageStatusMenu()->menu()->addAction( mSeparatorNewTagAction );
219 if (!mNewTagAction) {
220 mNewTagAction =
new KAction( i18n(
"Add new tag..." ),
this );
221 connect( mNewTagAction, SIGNAL(triggered(
bool)),
222 this, SLOT(newTagActionClicked()) );
226 if (needToAddMoreAction) {
227 if(!mSeparatorMoreAction) {
228 mSeparatorMoreAction =
new QAction(
this );
229 mSeparatorMoreAction->setSeparator(
true );
234 mMoreAction =
new KAction( i18n(
"More..." ),
this );
235 connect( mMoreAction, SIGNAL(triggered(
bool)),
241 if ( !mToolbarActions.isEmpty() && mGUIClient->factory() ) {
242 mGUIClient->plugActionList( QLatin1String(
"toolbar_messagetag_actions"), mToolbarActions );
248 foreach (
const Nepomuk2::Query::Result &result, results) {
249 Nepomuk2::Resource resource = result.resource();
250 mTags.append( MailCommon::Tag::fromNepomuk( resource ) );
254 void TagActionManager::finishedTagListing()
256 mTagQueryClient->close();
257 mTagQueryClient->deleteLater();
259 if ( mTags.isEmpty() )
261 qSort( mTags.begin(), mTags.end(), MailCommon::Tag::compare );
267 const Akonadi::Item &selectedItem )
272 if ( numberOfSelectedMessages == 1 )
274 Q_ASSERT( selectedItem.isValid() );
275 mAsyncNepomukRetriver->requestResource( selectedItem.url() );
277 else if ( numberOfSelectedMessages > 1 ) {
278 for ( ; it != end; ++it ) {
279 Nepomuk2::Tag tag( it.key() );
280 it.value()->setChecked(
false );
281 it.value()->setEnabled(
true );
282 it.value()->setText( i18n(
"Toggle Message Tag %1", tag.label() ) );
286 for ( ; it != end; ++it ) {
287 it.value()->setEnabled(
false );
292 void TagActionManager::slotLoadedResourceForUpdateActionStates(
const QUrl& uri,
const Nepomuk2::Resource& res)
296 for ( ; it != end; ++it ) {
297 const bool hasTag = res.tags().contains( Nepomuk2::Tag( it.key() ) );
298 it.value()->setChecked( hasTag );
299 it.value()->setEnabled(
true );
304 void TagActionManager::tagsChanged()
310 void TagActionManager::resourceCreated(
const Nepomuk2::Resource& res,
const QList<QUrl>&)
315 mTags.append( MailCommon::Tag::fromNepomuk( res ) );
316 qSort( mTags.begin(), mTags.end(), MailCommon::Tag::compare );
319 checkTags( checked );
322 void TagActionManager::resourceRemoved(
const QUrl& url,
const QList<QUrl>&)
324 foreach(
const MailCommon::Tag::Ptr &tag, mTags ) {
325 if(tag->nepomukResourceUri == url) {
326 mTags.removeAll(tag);
334 qSort( mTags.begin(), mTags.end(), MailCommon::Tag::compare );
337 checkTags( checked );
340 void TagActionManager::propertyChanged(
const Nepomuk2::Resource& res)
342 foreach(
const MailCommon::Tag::Ptr &tag, mTags ) {
343 if(tag->nepomukResourceUri == res.uri()) {
344 mTags.removeAll(tag);
348 mTags.append( MailCommon::Tag::fromNepomuk( res ) );
353 qSort( mTags.begin(), mTags.end(), MailCommon::Tag::compare );
356 checkTags( checked );
359 void TagActionManager::newTagActionClicked()
361 QPointer<MailCommon::AddTagDialog> dialog =
new MailCommon::AddTagDialog(
QList<KActionCollection*>() << mActionCollection, 0);
362 dialog->setTags(mTags);
363 if ( dialog->exec() ) {
364 mNewTagUri = dialog->nepomukUrl();
373 foreach(
const QUrl &url, tags ) {
374 const QString str = url.toString();
375 if ( mTagActions.contains( str ) ) {
376 mTagActions[str]->setChecked(
true );
386 for ( ; it != end; ++it ) {
387 if ( it.value()->isChecked() ) {
395 #include "tagactionmanager.moc"
Manages common actions that can be performed on one or more messages.
void tagMoreActionClicked()
Emitted when we want to select more action.
void tagActionTriggered(const QString &tagLabel)
Emitted when one of the tagging actions was triggered.
static int s_numberMaxTag
void clearActions()
Removes all actions from the GUI again.
void updateActionStates(int numberOfSelectedMessages, const Akonadi::Item &selectedItem)
Updates the state of the toggle actions of all tags.
void createActions()
Creates and plugs all tag actions.
TagActionManager(QObject *parent, KActionCollection *actionCollection, MessageActions *messageActions, KXMLGUIClient *guiClient)
Does not take ownership of the action collection, the GUI client or the message actions.
KActionMenu * messageStatusMenu() const