kmail

kmreadermainwin.cpp

00001 /*
00002     This file is part of KMail, the KDE mail client.
00003     Copyright (c) 2002 Don Sanders <sanders@kde.org>
00004 
00005     KMail is free software; you can redistribute it and/or modify it
00006     under the terms of the GNU General Public License, version 2, as
00007     published by the Free Software Foundation.
00008 
00009     KMail is distributed in the hope that it will be useful, but
00010     WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012     General Public License for more details.
00013 
00014     You should have received a copy of the GNU General Public License
00015     along with this program; if not, write to the Free Software
00016     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00017 */
00018 //
00019 // A toplevel KMainWindow derived class for displaying
00020 // single messages or single message parts.
00021 //
00022 // Could be extended to include support for normal main window
00023 // widgets like a toolbar.
00024 
00025 #ifdef HAVE_CONFIG_H
00026 #include <config.h>
00027 #endif
00028 
00029 #include <qaccel.h>
00030 #include <kapplication.h>
00031 #include <kedittoolbar.h>
00032 #include <klocale.h>
00033 #include <kstdaccel.h>
00034 #include <kwin.h>
00035 #include <kaction.h>
00036 #include <kiconloader.h>
00037 #include <kdebug.h>
00038 #include "kmcommands.h"
00039 #include "kmenubar.h"
00040 #include "kpopupmenu.h"
00041 #include "kmreaderwin.h"
00042 #include "kmfolder.h"
00043 #include "kmmainwidget.h"
00044 #include "kmfoldertree.h"
00045 #include "kmmsgdict.h"
00046 #include "csshelper.h"
00047 #include "messageactions.h"
00048 
00049 #include "globalsettings.h"
00050 
00051 #include "kmreadermainwin.h"
00052 
00053 KMReaderMainWin::KMReaderMainWin( bool htmlOverride, bool htmlLoadExtOverride,
00054                                   char *name )
00055   : KMail::SecondaryWindow( name ? name : "readerwindow#" ),
00056     mMsg( 0 )
00057 {
00058   mReaderWin = new KMReaderWin( this, this, actionCollection() );
00059   //mReaderWin->setShowCompleteMessage( true );
00060   mReaderWin->setAutoDelete( true );
00061   mReaderWin->setHtmlOverride( htmlOverride );
00062   mReaderWin->setHtmlLoadExtOverride( htmlLoadExtOverride );
00063   mReaderWin->setDecryptMessageOverwrite( true );
00064   mReaderWin->setShowSignatureDetails( false );
00065   initKMReaderMainWin();
00066 }
00067 
00068 
00069 //-----------------------------------------------------------------------------
00070 KMReaderMainWin::KMReaderMainWin( char *name )
00071   : KMail::SecondaryWindow( name ? name : "readerwindow#" ),
00072     mMsg( 0 )
00073 {
00074   mReaderWin = new KMReaderWin( this, this, actionCollection() );
00075   mReaderWin->setAutoDelete( true );
00076   initKMReaderMainWin();
00077 }
00078 
00079 
00080 //-----------------------------------------------------------------------------
00081 KMReaderMainWin::KMReaderMainWin(KMMessagePart* aMsgPart,
00082     bool aHTML, const QString& aFileName, const QString& pname,
00083     const QString & encoding, char *name )
00084   : KMail::SecondaryWindow( name ? name : "readerwindow#" ),
00085     mMsg( 0 )
00086 {
00087   mReaderWin = new KMReaderWin( this, this, actionCollection() );
00088   mReaderWin->setOverrideEncoding( encoding );
00089   mReaderWin->setMsgPart( aMsgPart, aHTML, aFileName, pname );
00090   initKMReaderMainWin();
00091 }
00092 
00093 
00094 //-----------------------------------------------------------------------------
00095 void KMReaderMainWin::initKMReaderMainWin() {
00096   setCentralWidget( mReaderWin );
00097   setupAccel();
00098   setupGUI( Keys | StatusBar | Create, "kmreadermainwin.rc" );
00099   setupForwardingActionsList();
00100   applyMainWindowSettings( KMKernel::config(), "Separate Reader Window" );
00101   if ( ! mReaderWin->message() ) {
00102     menuBar()->hide();
00103     toolBar( "mainToolBar" )->hide();
00104   }
00105 
00106   connect( kmkernel, SIGNAL( configChanged() ),
00107            this, SLOT( slotConfigChanged() ) );
00108 }
00109 
00110 void KMReaderMainWin::setupForwardingActionsList()
00111 {
00112   QPtrList<KAction> mForwardActionList;
00113   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
00114       unplugActionList( "forward_action_list" );
00115       mForwardActionList.append( mForwardInlineAction );
00116       mForwardActionList.append( mForwardAttachedAction );
00117       mForwardActionList.append( mForwardDigestAction );
00118       mForwardActionList.append( mRedirectAction );
00119       plugActionList( "forward_action_list", mForwardActionList );
00120   } else {
00121       unplugActionList( "forward_action_list" );
00122       mForwardActionList.append( mForwardAttachedAction );
00123       mForwardActionList.append( mForwardInlineAction );
00124       mForwardActionList.append( mForwardDigestAction );
00125       mForwardActionList.append( mRedirectAction );
00126       plugActionList( "forward_action_list", mForwardActionList );
00127   }
00128 }
00129 
00130 //-----------------------------------------------------------------------------
00131 KMReaderMainWin::~KMReaderMainWin()
00132 {
00133   saveMainWindowSettings( KMKernel::config(), "Separate Reader Window" );
00134 }
00135 
00136 //-----------------------------------------------------------------------------
00137 void KMReaderMainWin::setUseFixedFont( bool useFixedFont )
00138 {
00139   mReaderWin->setUseFixedFont( useFixedFont );
00140 }
00141 
00142 //-----------------------------------------------------------------------------
00143 void KMReaderMainWin::showMsg( const QString & encoding, KMMessage *msg,
00144                                unsigned long serNumOfOriginalMessage, int nodeIdOffset )
00145 {
00146   mReaderWin->setOverrideEncoding( encoding );
00147   mReaderWin->setMsg( msg, true );
00148   if ( serNumOfOriginalMessage != 0 ) {
00149     Q_ASSERT( nodeIdOffset != -1 );
00150     mReaderWin->setOriginalMsg( serNumOfOriginalMessage, nodeIdOffset );
00151   }
00152   mReaderWin->slotTouchMessage();
00153   setCaption( msg->subject() );
00154   mMsg = msg;
00155   mMsgActions->setCurrentMessage( msg );
00156   menuBar()->show();
00157   toolBar( "mainToolBar" )->show();
00158 
00159   connect ( msg->parent(), SIGNAL( destroyed( QObject* ) ), this, SLOT( slotFolderRemoved( QObject* ) ) );
00160 
00161 }
00162 
00163 void KMReaderMainWin::slotFolderRemoved( QObject* folderPtr )
00164 {
00165   assert(mMsg);
00166   assert(folderPtr == mMsg->parent());
00167   if( mMsg && folderPtr == mMsg->parent() )
00168     mMsg->setParent( 0 );
00169 }
00170 
00171 //-----------------------------------------------------------------------------
00172 void KMReaderMainWin::slotTrashMsg()
00173 {
00174   if ( !mMsg )
00175     return;
00176   // find the real msg by its sernum
00177   KMFolder* parent;
00178   int index;
00179   KMMsgDict::instance()->getLocation( mMsg->getMsgSerNum(), &parent, &index );
00180   if ( parent && !parent->isTrash() ) {
00181     // open the folder (ref counted)
00182     parent->open("trashmsg");
00183     KMMessage *msg = parent->getMsg( index );
00184     if (msg) {
00185       KMDeleteMsgCommand *command = new KMDeleteMsgCommand( parent, msg );
00186       command->start();
00187     }
00188     parent->close("trashmsg");
00189   }
00190   close();
00191 }
00192 
00193 //-----------------------------------------------------------------------------
00194 void KMReaderMainWin::slotFind()
00195 {
00196   mReaderWin->slotFind();
00197 }
00198 
00199 void KMReaderMainWin::slotFindNext()
00200 {
00201   mReaderWin->slotFindNext();
00202 }
00203 
00204 //-----------------------------------------------------------------------------
00205 void KMReaderMainWin::slotCopy()
00206 {
00207   mReaderWin->slotCopySelectedText();
00208 }
00209 
00210 //-----------------------------------------------------------------------------
00211 void KMReaderMainWin::slotMarkAll()
00212 {
00213   mReaderWin->selectAll();
00214 }
00215 
00216 //-----------------------------------------------------------------------------
00217 void KMReaderMainWin::slotPrintMsg()
00218 {
00219   KMPrintCommand *command = new KMPrintCommand( this, mReaderWin->message(),
00220       mReaderWin->htmlOverride(), mReaderWin->htmlLoadExtOverride(),
00221       mReaderWin->isFixedFont(), mReaderWin->overrideEncoding() );
00222   command->setOverrideFont( mReaderWin->cssHelper()->bodyFont( mReaderWin->isFixedFont(), true /*printing*/ ) );
00223   command->start();
00224 }
00225 
00226 //-----------------------------------------------------------------------------
00227 void KMReaderMainWin::slotForwardInlineMsg()
00228 {
00229    KMCommand *command = 0;
00230    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00231     command = new KMForwardInlineCommand( this, mReaderWin->message(),
00232         mReaderWin->message()->parent()->identity() );
00233    } else {
00234     command = new KMForwardInlineCommand( this, mReaderWin->message() );
00235    }
00236    command->start();
00237 }
00238 
00239 //-----------------------------------------------------------------------------
00240 void KMReaderMainWin::slotForwardAttachedMsg()
00241 {
00242    KMCommand *command = 0;
00243    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00244      command = new KMForwardAttachedCommand( this, mReaderWin->message(),
00245         mReaderWin->message()->parent()->identity() );
00246    } else {
00247      command = new KMForwardAttachedCommand( this, mReaderWin->message() );
00248    }
00249    command->start();
00250 }
00251 
00252 //-----------------------------------------------------------------------------
00253 void KMReaderMainWin::slotForwardDigestMsg()
00254 {
00255    KMCommand *command = 0;
00256    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00257      command = new KMForwardDigestCommand( this, mReaderWin->message(),
00258         mReaderWin->message()->parent()->identity() );
00259    } else {
00260      command = new KMForwardDigestCommand( this, mReaderWin->message() );
00261    }
00262    command->start();
00263 }
00264 
00265 //-----------------------------------------------------------------------------
00266 void KMReaderMainWin::slotRedirectMsg()
00267 {
00268   KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
00269   command->start();
00270 }
00271 
00272 //-----------------------------------------------------------------------------
00273 void KMReaderMainWin::slotShowMsgSrc()
00274 {
00275   KMMessage *msg = mReaderWin->message();
00276   if ( !msg )
00277     return;
00278   KMCommand *command = new KMShowMsgSrcCommand( this, msg,
00279                                                 mReaderWin->isFixedFont() );
00280   command->start();
00281 }
00282 
00283 //-----------------------------------------------------------------------------
00284 void KMReaderMainWin::setupForwardActions()
00285 {
00286   disconnect( mForwardActionMenu, SIGNAL( activated() ), 0, 0 );
00287   mForwardActionMenu->remove( mForwardInlineAction );
00288   mForwardActionMenu->remove( mForwardAttachedAction );
00289 
00290   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
00291     mForwardActionMenu->insert( mForwardInlineAction, 0 );
00292     mForwardActionMenu->insert( mForwardAttachedAction, 1 );
00293     mForwardInlineAction->setShortcut( Key_F );
00294     mForwardAttachedAction->setShortcut( SHIFT+Key_F );
00295     connect( mForwardActionMenu, SIGNAL(activated()), this,
00296             SLOT(slotForwardInlineMsg()) );
00297 
00298   } else {
00299     mForwardActionMenu->insert( mForwardAttachedAction, 0 );
00300     mForwardActionMenu->insert( mForwardInlineAction, 1 );
00301     mForwardInlineAction->setShortcut( SHIFT+Key_F );
00302     mForwardAttachedAction->setShortcut( Key_F );
00303     connect( mForwardActionMenu, SIGNAL(activated()), this,
00304             SLOT(slotForwardAttachedMsg()) );
00305   }
00306 }
00307 
00308 //-----------------------------------------------------------------------------
00309 void KMReaderMainWin::slotConfigChanged()
00310 {
00311   //readConfig();
00312   setupForwardActions();
00313   setupForwardingActionsList();
00314 }
00315 
00316 void KMReaderMainWin::setupAccel()
00317 {
00318   if ( kmkernel->xmlGuiInstance() )
00319     setInstance( kmkernel->xmlGuiInstance() );
00320 
00321   mMsgActions = new KMail::MessageActions( actionCollection(), this );
00322   mMsgActions->setMessageView( mReaderWin );
00323   //----- File Menu
00324   //mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
00325   //                                actionCollection() );
00326 
00327   //mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
00328   //                             KStdAccel::shortcut( KStdAccel::Save ),
00329   //                             this, SLOT( slotSaveMsg() ),
00330   //                             actionCollection(), "file_save_as" );
00331 
00332   mSaveAsAction = KStdAction::saveAs( mReaderWin, SLOT( slotSaveMsg() ),
00333                       actionCollection() );
00334   mSaveAsAction->setShortcut( KStdAccel::shortcut( KStdAccel::Save ) );
00335   mPrintAction = KStdAction::print( this, SLOT( slotPrintMsg() ),
00336                                     actionCollection() );
00337 
00338   KAction *closeAction = KStdAction::close( this, SLOT( close() ), actionCollection() );
00339   KShortcut closeShortcut = closeAction->shortcut();
00340   closeShortcut.append( KKey(Key_Escape));
00341   closeAction->setShortcut(closeShortcut);
00342 
00343   //----- Edit Menu
00344   KStdAction::copy( this, SLOT( slotCopy() ), actionCollection() );
00345   KStdAction::selectAll( this, SLOT( slotMarkAll() ), actionCollection() );
00346   KStdAction::find( this, SLOT(slotFind()), actionCollection() );
00347   KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection() );
00348   mTrashAction = new KAction( KGuiItem( i18n( "&Move to Trash" ), "edittrash",
00349                               i18n( "Move message to trashcan" ) ),
00350                               Key_Delete, this, SLOT( slotTrashMsg() ),
00351                               actionCollection(), "move_to_trash" );
00352 
00353   //----- View Menu
00354   mViewSourceAction = new KAction( i18n("&View Source"), Key_V, this,
00355                                    SLOT(slotShowMsgSrc()), actionCollection(),
00356                                    "view_source" );
00357 
00358 
00359   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
00360                     "mail_forward", actionCollection(),
00361                     "message_forward" );
00362       mForwardInlineAction = new KAction( i18n("&Inline..."),
00363                                       "mail_forward", SHIFT+Key_F, this,
00364                                       SLOT(slotForwardInlineMsg()),
00365                                       actionCollection(),
00366                                       "message_forward_inline" );
00367 
00368       mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
00369                                         "mail_forward", Key_F, this,
00370                                         SLOT(slotForwardAttachedMsg()),
00371                                         actionCollection(),
00372                                         "message_forward_as_attachment" );
00373 
00374       mForwardDigestAction = new KAction( i18n("Message->Forward->","As Di&gest..."),
00375                                       "mail_forward", 0, this,
00376                                       SLOT(slotForwardDigestMsg()),
00377                                       actionCollection(),
00378                                       "message_forward_as_digest" );
00379 
00380       mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
00381                                  "mail_forward", Key_E, this,
00382                                  SLOT(slotRedirectMsg()),
00383                                  actionCollection(),
00384                                  "message_forward_redirect" );
00385 
00386   setupForwardActions();
00387 
00388   mForwardActionMenu->insert( mForwardDigestAction );
00389   mForwardActionMenu->insert( mRedirectAction );
00390 
00391   fontAction = new KFontAction( "Select Font", 0, actionCollection(),
00392                                "text_font" );
00393   fontAction->setFont( mReaderWin->cssHelper()->bodyFont().family() );
00394   connect( fontAction, SIGNAL( activated( const QString& ) ),
00395            SLOT( slotFontAction( const QString& ) ) );
00396   fontSizeAction = new KFontSizeAction( "Select Size", 0, actionCollection(),
00397                                        "text_size" );
00398   fontSizeAction->setFontSize( mReaderWin->cssHelper()->bodyFont().pointSize() );
00399   connect( fontSizeAction, SIGNAL( fontSizeChanged( int ) ),
00400            SLOT( slotSizeAction( int ) ) );
00401 
00402   QAccel *accel = new QAccel(mReaderWin, "showMsg()");
00403   accel->connectItem(accel->insertItem(Key_Up),
00404                      mReaderWin, SLOT(slotScrollUp()));
00405   accel->connectItem(accel->insertItem(Key_Down),
00406                      mReaderWin, SLOT(slotScrollDown()));
00407   accel->connectItem(accel->insertItem(Key_Prior),
00408                      mReaderWin, SLOT(slotScrollPrior()));
00409   accel->connectItem(accel->insertItem(Key_Next),
00410                      mReaderWin, SLOT(slotScrollNext()));
00411   accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
00412                      mReaderWin, SLOT(slotCopySelectedText()));
00413   connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
00414       this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
00415   connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
00416       mReaderWin, SLOT(slotUrlClicked()));
00417 
00418   setStandardToolBarMenuEnabled(true);
00419   KStdAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
00420 }
00421 
00422 
00423 void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
00424 {
00425   KPopupMenu * menu = new KPopupMenu;
00426   mUrl = aUrl;
00427   mMsg = &aMsg;
00428   bool urlMenuAdded=false;
00429   bool copyAdded = false;
00430   if (!aUrl.isEmpty())
00431   {
00432     if (aUrl.protocol() == "mailto") {
00433       // popup on a mailto URL
00434       mReaderWin->mailToComposeAction()->plug( menu );
00435       if ( mMsg ) {
00436         mReaderWin->mailToReplyAction()->plug( menu );
00437         mReaderWin->mailToForwardAction()->plug( menu );
00438         menu->insertSeparator();
00439       }
00440       mReaderWin->addAddrBookAction()->plug( menu );
00441       mReaderWin->openAddrBookAction()->plug( menu );
00442       mReaderWin->copyURLAction()->plug( menu );
00443       copyAdded = true;
00444     } else {
00445       // popup on a not-mailto URL
00446       mReaderWin->urlOpenAction()->plug( menu );
00447       mReaderWin->addBookmarksAction()->plug( menu );
00448       mReaderWin->urlSaveAsAction()->plug( menu );
00449       mReaderWin->copyURLAction()->plug( menu );
00450     }
00451     urlMenuAdded=true;
00452   }
00453   if(mReaderWin && !mReaderWin->copyText().isEmpty()) {
00454     if ( urlMenuAdded )
00455       menu->insertSeparator();
00456     mMsgActions->replyMenu()->plug( menu );
00457     menu->insertSeparator();
00458     if( !copyAdded )
00459        mReaderWin->copyAction()->plug( menu );
00460     mReaderWin->selectAllAction()->plug( menu );
00461   } else if ( !urlMenuAdded )
00462   {
00463     // popup somewhere else (i.e., not a URL) on the message
00464 
00465     if (!mMsg) // no message
00466     {
00467       delete menu;
00468       return;
00469     }
00470 
00471     if ( ! ( aMsg.parent() && ( aMsg.parent()->isSent() ||
00472                                 aMsg.parent()->isDrafts() ||
00473                                 aMsg.parent()->isTemplates() ) ) ) {
00474       // add the reply and forward actions only if we are not in a sent-mail,
00475       // templates or drafts folder
00476       //
00477       // FIXME: needs custom templates added to menu
00478       // (see KMMainWidget::updateCustomTemplateMenus)
00479       mMsgActions->replyMenu()->plug( menu );
00480       mForwardActionMenu->plug( menu );
00481       menu->insertSeparator();
00482     }
00483 
00484     QPopupMenu* copyMenu = new QPopupMenu(menu);
00485     KMMainWidget* mainwin = kmkernel->getKMMainWidget();
00486     if ( mainwin )
00487       mainwin->folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage, this,
00488           &mMenuToFolder, copyMenu );
00489     menu->insertItem( i18n("&Copy To" ), copyMenu );
00490     menu->insertSeparator();
00491     mViewSourceAction->plug( menu );
00492     mReaderWin->toggleFixFontAction()->plug( menu );
00493     menu->insertSeparator();
00494     mPrintAction->plug( menu );
00495     mSaveAsAction->plug( menu );
00496     menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
00497     mMsgActions->createTodoAction()->plug( menu );
00498   }
00499   menu->exec(aPoint, 0);
00500   delete menu;
00501 }
00502 
00503 void KMReaderMainWin::copySelectedToFolder( int menuId )
00504 {
00505   if (!mMenuToFolder[menuId])
00506     return;
00507 
00508   KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
00509   command->start();
00510 }
00511 
00512 void KMReaderMainWin::slotFontAction( const QString& font)
00513 {
00514   QFont f( mReaderWin->cssHelper()->bodyFont() );
00515   f.setFamily( font );
00516   mReaderWin->cssHelper()->setBodyFont( f );
00517   mReaderWin->cssHelper()->setPrintFont( f );
00518   mReaderWin->saveRelativePosition();
00519   mReaderWin->update();
00520 }
00521 
00522 void KMReaderMainWin::slotSizeAction( int size )
00523 {
00524   QFont f( mReaderWin->cssHelper()->bodyFont() );
00525   f.setPointSize( size );
00526   mReaderWin->cssHelper()->setBodyFont( f );
00527   mReaderWin->cssHelper()->setPrintFont( f );
00528   mReaderWin->saveRelativePosition();
00529   mReaderWin->update();
00530 }
00531 
00532 void KMReaderMainWin::slotCreateTodo()
00533 {
00534   if ( !mMsg )
00535     return;
00536   KMCommand *command = new CreateTodoCommand( this, mMsg );
00537   command->start();
00538 }
00539 
00540 void KMReaderMainWin::slotEditToolbars()
00541 {
00542   saveMainWindowSettings( KMKernel::config(), "ReaderWindow" );
00543   KEditToolbar dlg( guiFactory(), this );
00544   connect( &dlg, SIGNAL(newToolbarConfig()), SLOT(slotUpdateToolbars()) );
00545   dlg.exec();
00546 }
00547 
00548 void KMReaderMainWin::slotUpdateToolbars()
00549 {
00550   createGUI("kmreadermainwin.rc");
00551   applyMainWindowSettings(KMKernel::config(), "ReaderWindow");
00552 }
00553 
00554 #include "kmreadermainwin.moc"