30 #include <kactionmenu.h>
31 #include <kedittoolbar.h>
33 #include <kstandardshortcut.h>
34 #include <kwindowsystem.h>
36 #include <kfontaction.h>
37 #include <kstandardaction.h>
38 #include <ktoggleaction.h>
41 #include <KFontAction>
42 #include <KFontSizeAction>
43 #include <kstatusbar.h>
44 #include <KMessageBox>
45 #include <KAcceleratorManager>
50 #include "messageviewer/viewer/csshelper.h"
51 #include "customtemplatesmenu.h"
54 #include "kernel/mailkernel.h"
55 #include "foldercollection.h"
57 #include <KActionCollection>
58 #include <akonadi/contact/contactsearchjob.h>
59 #include <kpimutils/email.h>
60 #include <kmime/kmime_message.h>
62 #include <akonadi/item.h>
63 #include <akonadi/itemcopyjob.h>
64 #include <akonadi/itemcreatejob.h>
65 #include <akonadi/itemmovejob.h>
66 #include <akonadi/kmime/messageflags.h>
68 #include "messagecore/helpers/messagehelpers.h"
69 #include <util/mailutil.h>
71 using namespace MailCommon;
75 : KMail::SecondaryWindow( name ? name :
"readerwindow#" )
77 mReaderWin =
new KMReaderWin(
this,
this, actionCollection());
82 initKMReaderMainWin();
88 : KMail::SecondaryWindow( name ? name :
"readerwindow#" )
90 mReaderWin =
new KMReaderWin(
this,
this, actionCollection());
91 initKMReaderMainWin();
97 : KMail::SecondaryWindow( name ? name :
"readerwindow#" )
99 mReaderWin =
new KMReaderWin(
this,
this, actionCollection() );
103 initKMReaderMainWin();
107 void KMReaderMainWin::initKMReaderMainWin()
109 setCentralWidget( mReaderWin );
111 setupGUI( Keys | StatusBar | Create,
QLatin1String(
"kmreadermainwin.rc") );
113 applyMainWindowSettings(
KMKernel::self()->config()->group(
"Separate Reader Window" ) );
114 if( ! mReaderWin->
message().isValid() ) {
118 connect(
kmkernel, SIGNAL(configChanged()),
119 this, SLOT(slotConfigChanged()) );
120 connect( mReaderWin, SIGNAL(showStatusBarMessage(
QString)),
127 saveMainWindowSettings(
KMKernel::self()->config()->group(
"Separate Reader Window" ) );
139 mParentCollection = parentCollection;
141 mReaderWin->
setMessage( msg, MessageViewer::Viewer::Force );
142 KMime::Message::Ptr message = MessageCore::Util::message( msg );
145 caption = message->subject()->asUnicodeString();
147 if(mParentCollection.isValid()) {
149 caption += MailCommon::Util::fullCollectionPath( mParentCollection );
157 const bool canChange = mParentCollection.isValid() ? (bool)( mParentCollection.rights() & Akonadi::Collection::CanDeleteItem ) :
false;
158 mTrashAction->setEnabled( canChange );
171 item.setPayload<KMime::Message::Ptr>( message );
172 Akonadi::MessageFlags::copyMessageFlags(*message, item);
173 item.setMimeType( KMime::Message::mimeType() );
180 setCaption( message->subject()->asUnicodeString() );
182 mTrashAction->setEnabled(
false );
189 void KMReaderMainWin::slotReplyOrForwardFinished()
196 Akonadi::Collection KMReaderMainWin::parentCollection()
const
198 if ( mParentCollection.isValid() )
199 return mParentCollection;
201 return mMsg.parentCollection();
205 void KMReaderMainWin::slotTrashMsg()
207 if ( !mMsg.isValid() )
215 void KMReaderMainWin::slotForwardInlineMsg()
217 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
219 const Akonadi::Collection parentCol = mReaderWin->
message().parentCollection();
220 if ( parentCol.isValid() ) {
230 connect( command, SIGNAL(completed(
KMCommand*)),
231 this, SLOT(slotReplyOrForwardFinished()) );
236 void KMReaderMainWin::slotForwardAttachedMsg()
238 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
240 const Akonadi::Collection parentCol = mReaderWin->
message().parentCollection();
241 if ( parentCol.isValid() ) {
252 connect( command, SIGNAL(completed(
KMCommand*)),
253 this, SLOT(slotReplyOrForwardFinished()) );
258 void KMReaderMainWin::slotRedirectMsg()
260 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
262 connect( command, SIGNAL(completed(
KMCommand*)),
263 this, SLOT(slotReplyOrForwardFinished()) );
268 void KMReaderMainWin::slotCustomReplyToMsg(
const QString &tmpl )
270 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
273 MessageComposer::ReplySmart,
276 connect( command, SIGNAL(completed(
KMCommand*)),
277 this, SLOT(slotReplyOrForwardFinished()) );
282 void KMReaderMainWin::slotCustomReplyAllToMsg(
const QString &tmpl )
284 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
287 MessageComposer::ReplyAll,
290 connect( command, SIGNAL(completed(
KMCommand*)),
291 this, SLOT(slotReplyOrForwardFinished()) );
297 void KMReaderMainWin::slotCustomForwardMsg(
const QString &tmpl)
299 if ( !mReaderWin->
message().hasPayload<KMime::Message::Ptr>() )
return;
303 connect( command, SIGNAL(completed(
KMCommand*)),
304 this, SLOT(slotReplyOrForwardFinished()) );
310 void KMReaderMainWin::slotConfigChanged()
317 void KMReaderMainWin::setupAccel()
319 if (
kmkernel->xmlGuiInstance().isValid() )
320 setComponentData(
kmkernel->xmlGuiInstance() );
324 connect( mMsgActions, SIGNAL(replyActionFinished()),
325 this, SLOT(slotReplyOrForwardFinished()) );
329 mSaveAtmAction =
new KAction(KIcon(
QLatin1String(
"mail-attachment")), i18n(
"Save A&ttachments..."), actionCollection() );
330 connect( mSaveAtmAction, SIGNAL(triggered(
bool)), mReaderWin->
viewer(), SLOT(slotAttachmentSaveAll()) );
332 mTrashAction =
new KAction( KIcon(
QLatin1String(
"user-trash") ), i18n(
"&Move to Trash"),
this );
333 mTrashAction->setIconText( i18nc(
"@action:intoolbar Move to Trash",
"Trash" ) );
334 mTrashAction->setHelpText( i18n(
"Move message to trashcan" ) );
335 mTrashAction->setShortcut(
QKeySequence( Qt::Key_Delete ) );
336 actionCollection()->addAction(
QLatin1String(
"move_to_trash"), mTrashAction );
337 connect( mTrashAction, SIGNAL(triggered()),
this, SLOT(slotTrashMsg()) );
339 KAction *closeAction = KStandardAction::close(
this, SLOT(close()), actionCollection() );
340 KShortcut closeShortcut = KShortcut(closeAction->shortcuts());
341 closeShortcut.setAlternate(
QKeySequence(Qt::Key_Escape));
342 closeAction->setShortcuts(closeShortcut);
346 mFontAction =
new KFontAction( i18n(
"Select Font"),
this );
347 actionCollection()->addAction(
QLatin1String(
"text_font"), mFontAction );
348 mFontAction->setFont( mReaderWin->
cssHelper()->bodyFont().family() );
349 connect( mFontAction, SIGNAL(triggered(
QString)),
350 SLOT(slotFontAction(
QString)) );
351 mFontSizeAction =
new KFontSizeAction( i18n(
"Select Size" ),
this );
352 mFontSizeAction->setFontSize( mReaderWin->
cssHelper()->bodyFont().pointSize() );
353 actionCollection()->addAction(
QLatin1String(
"text_size"), mFontSizeAction );
354 connect( mFontSizeAction, SIGNAL(fontSizeChanged(
int)),
355 SLOT(slotSizeAction(
int)) );
358 connect( mReaderWin->
viewer(), SIGNAL(popupMenu(Akonadi::Item,KUrl,KUrl,
QPoint)),
359 this, SLOT(slotMessagePopup(Akonadi::Item,KUrl,KUrl,
QPoint)) );
361 connect( mReaderWin->
viewer(), SIGNAL(itemRemoved()),
362 this, SLOT(close()) );
364 setStandardToolBarMenuEnabled(
true);
365 KStandardAction::configureToolbars(
this, SLOT(slotEditToolbars()), actionCollection());
366 connect( mReaderWin->
viewer(), SIGNAL(moveMessageToTrash()),
this, SLOT(slotTrashMsg()) );
370 KAction *KMReaderMainWin::copyActionMenu(
QMenu *menu)
377 action->setText(i18n(
"Copy Message To...") );
378 mainwin->
standardMailActionManager()->standardActionManager()->createActionFolderMenu( action->menu(), Akonadi::StandardActionManager::CopyItemToMenu );
379 connect( action->menu(), SIGNAL(triggered(
QAction*)), SLOT(slotCopyItem(
QAction*)) );
386 KAction *KMReaderMainWin::moveActionMenu(
QMenu *menu)
392 action->setText(i18n(
"Move Message To...") );
393 mainwin->
standardMailActionManager()->standardActionManager()->createActionFolderMenu( action->menu(), Akonadi::StandardActionManager::MoveItemToMenu );
394 connect( action->menu(), SIGNAL(triggered(
QAction*)), SLOT(slotMoveItem(
QAction*)) );
402 void KMReaderMainWin::slotMoveItem(
QAction *action)
407 const Akonadi::Collection collection = index.
data( Akonadi::EntityTreeModel::CollectionRole ).
value<Akonadi::Collection>();
408 copyOrMoveItem(collection,
true);
412 void KMReaderMainWin::copyOrMoveItem(
const Akonadi::Collection &collection,
bool move)
414 if ( mMsg.isValid() ) {
416 Akonadi::ItemMoveJob *job =
new Akonadi::ItemMoveJob( mMsg, collection,
this );
417 connect( job, SIGNAL(result(
KJob*)),
this, SLOT(slotCopyMoveResult(
KJob*)) );
419 Akonadi::ItemCopyJob *job =
new Akonadi::ItemCopyJob( mMsg, collection,
this );
420 connect( job, SIGNAL(result(
KJob*)),
this, SLOT(slotCopyMoveResult(
KJob*)) );
425 Akonadi::ItemCreateJob *job =
new Akonadi::ItemCreateJob( mMsg, collection,
this );
426 connect( job, SIGNAL(result(
KJob*)),
this, SLOT(slotCopyMoveResult(
KJob*)) );
430 void KMReaderMainWin::slotCopyItem(
QAction*action)
435 const Akonadi::Collection collection = index.
data( Akonadi::EntityTreeModel::CollectionRole ).
value<Akonadi::Collection>();
436 copyOrMoveItem(collection,
false);
440 void KMReaderMainWin::slotCopyMoveResult(
KJob * job )
442 if ( job->error() ) {
443 KMessageBox::sorry(
this, i18n(
"Cannot copy item. %1", job->errorString() ) );
447 void KMReaderMainWin::slotMessagePopup(
const Akonadi::Item&aMsg ,
const KUrl&aUrl,
const KUrl&imageUrl,
const QPoint& aPoint)
451 const QString email = KPIMUtils::firstEmailAddress( aUrl.path() ).toLower();
453 Akonadi::ContactSearchJob *job =
new Akonadi::ContactSearchJob(
this );
455 job->setQuery( Akonadi::ContactSearchJob::Email, email, Akonadi::ContactSearchJob::ExactMatch );
457 job->setProperty(
"point", aPoint );
458 job->setProperty(
"imageUrl", imageUrl );
459 job->setProperty(
"url", aUrl );
460 connect( job, SIGNAL(result(
KJob*)), SLOT(slotContactSearchJobForMessagePopupDone(
KJob*)) );
466 void KMReaderMainWin::slotContactSearchJobForMessagePopupDone(
KJob *job )
468 const Akonadi::ContactSearchJob *searchJob = qobject_cast<Akonadi::ContactSearchJob*>( job );
469 const bool contactAlreadyExists = !searchJob->contacts().isEmpty();
472 const bool uniqueContactFound = (listContact.
count() == 1);
473 if(uniqueContactFound) {
479 const Akonadi::Item msg = job->property(
"msg" ).value<Akonadi::Item>();
480 const QPoint aPoint = job->property(
"point" ).toPoint();
481 const KUrl imageUrl = job->property(
"imageUrl").value<KUrl>();
482 const KUrl url = job->property(
"url").value<KUrl>();
484 showMessagePopup(msg, url, imageUrl, aPoint, contactAlreadyExists, uniqueContactFound);
491 bool urlMenuAdded =
false;
492 bool copyAdded =
false;
493 const bool messageHasPayload = msg.hasPayload<KMime::Message::Ptr>();
494 if ( !url.isEmpty() ) {
499 if ( messageHasPayload ) {
502 menu->addSeparator();
505 if ( contactAlreadyExists ) {
506 if(uniqueContactFound) {
515 menu->addSeparator();
517 menu->addSeparator();
521 }
else if( url.protocol() !=
QLatin1String(
"attachment" ) ){
529 menu->addSeparator();
532 if(!imageUrl.isEmpty()) {
533 menu->addSeparator();
538 menu->addSeparator();
546 if ( !selectedText.isEmpty() ) {
549 if ( urlMenuAdded ) {
550 menu->addSeparator();
552 if(messageHasPayload) {
553 menu->addAction( mMsgActions->
replyMenu() );
554 menu->addSeparator();
556 menu->addSeparator();
561 menu->addSeparator();
563 menu->addSeparator();
565 menu->addSeparator();
567 }
else if ( !urlMenuAdded ) {
572 if (messageHasPayload) {
573 bool replyForwardMenu =
false;
574 Akonadi::Collection col = parentCollection();
575 if ( col.isValid() ) {
576 if ( ! ( CommonKernel->folderIsSentMailFolder( col ) ||
577 CommonKernel->folderIsDrafts( col ) ||
578 CommonKernel->folderIsTemplates( col ) ) ) {
579 replyForwardMenu =
true;
581 }
else if ( messageHasPayload ) {
582 replyForwardMenu =
true;
584 if ( replyForwardMenu ) {
587 menu->addAction( mMsgActions->
replyMenu() );
589 menu->addSeparator();
591 menu->addAction( copyActionMenu(menu) );
592 menu->addAction( moveActionMenu(menu));
593 menu->addSeparator();
596 menu->addSeparator();
597 if(!imageUrl.isEmpty()) {
598 menu->addSeparator();
602 menu->addSeparator();
605 menu->addSeparator();
613 menu->addSeparator();
618 menu->addAction( mSaveAtmAction );
619 if ( msg.isValid() ) {
620 menu->addSeparator();
623 menu->addSeparator();
633 menu->addSeparator();
637 menu->addSeparator();
640 if (
kmkernel->allowToDebugBalooSupport()) {
641 menu->addSeparator();
646 KAcceleratorManager::manage(menu);
647 menu->exec( aPoint, 0 );
652 void KMReaderMainWin::slotFontAction(
const QString& font)
659 void KMReaderMainWin::slotSizeAction(
int size )
666 void KMReaderMainWin::changeFont(
const QFont &f)
668 mReaderWin->
cssHelper()->setBodyFont( f );
669 mReaderWin->
cssHelper()->setPrintFont( f );
673 void KMReaderMainWin::slotEditToolbars()
675 saveMainWindowSettings( KConfigGroup(
KMKernel::self()->config(),
"ReaderWindow") );
676 KEditToolBar dlg( guiFactory(),
this );
677 connect( &dlg, SIGNAL(newToolBarConfig()), SLOT(slotUpdateToolbars()) );
681 void KMReaderMainWin::slotUpdateToolbars()
684 applyMainWindowSettings( KConfigGroup(
KMKernel::self()->config(),
"ReaderWindow") );
void addWebShortcutsMenu(KMenu *menu, const QString &text)
void setPointSize(int pointSize)
void showMessage(const QString &encoding, const Akonadi::Item &msg, const Akonadi::Collection &parentCollection=Akonadi::Collection())
take ownership of and show
KAction * urlOpenAction() const
This class implements a "reader window", that is a window used for reading or viewing messages...
KAction * blockImage() const
KAction * copyURLAction() const
MessageViewer::Viewer * viewer()
virtual void setCaption(const QString &caption)
Reimplement because we have this bug #Bug 163978.
KMenu * viewHtmlOption() const
Manages common actions that can be performed on one or more messages.
bool isAShortUrl(const KUrl &url) const
KAction * mailToComposeAction() const
KAction * saveAsAction() const
KAction * createEventAction() const
KAction * mailToReplyAction() const
Akonadi::Item message() const
static KMKernel * self()
normal control stuff
KAction * addFollowupReminderAction() const
void setupForwardingActionsList(KXMLGUIClient *guiClient)
Sets up action list for forward menu.
void setOverrideEncoding(const QString &encoding)
Set the override character encoding.
void setContactItem(const Akonadi::Item &contact, const KABC::Addressee &address)
MessageViewer::CSSHelper * cssHelper() const
KAction * expandShortUrlAction() const
KAction * copyImageLocation() const
KAction * createTodoAction() const
int count(const T &value) const
KAction * openAddrBookAction() const
void update(bool force=false)
KAction * printPreviewAction() const
Small helper structure which encapsulates the KMMessage created when creating a reply, and.
void setDecryptMessageOverwrite(bool overwrite=true)
Enforce message decryption.
void setDisplayFormatMessageOverwrite(MessageViewer::Viewer::DisplayFormatMessage format)
KAction * viewSourceAction() const
void showMessagePopup(const Akonadi::Item &msg, const KUrl &aUrl, const KUrl &imageUrl, const QPoint &aPoint, bool contactAlreadyExists, bool uniqueContactFound)
void setMsgPart(KMime::Content *aMsgPart)
Instead of settings a message to be shown sets a message part to be shown.
KAction * translateAction() const
void setHtmlLoadExtOverride(bool override)
void setMessage(const Akonadi::Item &item, MessageViewer::Viewer::UpdateMode updateMode=MessageViewer::Viewer::Delayed)
KActionMenu * forwardMenu() const
QAction * debugBalooAction() const
KAction * resetMessageDisplayFormatAction() const
void setCurrentMessage(const Akonadi::Item &item, const Akonadi::Item::List &items=Akonadi::Item::List())
KActionMenu * mailingListActionMenu() const
KAction * downloadImageToDiskAction() const
bool adblockEnabled() const
KAction * shareImage() const
QVariant fromValue(const T &value)
KAction * urlSaveAsAction() const
KAction * saveMessageDisplayFormatAction() const
KAction * copyAction() const
static GlobalSettings * self()
KToggleAction * toggleFixFontAction() const
KAction * addAddrBookAction() const
KAction * addToExistingContactAction() const
KActionMenu * replyMenu() const
KAction * editContactAction() const
QVariant data(int role) const
void setMessageView(KMReaderWin *msgView)
QString copyText() const
Return selected text.
KAction * addBookmarksAction() const
KAction * openBlockableItems() const
KAction * toggleMimePartTreeAction() const
void setFamily(const QString &family)
KAction * mailToForwardAction() const
KMReaderMainWin(MessageViewer::Viewer::DisplayFormatMessage format, bool htmlLoadExtOverride, char *name=0)
void setUseFixedFont(bool useFixedFont)
KAction * printAction() const
void setUseFixedFont(bool useFixedFont)
virtual ~KMReaderMainWin()
KAction * selectAllAction() const
bool mimePartTreeIsEmpty() const
Akonadi::StandardMailActionManager * standardMailActionManager() const
void setupForwardActions()
This function adds or updates the actions of the forward action menu, taking the preference whether t...
KAction * speakTextAction() const