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->headerStyle(), mReaderWin->headerStrategy(),
00221       mReaderWin->htmlOverride(), mReaderWin->htmlLoadExtOverride(),
00222       mReaderWin->isFixedFont(), mReaderWin->overrideEncoding() );
00223   command->setOverrideFont( mReaderWin->cssHelper()->bodyFont( mReaderWin->isFixedFont(), true /*printing*/ ) );
00224   command->start();
00225 }
00226 
00227 //-----------------------------------------------------------------------------
00228 void KMReaderMainWin::slotForwardInlineMsg()
00229 {
00230    KMCommand *command = 0;
00231    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00232     command = new KMForwardInlineCommand( this, mReaderWin->message(),
00233         mReaderWin->message()->parent()->identity() );
00234    } else {
00235     command = new KMForwardInlineCommand( this, mReaderWin->message() );
00236    }
00237    command->start();
00238 }
00239 
00240 //-----------------------------------------------------------------------------
00241 void KMReaderMainWin::slotForwardAttachedMsg()
00242 {
00243    KMCommand *command = 0;
00244    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00245      command = new KMForwardAttachedCommand( this, mReaderWin->message(),
00246         mReaderWin->message()->parent()->identity() );
00247    } else {
00248      command = new KMForwardAttachedCommand( this, mReaderWin->message() );
00249    }
00250    command->start();
00251 }
00252 
00253 //-----------------------------------------------------------------------------
00254 void KMReaderMainWin::slotForwardDigestMsg()
00255 {
00256    KMCommand *command = 0;
00257    if ( mReaderWin->message() && mReaderWin->message()->parent() ) {
00258      command = new KMForwardDigestCommand( this, mReaderWin->message(),
00259         mReaderWin->message()->parent()->identity() );
00260    } else {
00261      command = new KMForwardDigestCommand( this, mReaderWin->message() );
00262    }
00263    command->start();
00264 }
00265 
00266 //-----------------------------------------------------------------------------
00267 void KMReaderMainWin::slotRedirectMsg()
00268 {
00269   KMCommand *command = new KMRedirectCommand( this, mReaderWin->message() );
00270   command->start();
00271 }
00272 
00273 //-----------------------------------------------------------------------------
00274 void KMReaderMainWin::slotShowMsgSrc()
00275 {
00276   KMMessage *msg = mReaderWin->message();
00277   if ( !msg )
00278     return;
00279   KMCommand *command = new KMShowMsgSrcCommand( this, msg,
00280                                                 mReaderWin->isFixedFont() );
00281   command->start();
00282 }
00283 
00284 //-----------------------------------------------------------------------------
00285 void KMReaderMainWin::setupForwardActions()
00286 {
00287   disconnect( mForwardActionMenu, SIGNAL( activated() ), 0, 0 );
00288   mForwardActionMenu->remove( mForwardInlineAction );
00289   mForwardActionMenu->remove( mForwardAttachedAction );
00290 
00291   if ( GlobalSettings::self()->forwardingInlineByDefault() ) {
00292     mForwardActionMenu->insert( mForwardInlineAction, 0 );
00293     mForwardActionMenu->insert( mForwardAttachedAction, 1 );
00294     mForwardInlineAction->setShortcut( Key_F );
00295     mForwardAttachedAction->setShortcut( SHIFT+Key_F );
00296     connect( mForwardActionMenu, SIGNAL(activated()), this,
00297             SLOT(slotForwardInlineMsg()) );
00298 
00299   } else {
00300     mForwardActionMenu->insert( mForwardAttachedAction, 0 );
00301     mForwardActionMenu->insert( mForwardInlineAction, 1 );
00302     mForwardInlineAction->setShortcut( SHIFT+Key_F );
00303     mForwardAttachedAction->setShortcut( Key_F );
00304     connect( mForwardActionMenu, SIGNAL(activated()), this,
00305             SLOT(slotForwardAttachedMsg()) );
00306   }
00307 }
00308 
00309 //-----------------------------------------------------------------------------
00310 void KMReaderMainWin::slotConfigChanged()
00311 {
00312   //readConfig();
00313   setupForwardActions();
00314   setupForwardingActionsList();
00315 }
00316 
00317 void KMReaderMainWin::setupAccel()
00318 {
00319   if ( kmkernel->xmlGuiInstance() )
00320     setInstance( kmkernel->xmlGuiInstance() );
00321 
00322   mMsgActions = new KMail::MessageActions( actionCollection(), this );
00323   mMsgActions->setMessageView( mReaderWin );
00324   //----- File Menu
00325   //mOpenAction = KStdAction::open( this, SLOT( slotOpenMsg() ),
00326   //                                actionCollection() );
00327 
00328   //mSaveAsAction = new KAction( i18n("Save &As..."), "filesave",
00329   //                             KStdAccel::shortcut( KStdAccel::Save ),
00330   //                             this, SLOT( slotSaveMsg() ),
00331   //                             actionCollection(), "file_save_as" );
00332 
00333   mSaveAsAction = KStdAction::saveAs( mReaderWin, SLOT( slotSaveMsg() ),
00334                       actionCollection() );
00335   mSaveAsAction->setShortcut( KStdAccel::shortcut( KStdAccel::Save ) );
00336   mPrintAction = KStdAction::print( this, SLOT( slotPrintMsg() ),
00337                                     actionCollection() );
00338 
00339   KAction *closeAction = KStdAction::close( this, SLOT( close() ), actionCollection() );
00340   KShortcut closeShortcut = closeAction->shortcut();
00341   closeShortcut.append( KKey(Key_Escape));
00342   closeAction->setShortcut(closeShortcut);
00343 
00344   //----- Edit Menu
00345   KStdAction::copy( this, SLOT( slotCopy() ), actionCollection() );
00346   KStdAction::selectAll( this, SLOT( slotMarkAll() ), actionCollection() );
00347   KStdAction::find( this, SLOT(slotFind()), actionCollection() );
00348   KStdAction::findNext( this, SLOT( slotFindNext() ), actionCollection() );
00349   mTrashAction = new KAction( KGuiItem( i18n( "&Move to Trash" ), "edittrash",
00350                               i18n( "Move message to trashcan" ) ),
00351                               Key_Delete, this, SLOT( slotTrashMsg() ),
00352                               actionCollection(), "move_to_trash" );
00353 
00354   //----- View Menu
00355   mViewSourceAction = new KAction( i18n("&View Source"), Key_V, this,
00356                                    SLOT(slotShowMsgSrc()), actionCollection(),
00357                                    "view_source" );
00358 
00359 
00360   mForwardActionMenu = new KActionMenu( i18n("Message->","&Forward"),
00361                     "mail_forward", actionCollection(),
00362                     "message_forward" );
00363       mForwardInlineAction = new KAction( i18n("&Inline..."),
00364                                       "mail_forward", SHIFT+Key_F, this,
00365                                       SLOT(slotForwardInlineMsg()),
00366                                       actionCollection(),
00367                                       "message_forward_inline" );
00368 
00369       mForwardAttachedAction = new KAction( i18n("Message->Forward->","As &Attachment..."),
00370                                         "mail_forward", Key_F, this,
00371                                         SLOT(slotForwardAttachedMsg()),
00372                                         actionCollection(),
00373                                         "message_forward_as_attachment" );
00374 
00375       mForwardDigestAction = new KAction( i18n("Message->Forward->","As Di&gest..."),
00376                                       "mail_forward", 0, this,
00377                                       SLOT(slotForwardDigestMsg()),
00378                                       actionCollection(),
00379                                       "message_forward_as_digest" );
00380 
00381       mRedirectAction = new KAction( i18n("Message->Forward->","&Redirect..."),
00382                                  "mail_forward", Key_E, this,
00383                                  SLOT(slotRedirectMsg()),
00384                                  actionCollection(),
00385                                  "message_forward_redirect" );
00386 
00387   setupForwardActions();
00388 
00389   mForwardActionMenu->insert( mForwardDigestAction );
00390   mForwardActionMenu->insert( mRedirectAction );
00391 
00392   fontAction = new KFontAction( "Select Font", 0, actionCollection(),
00393                                "text_font" );
00394   fontAction->setFont( mReaderWin->cssHelper()->bodyFont().family() );
00395   connect( fontAction, SIGNAL( activated( const QString& ) ),
00396            SLOT( slotFontAction( const QString& ) ) );
00397   fontSizeAction = new KFontSizeAction( "Select Size", 0, actionCollection(),
00398                                        "text_size" );
00399   fontSizeAction->setFontSize( mReaderWin->cssHelper()->bodyFont().pointSize() );
00400   connect( fontSizeAction, SIGNAL( fontSizeChanged( int ) ),
00401            SLOT( slotSizeAction( int ) ) );
00402 
00403   QAccel *accel = new QAccel(mReaderWin, "showMsg()");
00404   accel->connectItem(accel->insertItem(Key_Up),
00405                      mReaderWin, SLOT(slotScrollUp()));
00406   accel->connectItem(accel->insertItem(Key_Down),
00407                      mReaderWin, SLOT(slotScrollDown()));
00408   accel->connectItem(accel->insertItem(Key_Prior),
00409                      mReaderWin, SLOT(slotScrollPrior()));
00410   accel->connectItem(accel->insertItem(Key_Next),
00411                      mReaderWin, SLOT(slotScrollNext()));
00412   accel->connectItem(accel->insertItem(KStdAccel::shortcut(KStdAccel::Copy)),
00413                      mReaderWin, SLOT(slotCopySelectedText()));
00414   connect( mReaderWin, SIGNAL(popupMenu(KMMessage&,const KURL&,const QPoint&)),
00415       this, SLOT(slotMsgPopup(KMMessage&,const KURL&,const QPoint&)));
00416   connect(mReaderWin, SIGNAL(urlClicked(const KURL&,int)),
00417       mReaderWin, SLOT(slotUrlClicked()));
00418 
00419   setStandardToolBarMenuEnabled(true);
00420   KStdAction::configureToolbars(this, SLOT(slotEditToolbars()), actionCollection());
00421 }
00422 
00423 
00424 void KMReaderMainWin::slotMsgPopup(KMMessage &aMsg, const KURL &aUrl, const QPoint& aPoint)
00425 {
00426   KPopupMenu * menu = new KPopupMenu;
00427   mUrl = aUrl;
00428   mMsg = &aMsg;
00429   bool urlMenuAdded=false;
00430   bool copyAdded = false;
00431   if (!aUrl.isEmpty())
00432   {
00433     if (aUrl.protocol() == "mailto") {
00434       // popup on a mailto URL
00435       mReaderWin->mailToComposeAction()->plug( menu );
00436       if ( mMsg ) {
00437         mReaderWin->mailToReplyAction()->plug( menu );
00438         mReaderWin->mailToForwardAction()->plug( menu );
00439         menu->insertSeparator();
00440       }
00441       mReaderWin->addAddrBookAction()->plug( menu );
00442       mReaderWin->openAddrBookAction()->plug( menu );
00443       mReaderWin->copyURLAction()->plug( menu );
00444       copyAdded = true;
00445     } else {
00446       // popup on a not-mailto URL
00447       mReaderWin->urlOpenAction()->plug( menu );
00448       mReaderWin->addBookmarksAction()->plug( menu );
00449       mReaderWin->urlSaveAsAction()->plug( menu );
00450       mReaderWin->copyURLAction()->plug( menu );
00451     }
00452     urlMenuAdded=true;
00453   }
00454   if(mReaderWin && !mReaderWin->copyText().isEmpty()) {
00455     if ( urlMenuAdded )
00456       menu->insertSeparator();
00457     mMsgActions->replyMenu()->plug( menu );
00458     menu->insertSeparator();
00459     if( !copyAdded )
00460        mReaderWin->copyAction()->plug( menu );
00461     mReaderWin->selectAllAction()->plug( menu );
00462   } else if ( !urlMenuAdded )
00463   {
00464     // popup somewhere else (i.e., not a URL) on the message
00465 
00466     if (!mMsg) // no message
00467     {
00468       delete menu;
00469       return;
00470     }
00471 
00472     if ( ! ( aMsg.parent() && ( aMsg.parent()->isSent() ||
00473                                 aMsg.parent()->isDrafts() ||
00474                                 aMsg.parent()->isTemplates() ) ) ) {
00475       // add the reply and forward actions only if we are not in a sent-mail,
00476       // templates or drafts folder
00477       //
00478       // FIXME: needs custom templates added to menu
00479       // (see KMMainWidget::updateCustomTemplateMenus)
00480       mMsgActions->replyMenu()->plug( menu );
00481       mForwardActionMenu->plug( menu );
00482       menu->insertSeparator();
00483     }
00484 
00485     QPopupMenu* copyMenu = new QPopupMenu(menu);
00486     KMMainWidget* mainwin = kmkernel->getKMMainWidget();
00487     if ( mainwin )
00488       mainwin->folderTree()->folderToPopupMenu( KMFolderTree::CopyMessage, this,
00489           &mMenuToFolder, copyMenu );
00490     menu->insertItem( i18n("&Copy To" ), copyMenu );
00491     menu->insertSeparator();
00492     mViewSourceAction->plug( menu );
00493     mReaderWin->toggleFixFontAction()->plug( menu );
00494     menu->insertSeparator();
00495     mPrintAction->plug( menu );
00496     mSaveAsAction->plug( menu );
00497     menu->insertItem( i18n("Save Attachments..."), mReaderWin, SLOT(slotSaveAttachments()) );
00498     mMsgActions->createTodoAction()->plug( menu );
00499   }
00500   menu->exec(aPoint, 0);
00501   delete menu;
00502 }
00503 
00504 void KMReaderMainWin::copySelectedToFolder( int menuId )
00505 {
00506   if (!mMenuToFolder[menuId])
00507     return;
00508 
00509   KMCommand *command = new KMCopyCommand( mMenuToFolder[menuId], mMsg );
00510   command->start();
00511 }
00512 
00513 void KMReaderMainWin::slotFontAction( const QString& font)
00514 {
00515   QFont f( mReaderWin->cssHelper()->bodyFont() );
00516   f.setFamily( font );
00517   mReaderWin->cssHelper()->setBodyFont( f );
00518   mReaderWin->cssHelper()->setPrintFont( f );
00519   mReaderWin->saveRelativePosition();
00520   mReaderWin->update();
00521 }
00522 
00523 void KMReaderMainWin::slotSizeAction( int size )
00524 {
00525   QFont f( mReaderWin->cssHelper()->bodyFont() );
00526   f.setPointSize( size );
00527   mReaderWin->cssHelper()->setBodyFont( f );
00528   mReaderWin->cssHelper()->setPrintFont( f );
00529   mReaderWin->saveRelativePosition();
00530   mReaderWin->update();
00531 }
00532 
00533 void KMReaderMainWin::slotCreateTodo()
00534 {
00535   if ( !mMsg )
00536     return;
00537   KMCommand *command = new CreateTodoCommand( this, mMsg );
00538   command->start();
00539 }
00540 
00541 void KMReaderMainWin::slotEditToolbars()
00542 {
00543   saveMainWindowSettings( KMKernel::config(), "ReaderWindow" );
00544   KEditToolbar dlg( guiFactory(), this );
00545   connect( &dlg, SIGNAL(newToolbarConfig()), SLOT(slotUpdateToolbars()) );
00546   dlg.exec();
00547 }
00548 
00549 void KMReaderMainWin::slotUpdateToolbars()
00550 {
00551   createGUI("kmreadermainwin.rc");
00552   applyMainWindowSettings(KMKernel::config(), "ReaderWindow");
00553 }
00554 
00555 #include "kmreadermainwin.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys