• Skip to content
  • Skip to link menu
KDE API Reference
  • KDE API Reference
  • kdepim API Reference
  • KDE Home
  • Contact Us
 

kmail

  • sources
  • kde-4.12
  • kdepim
  • kmail
messageactions.cpp
Go to the documentation of this file.
1 /*
2  Copyright (c) 2007 Volker Krause <vkrause@kde.org>
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; either version 2 of the License, or
7  (at your option) any later version.
8 
9  This program 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
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 */
18 
19 #include "messageactions.h"
20 
21 #include "settings/globalsettings.h"
22 #include "kmreaderwin.h"
23 #include "kmkernel.h"
24 #include "kernel/mailkernel.h"
25 #include "kmmainwidget.h"
26 #include "util.h"
27 #include "kmcommands.h"
28 #include "customtemplatesmenu.h"
29 
30 #include "messagecore/widgets/annotationdialog.h"
31 #include "messagecore/settings/globalsettings.h"
32 #include "messagecore/misc/mailinglist.h"
33 #include "messagecore/helpers/messagehelpers.h"
34 #include "messageviewer/viewer/csshelper.h"
35 #include "messageviewer/settings/globalsettings.h"
36 
37 #include <Nepomuk2/Resource>
38 
39 #include <akonadi/itemfetchjob.h>
40 #include <akonadi/kmime/messageparts.h>
41 #include <KAction>
42 #include <KActionMenu>
43 #include <KActionCollection>
44 #include <KToggleAction>
45 #include <KDebug>
46 #include <KLocale>
47 #include <KXMLGUIClient>
48 #include <KStandardDirs>
49 #include <KRun>
50 #include <KMenu>
51 #include <KUriFilterData>
52 #include <KToolInvocation>
53 #include <KUriFilter>
54 #include <KStringHandler>
55 #include <KPrintPreview>
56 
57 #include <QVariant>
58 #include <qwidget.h>
59 #include <akonadi/collection.h>
60 #include <Akonadi/Monitor>
61 #include <util/mailutil.h>
62 #include <nepomukutil/asyncnepomukresourceretriever.h>
63 #include <nepomuk2/resourcemanager.h>
64 #include <Soprano/Vocabulary/NAO>
65 
66 using namespace KMail;
67 
68 MessageActions::MessageActions( KActionCollection *ac, QWidget *parent )
69  : QObject( parent ),
70  mParent( parent ),
71  mMessageView( 0 ),
72  mRedirectAction( 0 ),
73  mPrintPreviewAction( 0 ),
74  mAsynNepomukRetriever( new MessageCore::AsyncNepomukResourceRetriever( QVector<QUrl>() << Soprano::Vocabulary::NAO::annotation().toString()
75  << Soprano::Vocabulary::NAO::description().toString(), this ) ),
76  mCustomTemplatesMenu( 0 )
77 {
78  mReplyActionMenu = new KActionMenu( KIcon(QLatin1String("mail-reply-sender")), i18nc("Message->","&Reply"), this );
79  ac->addAction( QLatin1String("message_reply_menu"), mReplyActionMenu );
80  connect( mReplyActionMenu, SIGNAL(triggered(bool)),
81  this, SLOT(slotReplyToMsg()) );
82 
83  mReplyAction = new KAction( KIcon(QLatin1String("mail-reply-sender")), i18n("&Reply..."), this );
84  ac->addAction( QLatin1String("reply"), mReplyAction );
85  mReplyAction->setShortcut(Qt::Key_R);
86  connect( mReplyAction, SIGNAL(triggered(bool)),
87  this, SLOT(slotReplyToMsg()) );
88  mReplyActionMenu->addAction( mReplyAction );
89 
90  mReplyAuthorAction = new KAction( KIcon(QLatin1String("mail-reply-sender")), i18n("Reply to A&uthor..."), this );
91  ac->addAction( QLatin1String("reply_author"), mReplyAuthorAction );
92  mReplyAuthorAction->setShortcut(Qt::SHIFT+Qt::Key_A);
93  connect( mReplyAuthorAction, SIGNAL(triggered(bool)),
94  this, SLOT(slotReplyAuthorToMsg()) );
95  mReplyActionMenu->addAction( mReplyAuthorAction );
96 
97  mReplyAllAction = new KAction( KIcon(QLatin1String("mail-reply-all")), i18n("Reply to &All..."), this );
98  ac->addAction( QLatin1String("reply_all"), mReplyAllAction );
99  mReplyAllAction->setShortcut( Qt::Key_A );
100  connect( mReplyAllAction, SIGNAL(triggered(bool)),
101  this, SLOT(slotReplyAllToMsg()) );
102  mReplyActionMenu->addAction( mReplyAllAction );
103 
104  mReplyListAction = new KAction( KIcon(QLatin1String("mail-reply-list")), i18n("Reply to Mailing-&List..."), this );
105  ac->addAction( QLatin1String("reply_list"), mReplyListAction );
106  mReplyListAction->setShortcut( Qt::Key_L );
107  connect( mReplyListAction, SIGNAL(triggered(bool)),
108  this, SLOT(slotReplyListToMsg()) );
109  mReplyActionMenu->addAction( mReplyListAction );
110 
111  mNoQuoteReplyAction = new KAction( i18n("Reply Without &Quote..."), this );
112  ac->addAction(QLatin1String("noquotereply"), mNoQuoteReplyAction );
113  mNoQuoteReplyAction->setShortcut( Qt::SHIFT+Qt::Key_R );
114  connect( mNoQuoteReplyAction, SIGNAL(triggered(bool)),
115  this, SLOT(slotNoQuoteReplyToMsg()) );
116 
117 
118  mListFilterAction = new KAction(i18n("Filter on Mailing-&List..."), this);
119  ac->addAction(QLatin1String("mlist_filter"), mListFilterAction );
120  connect(mListFilterAction, SIGNAL(triggered(bool)), SLOT(slotMailingListFilter()));
121 
122  mCreateTodoAction = new KAction( KIcon( QLatin1String("task-new") ), i18n( "Create To-do/Reminder..." ), this );
123  mCreateTodoAction->setIconText( i18n( "Create To-do" ) );
124  mCreateTodoAction->setHelpText( i18n( "Allows you to create a calendar to-do or reminder from this message" ) );
125  mCreateTodoAction->setWhatsThis( i18n( "This option starts the KOrganizer to-do editor with initial values taken from the currently selected message. Then you can edit the to-do to your liking before saving it to your calendar." ) );
126  ac->addAction( QLatin1String("create_todo"), mCreateTodoAction );
127  connect( mCreateTodoAction, SIGNAL(triggered(bool)),
128  this, SLOT(slotCreateTodo()) );
129  mKorganizerIsOnSystem = !KStandardDirs::findExe(QLatin1String("korganizer")).isEmpty();
130  mCreateTodoAction->setEnabled( mKorganizerIsOnSystem );
131 
132  mStatusMenu = new KActionMenu ( i18n( "Mar&k Message" ), this );
133  ac->addAction( QLatin1String("set_status"), mStatusMenu );
134 
135 
136  KMMainWidget* mainwin = kmkernel->getKMMainWidget();
137  if ( mainwin ) {
138  KAction * action = mainwin->akonadiStandardAction( Akonadi::StandardMailActionManager::MarkMailAsRead );
139  mStatusMenu->addAction( action );
140 
141  action = mainwin->akonadiStandardAction( Akonadi::StandardMailActionManager::MarkMailAsUnread );
142  mStatusMenu->addAction( action );
143 
144  mStatusMenu->addSeparator();
145  action = mainwin->akonadiStandardAction( Akonadi::StandardMailActionManager::MarkMailAsImportant );
146  mStatusMenu->addAction( action );
147 
148  action = mainwin->akonadiStandardAction( Akonadi::StandardMailActionManager::MarkMailAsActionItem );
149  mStatusMenu->addAction( action );
150 
151  }
152 
153  mEditAction = new KAction( KIcon(QLatin1String("accessories-text-editor")), i18n("&Edit Message"), this );
154  ac->addAction( QLatin1String("edit"), mEditAction );
155  connect( mEditAction, SIGNAL(triggered(bool)),
156  this, SLOT(editCurrentMessage()) );
157  mEditAction->setShortcut( Qt::Key_T );
158 
159  mAnnotateAction = new KAction( KIcon( QLatin1String("view-pim-notes") ), i18n( "Add Note..."), this );
160  ac->addAction( QLatin1String("annotate"), mAnnotateAction );
161  connect( mAnnotateAction, SIGNAL(triggered(bool)),
162  this, SLOT(annotateMessage()) );
163 
164  mPrintAction = KStandardAction::print( this, SLOT(slotPrintMsg()), ac );
165  if(KPrintPreview::isAvailable())
166  mPrintPreviewAction = KStandardAction::printPreview( this, SLOT(slotPrintPreviewMsg()), ac );
167 
168  mForwardActionMenu = new KActionMenu(KIcon(QLatin1String("mail-forward")), i18nc("Message->","&Forward"), this);
169  ac->addAction(QLatin1String("message_forward"), mForwardActionMenu );
170 
171  mForwardAttachedAction = new KAction( KIcon(QLatin1String("mail-forward")),
172  i18nc( "@action:inmenu Message->Forward->",
173  "As &Attachment..." ),
174  this );
175  connect( mForwardAttachedAction, SIGNAL(triggered(bool)),
176  parent, SLOT(slotForwardAttachedMsg()) );
177  ac->addAction( QLatin1String("message_forward_as_attachment"), mForwardAttachedAction );
178 
179  mForwardInlineAction = new KAction( KIcon( QLatin1String("mail-forward") ),
180  i18nc( "@action:inmenu Message->Forward->",
181  "&Inline..." ),
182  this );
183  connect( mForwardInlineAction, SIGNAL(triggered(bool)),
184  parent, SLOT(slotForwardInlineMsg()) );
185  ac->addAction( QLatin1String("message_forward_inline"), mForwardInlineAction );
186 
187  setupForwardActions();
188 
189  mRedirectAction = new KAction(i18nc("Message->Forward->", "&Redirect..."), this );
190  ac->addAction( QLatin1String("message_forward_redirect"), mRedirectAction );
191  connect( mRedirectAction, SIGNAL(triggered(bool)),
192  parent, SLOT(slotRedirectMsg()) );
193  mRedirectAction->setShortcut( QKeySequence( Qt::Key_E ) );
194  mForwardActionMenu->addAction( mRedirectAction );
195 
196  //FIXME add KIcon("mail-list") as first arguement. Icon can be derived from
197  // mail-reply-list icon by removing top layers off svg
198  mMailingListActionMenu = new KActionMenu( i18nc( "Message->", "Mailing-&List" ), this );
199  connect( mMailingListActionMenu->menu(), SIGNAL(triggered(QAction*)),
200  this, SLOT(slotRunUrl(QAction*)) );
201  ac->addAction( QLatin1String("mailing_list"), mMailingListActionMenu );
202  mMailingListActionMenu->setEnabled(false);
203 
204  mMonitor = new Akonadi::Monitor( this );
205  //FIXME: Attachment fetching is not needed here, but on-demand loading is not supported ATM
206  mMonitor->itemFetchScope().fetchPayloadPart( Akonadi::MessagePart::Header );
207  connect( mMonitor, SIGNAL(itemChanged(Akonadi::Item,QSet<QByteArray>)), SLOT(slotItemModified(Akonadi::Item,QSet<QByteArray>)));
208  connect( mMonitor, SIGNAL(itemRemoved(Akonadi::Item)), SLOT(slotItemRemoved(Akonadi::Item)));
209 
210  connect( mAsynNepomukRetriever, SIGNAL(resourceReceived(QUrl,Nepomuk2::Resource)), SLOT(updateAnnotateAction(QUrl,Nepomuk2::Resource)) );
211 
212  mCustomTemplatesMenu = new TemplateParser::CustomTemplatesMenu( parent, ac );
213 
214  connect( mCustomTemplatesMenu, SIGNAL(replyTemplateSelected(QString)),
215  parent, SLOT(slotCustomReplyToMsg(QString)) );
216  connect( mCustomTemplatesMenu, SIGNAL(replyAllTemplateSelected(QString)),
217  parent, SLOT(slotCustomReplyAllToMsg(QString)) );
218  connect( mCustomTemplatesMenu, SIGNAL(forwardTemplateSelected(QString)),
219  parent, SLOT(slotCustomForwardMsg(QString)) );
220  connect( KMKernel::self(), SIGNAL(customTemplatesChanged()), mCustomTemplatesMenu, SLOT(update()) );
221 
222  forwardMenu()->addSeparator();
223  forwardMenu()->addAction( mCustomTemplatesMenu->forwardActionMenu() );
224  replyMenu()->addSeparator();
225  replyMenu()->addAction( mCustomTemplatesMenu->replyActionMenu() );
226  replyMenu()->addAction( mCustomTemplatesMenu->replyAllActionMenu() );
227 
228  updateActions();
229 }
230 
231 MessageActions::~MessageActions()
232 {
233  delete mCustomTemplatesMenu;
234 }
235 
236 TemplateParser::CustomTemplatesMenu* MessageActions::customTemplatesMenu() const
237 {
238  return mCustomTemplatesMenu;
239 }
240 
241 void MessageActions::setCurrentMessage( const Akonadi::Item &msg, const Akonadi::Item::List &items )
242 {
243  mMonitor->setItemMonitored( mCurrentItem, false );
244  mCurrentItem = msg;
245 
246  if (!items.isEmpty()) {
247  Q_FOREACH( const Akonadi::Item& item, mVisibleItems ) {
248  mMonitor->setItemMonitored( item, false );
249  }
250  if (!msg.isValid()) {
251  mVisibleItems.clear();
252  } else {
253  mVisibleItems = items;
254  Q_FOREACH( const Akonadi::Item& item, items ) {
255  mMonitor->setItemMonitored( item, true );
256  }
257  }
258  }
259 
260  if ( !msg.isValid() ) {
261  mVisibleItems.clear();
262  clearMailingListActions();
263  }
264 
265  mMonitor->setItemMonitored( mCurrentItem, true );
266  updateActions();
267 }
268 
269 void MessageActions::slotItemRemoved(const Akonadi::Item& item)
270 {
271  if ( item == mCurrentItem ) {
272  mCurrentItem = Akonadi::Item();
273  updateActions();
274  }
275 }
276 
277 void MessageActions::slotItemModified( const Akonadi::Item & item, const QSet< QByteArray > & partIdentifiers )
278 {
279  Q_UNUSED( partIdentifiers );
280  if ( item == mCurrentItem ) {
281  mCurrentItem = item;
282  const int numberOfVisibleItems = mVisibleItems.count();
283  for ( int i = 0; i < numberOfVisibleItems; ++i ) {
284  Akonadi::Item it = mVisibleItems.at(i);
285  if ( item == it ) {
286  mVisibleItems[i] = item;
287  }
288  }
289  updateActions();
290  }
291 }
292 
293 void MessageActions::updateActions()
294 {
295  const bool hasPayload = mCurrentItem.hasPayload<KMime::Message::Ptr>();
296  bool itemValid = mCurrentItem.isValid();
297  Akonadi::Collection parent;
298  if ( itemValid ) //=> valid
299  parent = mCurrentItem.parentCollection();
300  if ( parent.isValid() ) {
301  if ( CommonKernel->folderIsTemplates(parent) )
302  itemValid = false;
303  }
304 
305  const bool multiVisible = mVisibleItems.count() > 0 || mCurrentItem.isValid();
306  const bool uniqItem = ( itemValid||hasPayload ) && ( mVisibleItems.count()<=1 );
307  mCreateTodoAction->setEnabled( itemValid && ( mVisibleItems.count()<=1 ) && mKorganizerIsOnSystem);
308  mReplyActionMenu->setEnabled( hasPayload );
309  mReplyAction->setEnabled( hasPayload );
310  mNoQuoteReplyAction->setEnabled( hasPayload );
311  mReplyAuthorAction->setEnabled( hasPayload );
312  mReplyAllAction->setEnabled( hasPayload );
313  mReplyListAction->setEnabled( hasPayload );
314  mNoQuoteReplyAction->setEnabled( hasPayload );
315 
316  if ( Nepomuk2::ResourceManager::instance()->initialized() ) {
317  mAnnotateAction->setEnabled( uniqItem );
318  mAsynNepomukRetriever->requestResource( mCurrentItem.url() );
319  } else {
320  mAnnotateAction->setEnabled( false );
321  }
322 
323  mStatusMenu->setEnabled( multiVisible );
324 
325  if ( mCurrentItem.hasPayload<KMime::Message::Ptr>() ) {
326  if ( mCurrentItem.loadedPayloadParts().contains("RFC822") ) {
327  updateMailingListActions( mCurrentItem );
328  } else {
329  Akonadi::ItemFetchJob *job = new Akonadi::ItemFetchJob( mCurrentItem );
330  job->fetchScope().fetchAllAttributes();
331  job->fetchScope().fetchFullPayload( true );
332  job->fetchScope().fetchPayloadPart( Akonadi::MessagePart::Header );
333  connect( job, SIGNAL(result(KJob*)), SLOT(slotUpdateActionsFetchDone(KJob*)) );
334  }
335  }
336  mEditAction->setEnabled( uniqItem );
337 }
338 
339 void MessageActions::slotUpdateActionsFetchDone(KJob* job)
340 {
341  if ( job->error() )
342  return;
343 
344  Akonadi::ItemFetchJob *fetchJob = static_cast<Akonadi::ItemFetchJob*>( job );
345  if ( fetchJob->items().isEmpty() )
346  return;
347  Akonadi::Item messageItem = fetchJob->items().first();
348  if ( messageItem == mCurrentItem ) {
349  mCurrentItem = messageItem;
350  updateMailingListActions( messageItem );
351  }
352 }
353 
354 void MessageActions::clearMailingListActions()
355 {
356  mMailingListActionMenu->setEnabled( false );
357  mListFilterAction->setEnabled( false );
358  mListFilterAction->setText( i18n("Filter on Mailing-List...") );
359 }
360 
361 void MessageActions::updateMailingListActions( const Akonadi::Item& messageItem )
362 {
363  KMime::Message::Ptr message = messageItem.payload<KMime::Message::Ptr>();
364  const MessageCore::MailingList mailList = MessageCore::MailingList::detect( message );
365 
366  if ( mailList.features() == MessageCore::MailingList::None ) {
367  clearMailingListActions();
368  } else {
369  // A mailing list menu with only a title is pretty boring
370  // so make sure theres at least some content
371  QString listId;
372  if ( mailList.features() & MessageCore::MailingList::Id ) {
373  // From a list-id in the form, "Birds of France <bof.yahoo.com>",
374  // take "Birds of France" if it exists otherwise "bof.yahoo.com".
375  listId = mailList.id();
376  const int start = listId.indexOf( QLatin1Char( '<' ) );
377  if ( start > 0 ) {
378  listId.truncate( start - 1 );
379  } else if ( start == 0 ) {
380  const int end = listId.lastIndexOf( QLatin1Char( '>' ) );
381  if ( end < 1 ) { // shouldn't happen but account for it anyway
382  listId.remove( 0, 1 );
383  } else {
384  listId = listId.mid( 1, end-1 );
385  }
386  }
387  }
388  mMailingListActionMenu->menu()->clear();
389  qDeleteAll(mMailListActionList);
390  mMailListActionList.clear();
391  if ( !listId.isEmpty() )
392  mMailingListActionMenu->menu()->addTitle( listId );
393 
394  if ( mailList.features() & MessageCore::MailingList::ArchivedAt )
395  // IDEA: this may be something you want to copy - "Copy in submenu"?
396  addMailingListActions( i18n( "Open Message in List Archive" ), mailList.archivedAtUrls() );
397  if ( mailList.features() & MessageCore::MailingList::Post )
398  addMailingListActions( i18n( "Post New Message" ), mailList.postUrls() );
399  if ( mailList.features() & MessageCore::MailingList::Archive )
400  addMailingListActions( i18n( "Go to Archive" ), mailList.archiveUrls() );
401  if ( mailList.features() & MessageCore::MailingList::Help )
402  addMailingListActions( i18n( "Request Help" ), mailList.helpUrls() );
403  if ( mailList.features() & MessageCore::MailingList::Owner )
404  addMailingListActions( i18nc( "Contact the owner of the mailing list", "Contact Owner" ), mailList.ownerUrls() );
405  if ( mailList.features() & MessageCore::MailingList::Subscribe )
406  addMailingListActions( i18n( "Subscribe to List" ), mailList.subscribeUrls() );
407  if ( mailList.features() & MessageCore::MailingList::Unsubscribe )
408  addMailingListActions( i18n( "Unsubscribe from List" ), mailList.unsubscribeUrls() );
409  mMailingListActionMenu->setEnabled( true );
410 
411  QByteArray name;
412  QString value;
413  const QString lname = MailingList::name( message, name, value );
414  if ( !lname.isEmpty() ) {
415  mListFilterAction->setEnabled( true );
416  mListFilterAction->setText( i18n( "Filter on Mailing-List %1...", lname ) );
417  }
418  }
419 }
420 
421 
422 void MessageActions::replyCommand(MessageComposer::ReplyStrategy strategy)
423 {
424  if ( !mCurrentItem.hasPayload<KMime::Message::Ptr>() ) return;
425 
426  const QString text = mMessageView ? mMessageView->copyText() : QString();
427  KMCommand *command = new KMReplyCommand( mParent, mCurrentItem, strategy, text );
428  connect( command, SIGNAL(completed(KMCommand*)),
429  this, SIGNAL(replyActionFinished()) );
430  command->start();
431 }
432 
433 void MessageActions::slotCreateTodo()
434 {
435  if ( !mCurrentItem.isValid() )
436  return;
437 
438  MailCommon::Util::createTodoFromMail( mCurrentItem );
439 }
440 
441 void MessageActions::setMessageView(KMReaderWin * msgView)
442 {
443  mMessageView = msgView;
444 }
445 
446 void MessageActions::setupForwardActions()
447 {
448  disconnect( mForwardActionMenu, SIGNAL(triggered(bool)), 0, 0 );
449  mForwardActionMenu->removeAction( mForwardInlineAction );
450  mForwardActionMenu->removeAction( mForwardAttachedAction );
451 
452  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
453  mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
454  mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
455  mForwardInlineAction->setShortcut(QKeySequence(Qt::Key_F));
456  mForwardAttachedAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
457  QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
458  mParent, SLOT(slotForwardInlineMsg()) );
459  } else {
460  mForwardActionMenu->insertAction( mRedirectAction, mForwardAttachedAction );
461  mForwardActionMenu->insertAction( mRedirectAction, mForwardInlineAction );
462  mForwardInlineAction->setShortcut(QKeySequence(Qt::Key_F));
463  mForwardAttachedAction->setShortcut(QKeySequence(Qt::SHIFT+Qt::Key_F));
464  QObject::connect( mForwardActionMenu, SIGNAL(triggered(bool)),
465  mParent, SLOT(slotForwardAttachedMsg()) );
466  }
467 }
468 
469 void MessageActions::setupForwardingActionsList( KXMLGUIClient *guiClient )
470 {
471  QList<QAction*> forwardActionList;
472  guiClient->unplugActionList( QLatin1String("forward_action_list") );
473  if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
474  forwardActionList.append( mForwardInlineAction );
475  forwardActionList.append( mForwardAttachedAction );
476  } else {
477  forwardActionList.append( mForwardAttachedAction );
478  forwardActionList.append( mForwardInlineAction );
479  }
480  forwardActionList.append( mRedirectAction );
481  guiClient->plugActionList( QLatin1String("forward_action_list"), forwardActionList );
482 }
483 
484 
485 void MessageActions::slotReplyToMsg()
486 {
487  replyCommand( MessageComposer::ReplySmart );
488 }
489 
490 void MessageActions::slotReplyAuthorToMsg()
491 {
492  replyCommand( MessageComposer::ReplyAuthor );
493 }
494 
495 void MessageActions::slotReplyListToMsg()
496 {
497  replyCommand( MessageComposer::ReplyList );
498 }
499 
500 void MessageActions::slotReplyAllToMsg()
501 {
502  replyCommand( MessageComposer::ReplyAll );
503 }
504 
505 void MessageActions::slotNoQuoteReplyToMsg()
506 {
507  if ( !mCurrentItem.hasPayload<KMime::Message::Ptr>() )
508  return;
509  KMCommand *command = new KMReplyCommand( mParent, mCurrentItem, MessageComposer::ReplySmart, QString(), true );
510  command->start();
511 }
512 
513 void MessageActions::slotRunUrl( QAction *urlAction )
514 {
515  const QVariant q = urlAction->data();
516  if ( q.type() == QVariant::String ) {
517  new KRun( KUrl( q.toString() ) , mParent );
518  }
519 }
520 
521 void MessageActions::slotMailingListFilter()
522 {
523  if ( !mCurrentItem.hasPayload<KMime::Message::Ptr>() )
524  return;
525 
526  KMCommand *command = new KMMailingListFilterCommand( mParent, mCurrentItem );
527  command->start();
528 }
529 
530 void MessageActions::printMessage(bool preview)
531 {
532  bool result = false;
533  if ( mMessageView ) {
534  if (MessageViewer::GlobalSettings::self()->printSelectedText()) {
535  result = mMessageView->printSelectedText(preview);
536  }
537  }
538  if (!result) {
539  const bool useFixedFont = MessageViewer::GlobalSettings::self()->useFixedFont();
540  const QString overrideEncoding = MessageCore::GlobalSettings::self()->overrideCharacterEncoding();
541 
542  const Akonadi::Item message = mCurrentItem;
543  KMPrintCommand *command =
544  new KMPrintCommand( mParent, message,
545  mMessageView->viewer()->headerStyle(), mMessageView->viewer()->headerStrategy(),
546  mMessageView->viewer()->htmlOverride(), mMessageView->viewer()->htmlLoadExternal(),
547  useFixedFont, overrideEncoding );
548  command->setPrintPreview(preview);
549  command->start();
550  }
551 }
552 
553 void MessageActions::slotPrintPreviewMsg()
554 {
555  printMessage(true);
556 }
557 
558 void MessageActions::slotPrintMsg()
559 {
560  printMessage(false);
561 }
562 
571 void MessageActions::addMailingListActions( const QString &item, const KUrl::List &list )
572 {
573  foreach ( const KUrl& url, list ) {
574  addMailingListAction( item, url );
575  }
576 }
577 
582 void MessageActions::addMailingListAction( const QString &item, const KUrl &url )
583 {
584  QString protocol = url.protocol().toLower();
585  QString prettyUrl = url.prettyUrl();
586  if ( protocol == QLatin1String("mailto") ) {
587  protocol = i18n( "email" );
588  prettyUrl.remove( 0, 7 ); // length( "mailto:" )
589  } else if ( protocol.startsWith( QLatin1String( "http" ) ) ) {
590  protocol = i18n( "web" );
591  }
592  // item is a mailing list url description passed from the updateActions method above.
593  KAction *act = new KAction( i18nc( "%1 is a 'Contact Owner' or similar action. %2 is a protocol normally web or email though could be irc/ftp or other url variant", "%1 (%2)", item, protocol ) , this );
594  mMailListActionList.append(act);
595  const QVariant v( url.url() );
596  act->setData( v );
597  act->setHelpText( prettyUrl );
598  mMailingListActionMenu->addAction( act );
599 }
600 
601 void MessageActions::editCurrentMessage()
602 {
603  KMCommand *command = 0;
604  if ( mCurrentItem.isValid() ) {
605  Akonadi::Collection col = mCurrentItem.parentCollection();
606  qDebug()<<" mCurrentItem.parentCollection()"<<mCurrentItem.parentCollection();
607  // edit, unlike send again, removes the message from the folder
608  // we only want that for templates and drafts folders
609  if ( col.isValid()
610  && ( CommonKernel->folderIsDraftOrOutbox( col ) ||
611  CommonKernel->folderIsTemplates( col ) )
612  )
613  command = new KMEditItemCommand( mParent, mCurrentItem, true );
614  else
615  command = new KMEditItemCommand( mParent, mCurrentItem, false );
616  command->start();
617  } else if ( mCurrentItem.hasPayload<KMime::Message::Ptr>() ) {
618  command = new KMEditMessageCommand( mParent, mCurrentItem.payload<KMime::Message::Ptr>() );
619  command->start();
620  }
621 }
622 
623 void MessageActions::annotateMessage()
624 {
625  if ( !mCurrentItem.isValid() )
626  return;
627 
628  const QUrl url = mCurrentItem.url();
629  MessageCore::AnnotationEditDialog *dialog = new MessageCore::AnnotationEditDialog( url );
630  dialog->setAttribute( Qt::WA_DeleteOnClose );
631  if ( dialog->exec() )
632  mAsynNepomukRetriever->requestResource( url );
633 }
634 
635 void MessageActions::updateAnnotateAction( const QUrl &url, const Nepomuk2::Resource &resource )
636 {
637  if( mCurrentItem.isValid() && mCurrentItem.url() == url ) {
638  if ( resource.description().isEmpty() )
639  mAnnotateAction->setText( i18n( "Add Note..." ) );
640  else
641  mAnnotateAction->setText( i18n( "Edit Note...") );
642  }
643 }
644 
645 void MessageActions::addWebShortcutsMenu( KMenu *menu, const QString & text )
646 {
647  if ( text.isEmpty() )
648  return;
649 
650  QString searchText = text;
651  searchText = searchText.replace( QLatin1Char('\n'), QLatin1Char(' ') ).replace( QLatin1Char('\r'), QLatin1Char(' ') ).simplified();
652 
653  if ( searchText.isEmpty() )
654  return;
655 
656  KUriFilterData filterData( searchText );
657 
658  filterData.setSearchFilteringOptions( KUriFilterData::RetrievePreferredSearchProvidersOnly );
659 
660  if ( KUriFilter::self()->filterSearchUri( filterData, KUriFilter::NormalTextFilter ) ) {
661  const QStringList searchProviders = filterData.preferredSearchProviders();
662 
663  if ( !searchProviders.isEmpty() ) {
664  KMenu *webShortcutsMenu = new KMenu( menu );
665  webShortcutsMenu->setIcon( KIcon( QLatin1String("preferences-web-browser-shortcuts") ) );
666 
667  const QString squeezedText = KStringHandler::rsqueeze( searchText, 21 );
668  webShortcutsMenu->setTitle( i18n( "Search for '%1' with", squeezedText ) );
669 
670  KAction *action = 0;
671 
672  foreach( const QString &searchProvider, searchProviders ) {
673  action = new KAction( searchProvider, webShortcutsMenu );
674  action->setIcon( KIcon( filterData.iconNameForPreferredSearchProvider( searchProvider ) ) );
675  action->setData( filterData.queryForPreferredSearchProvider( searchProvider ) );
676  connect( action, SIGNAL(triggered()), this, SLOT(slotHandleWebShortcutAction()) );
677  webShortcutsMenu->addAction( action );
678  }
679 
680  webShortcutsMenu->addSeparator();
681 
682  action = new KAction( i18n( "Configure Web Shortcuts..." ), webShortcutsMenu );
683  action->setIcon( KIcon( QLatin1String("configure") ) );
684  connect( action, SIGNAL(triggered()), this, SLOT(slotConfigureWebShortcuts()) );
685  webShortcutsMenu->addAction( action );
686 
687  menu->addMenu(webShortcutsMenu);
688  }
689  }
690 }
691 
692 void MessageActions::slotHandleWebShortcutAction()
693 {
694  KAction *action = qobject_cast<KAction*>( sender() );
695 
696  if (action) {
697  KUriFilterData filterData( action->data().toString() );
698  if ( KUriFilter::self()->filterSearchUri( filterData, KUriFilter::WebShortcutFilter ) ) {
699  KToolInvocation::invokeBrowser( filterData.uri().url() );
700  }
701  }
702 }
703 
704 void MessageActions::slotConfigureWebShortcuts()
705 {
706  KToolInvocation::kdeinitExec( QLatin1String("kcmshell4"), QStringList() << QLatin1String("ebrowsing") );
707 }
708 
709 #include "messageactions.moc"
KMReplyCommand
Definition: kmcommands.h:312
globalsettings.h
KMail::MessageActions::addWebShortcutsMenu
void addWebShortcutsMenu(KMenu *menu, const QString &text)
Definition: messageactions.cpp:645
KMail::MessageActions::editCurrentMessage
void editCurrentMessage()
Definition: messageactions.cpp:601
KMail::MessageActions::replyActionFinished
void replyActionFinished()
kmmainwidget.h
KXMLGUIClient
KMMainWidget::akonadiStandardAction
KAction * akonadiStandardAction(Akonadi::StandardActionManager::Type type)
Definition: kmmainwidget.cpp:4554
KMail::MessageActions::~MessageActions
~MessageActions()
Definition: messageactions.cpp:231
KMReaderWin
This class implements a "reader window", that is a window used for reading or viewing messages...
Definition: kmreaderwin.h:50
KMReaderWin::viewer
MessageViewer::Viewer * viewer()
Definition: kmreaderwin.h:131
text
virtual QByteArray text(quint32 serialNumber) const =0
QWidget
KMMailingListFilterCommand
Definition: kmcommands.h:480
KMail::MessageActions::MessageActions
MessageActions(KActionCollection *ac, QWidget *parent)
Definition: messageactions.cpp:68
KMail::MessageActions::customTemplatesMenu
TemplateParser::CustomTemplatesMenu * customTemplatesMenu() const
Definition: messageactions.cpp:236
QObject
KMKernel::self
static KMKernel * self()
normal control stuff
Definition: kmkernel.cpp:1451
kmreaderwin.h
KMail::MessageActions::setupForwardingActionsList
void setupForwardingActionsList(KXMLGUIClient *guiClient)
Sets up action list for forward menu.
Definition: messageactions.cpp:469
messageactions.h
KMCommand
Small helper structure which encapsulates the KMMessage created when creating a reply, and.
Definition: kmcommands.h:44
KMCommand::start
void start()
Definition: kmcommands.cpp:234
KMMainWidget
Definition: kmmainwidget.h:83
KMail::MessageActions::forwardMenu
KActionMenu * forwardMenu() const
Definition: messageactions.h:89
util.h
kmkernel
#define kmkernel
Definition: kmkernel.h:22
KMail::MessageActions::setCurrentMessage
void setCurrentMessage(const Akonadi::Item &item, const Akonadi::Item::List &items=Akonadi::Item::List())
Definition: messageactions.cpp:241
KMail::MessageActions::annotateMessage
void annotateMessage()
Definition: messageactions.cpp:623
GlobalSettings::self
static GlobalSettings * self()
Definition: globalsettings.cpp:30
kmkernel.h
KMail::MessageActions::replyMenu
KActionMenu * replyMenu() const
Definition: messageactions.h:81
KMPrintCommand::setPrintPreview
void setPrintPreview(bool preview)
Definition: kmcommands.cpp:1101
KMail::MessageActions::setMessageView
void setMessageView(KMReaderWin *msgView)
Definition: messageactions.cpp:441
KMReaderWin::copyText
QString copyText() const
Return selected text.
Definition: kmreaderwin.cpp:443
KMReaderWin::printSelectedText
bool printSelectedText(bool preview)
Definition: kmreaderwin.cpp:726
KMPrintCommand
Definition: kmcommands.h:377
KMEditItemCommand
Definition: kmcommands.h:219
kmcommands.h
KJob
QList< QAction * >
KMail::MessageActions::setupForwardActions
void setupForwardActions()
This function adds or updates the actions of the forward action menu, taking the preference whether t...
Definition: messageactions.cpp:446
KMEditMessageCommand
Definition: kmcommands.h:233
This file is part of the KDE documentation.
Documentation copyright © 1996-2014 The KDE developers.
Generated on Tue Oct 14 2014 22:58:52 by doxygen 1.8.7 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.

kmail

Skip menu "kmail"
  • Main Page
  • Namespace List
  • Namespace Members
  • Alphabetical List
  • Class List
  • Class Hierarchy
  • Class Members
  • File List
  • File Members

kdepim API Reference

Skip menu "kdepim API Reference"
  • akonadi_next
  • akregator
  • blogilo
  • calendarsupport
  • console
  •   kabcclient
  •   konsolekalendar
  • kaddressbook
  • kalarm
  •   lib
  • kdgantt2
  • kjots
  • kleopatra
  • kmail
  • knode
  • knotes
  • kontact
  • korgac
  • korganizer
  • ktimetracker
  • libkdepim
  • libkleo
  • libkpgp
  • mailcommon
  • messagelist
  • messageviewer

Search



Report problems with this website to our bug tracking system.
Contact the specific authors with questions and comments about the page contents.

KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal