// -*- mode: C++; c-file-style: "gnu" -*-
// kmcomposewin.cpp
// Author: Markus Wuebben <markus.wuebben@kde.org>
// This code is published under the GPL.
# undef GrayScale
# undef Color
# include <config.h>
# define REALLY_WANT_KMCOMPOSEWIN_H
# include "kmcomposewin.h"
# undef REALLY_WANT_KMCOMPOSEWIN_H
# include "kmedit.h"
# include "kmlineeditspell.h"
# include "kmatmlistview.h"
# include "kmmainwin.h"
# include "kmreadermainwin.h"
# include "messagesender.h"
# include "kmmsgpartdlg.h"
# include <kpgpblock.h>
# include <kaddrbook.h>
# include "kmaddrbook.h"
# include "kmmsgdict.h"
# include "kmfolderimap.h"
# include "kmfoldermgr.h"
# include "kmfoldercombobox.h"
# include "kmtransport.h"
# include "kmcommands.h"
# include "kcursorsaver.h"
# include "partNode.h"
# include "encodingdetector.h"
# include "attachmentlistview.h"
# include "transportmanager.h"
using KMail : : AttachmentListView ;
# include "dictionarycombobox.h"
using KMail : : DictionaryComboBox ;
# include "addressesdialog.h"
using KPIM : : AddressesDialog ;
# include "addresseeemailselection.h"
using KPIM : : AddresseeEmailSelection ;
using KPIM : : AddresseeSelectorDialog ;
# include <maillistdrag.h>
using KPIM : : MailListDrag ;
# include "recentaddresses.h"
using TDERecentAddress : : RecentAddresses ;
# include "kleo_util.h"
# include "stl_util.h"
# include "recipientseditor.h"
# include "editorwatcher.h"
# include "attachmentcollector.h"
# include "objecttreeparser.h"
# include "kmfoldermaildir.h"
# include <libkpimidentities/identitymanager.h>
# include <libkpimidentities/identitycombo.h>
# include <libkpimidentities/identity.h>
# include <libtdepim/tdefileio.h>
# include <libemailfunctions/email.h>
# include <kleo/cryptobackendfactory.h>
# include <kleo/exportjob.h>
# include <kleo/specialjob.h>
# include <ui/progressdialog.h>
# include <ui/keyselectiondialog.h>
# include <gpgmepp/context.h>
# include <gpgmepp/key.h>
# include <tdeio/netaccess.h>
# include "tdelistboxdialog.h"
# include "messagecomposer.h"
# include "chiasmuskeyselector.h"
# include <kcharsets.h>
# include <tdecompletionbox.h>
# include <kcursor.h>
# include <kcombobox.h>
# include <tdestdaccel.h>
# include <tdepopupmenu.h>
# include <kedittoolbar.h>
# include <kkeydialog.h>
# include <kdebug.h>
# include <tdefiledialog.h>
# include <twin.h>
# include <kinputdialog.h>
# include <tdemessagebox.h>
# include <kurldrag.h>
# include <tdeio/scheduler.h>
# include <tdetempfile.h>
# include <tdelocale.h>
# include <tdeapplication.h>
# include <kstatusbar.h>
# include <tdeaction.h>
# include <kstdaction.h>
# include <kdirwatch.h>
# include <kstdguiitem.h>
# include <kiconloader.h>
# include <kpushbutton.h>
# include <kuserprofile.h>
# include <krun.h>
# include <ktempdir.h>
# include <kstandarddirs.h>
//#include <keditlistbox.h>
# include "globalsettings.h"
# include "replyphrases.h"
# include <tdespell.h>
# include <tdespelldlg.h>
# include <spellingfilter.h>
# include <ksyntaxhighlighter.h>
# include <kcolordialog.h>
# include <kzip.h>
# include <ksavefile.h>
# include <tqtabdialog.h>
# include <tqregexp.h>
# include <tqbuffer.h>
# include <tqtooltip.h>
# include <tqtextcodec.h>
# include <tqheader.h>
# include <tqwhatsthis.h>
# include <tqfontdatabase.h>
# include <mimelib/mimepp.h>
# include <algorithm>
# include <memory>
# include <sys/stat.h>
# include <sys/types.h>
# include <stdlib.h>
# include <unistd.h>
# include <errno.h>
# include <fcntl.h>
# include <assert.h>
# include "kmcomposewin.moc"
# include "snippetwidget.h"
KMail : : Composer * KMail : : makeComposer ( KMMessage * msg , uint identitiy ) {
return KMComposeWin : : create ( msg , identitiy ) ;
}
KMail : : Composer * KMComposeWin : : create ( KMMessage * msg , uint identitiy ) {
return new KMComposeWin ( msg , identitiy ) ;
}
//-----------------------------------------------------------------------------
KMComposeWin : : KMComposeWin ( KMMessage * aMsg , uint id )
: MailComposerIface ( ) , KMail : : Composer ( " kmail-composer# " ) ,
mSpellCheckInProgress ( false ) ,
mDone ( false ) ,
mAtmModified ( false ) ,
mAtmSelectNew ( 0 ) ,
mMsg ( 0 ) ,
mAttachMenu ( 0 ) ,
mSigningAndEncryptionExplicitlyDisabled ( false ) ,
mFolder ( 0 ) ,
mUseHTMLEditor ( false ) ,
mId ( id ) ,
mAttachPK ( 0 ) , mAttachMPK ( 0 ) ,
mAttachRemoveAction ( 0 ) , mAttachSaveAction ( 0 ) , mAttachPropertiesAction ( 0 ) ,
mAppendSignatureAction ( 0 ) , mPrependSignatureAction ( 0 ) , mInsertSignatureAction ( 0 ) ,
mSignAction ( 0 ) , mEncryptAction ( 0 ) , mRequestMDNAction ( 0 ) ,
mUrgentAction ( 0 ) , mAllFieldsAction ( 0 ) , mFromAction ( 0 ) ,
mReplyToAction ( 0 ) , mToAction ( 0 ) , mCcAction ( 0 ) , mBccAction ( 0 ) ,
mSubjectAction ( 0 ) ,
mIdentityAction ( 0 ) , mTransportAction ( 0 ) , mFccAction ( 0 ) ,
mWordWrapAction ( 0 ) , mFixedFontAction ( 0 ) , mAutoSpellCheckingAction ( 0 ) ,
mDictionaryAction ( 0 ) , mSnippetAction ( 0 ) ,
mEncodingAction ( 0 ) ,
mCryptoModuleAction ( 0 ) ,
mEncryptChiasmusAction ( 0 ) ,
mEncryptWithChiasmus ( false ) ,
mComposer ( 0 ) ,
mLabelWidth ( 0 ) ,
mAutoSaveTimer ( 0 ) , mLastAutoSaveErrno ( 0 ) ,
mSignatureStateIndicator ( 0 ) , mEncryptionStateIndicator ( 0 ) ,
mPreserveUserCursorPosition ( false ) ,
mPreventFccOverwrite ( false ) ,
mCheckForRecipients ( true ) ,
mCheckForForgottenAttachments ( true ) ,
mIgnoreStickyFields ( false )
{
mClassicalRecipients = GlobalSettings : : self ( ) - > recipientsEditorType ( ) = =
GlobalSettings : : EnumRecipientsEditorType : : Classic ;
mSubjectTextWasSpellChecked = false ;
if ( kmkernel - > xmlGuiInstance ( ) )
setInstance ( kmkernel - > xmlGuiInstance ( ) ) ;
mMainWidget = new TQWidget ( this ) ;
// splitter between the headers area and the actual editor
mHeadersToEditorSplitter = new TQSplitter ( Qt : : Vertical , mMainWidget , " mHeadersToEditorSplitter " ) ;
mHeadersToEditorSplitter - > setChildrenCollapsible ( false ) ;
mHeadersArea = new TQWidget ( mHeadersToEditorSplitter ) ;
mHeadersArea - > setSizePolicy ( mHeadersToEditorSplitter - > sizePolicy ( ) . horData ( ) , TQSizePolicy : : Maximum ) ;
TQVBoxLayout * v = new TQVBoxLayout ( mMainWidget ) ;
v - > addWidget ( mHeadersToEditorSplitter ) ;
mIdentity = new KPIM : : IdentityCombo ( kmkernel - > identityManager ( ) , mHeadersArea ) ;
TQToolTip : : add ( mIdentity ,
i18n ( " Select an identity for this message " ) ) ;
mDictionaryCombo = new DictionaryComboBox ( mHeadersArea ) ;
TQToolTip : : add ( mDictionaryCombo ,
i18n ( " Select the dictionary to use when spell-checking this message " ) ) ;
mFcc = new KMFolderComboBox ( mHeadersArea ) ;
mFcc - > showOutboxFolder ( false ) ;
TQToolTip : : add ( mFcc ,
i18n ( " Select the sent-mail folder where a copy of this message will be saved " ) ) ;
mTransport = new TQComboBox ( true , mHeadersArea ) ;
TQToolTip : : add ( mTransport ,
i18n ( " Select the outgoing account to use for sending this message " ) ) ;
mEdtFrom = new KMLineEdit ( false , mHeadersArea , " fromLine " ) ;
TQToolTip : : add ( mEdtFrom ,
i18n ( " Set the \" From: \" email address for this message " ) ) ;
mEdtReplyTo = new KMLineEdit ( true , mHeadersArea , " replyToLine " ) ;
TQToolTip : : add ( mEdtReplyTo ,
i18n ( " Set the \" Reply-To: \" email address for this message " ) ) ;
connect ( mEdtReplyTo , TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
if ( mClassicalRecipients ) {
mRecipientsEditor = 0 ;
mEdtTo = new KMLineEdit ( true , mHeadersArea , " toLine " ) ;
mEdtCc = new KMLineEdit ( true , mHeadersArea , " ccLine " ) ;
mEdtBcc = new KMLineEdit ( true , mHeadersArea , " bccLine " ) ;
mLblTo = new TQLabel ( mHeadersArea ) ;
mLblCc = new TQLabel ( mHeadersArea ) ;
mLblBcc = new TQLabel ( mHeadersArea ) ;
mBtnTo = new TQPushButton ( " ... " , mHeadersArea ) ;
mBtnCc = new TQPushButton ( " ... " , mHeadersArea ) ;
mBtnBcc = new TQPushButton ( " ... " , mHeadersArea ) ;
//mBtnFrom = new TQPushButton("...",mHeadersArea);
TQString tip = i18n ( " Select email address(es) " ) ;
TQToolTip : : add ( mBtnTo , tip ) ;
TQToolTip : : add ( mBtnCc , tip ) ;
TQToolTip : : add ( mBtnBcc , tip ) ;
mBtnTo - > setFocusPolicy ( TQ_NoFocus ) ;
mBtnCc - > setFocusPolicy ( TQ_NoFocus ) ;
mBtnBcc - > setFocusPolicy ( TQ_NoFocus ) ;
//mBtnFrom->setFocusPolicy(TQ_NoFocus);
connect ( mBtnTo , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( slotAddrBookTo ( ) ) ) ;
connect ( mBtnCc , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( slotAddrBookTo ( ) ) ) ;
connect ( mBtnBcc , TQT_SIGNAL ( clicked ( ) ) , TQT_SLOT ( slotAddrBookTo ( ) ) ) ;
//connect(mBtnFrom,TQT_SIGNAL(clicked()),TQT_SLOT(slotAddrBookFrom()));
connect ( mEdtTo , TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
connect ( mEdtCc , TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
connect ( mEdtBcc , TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
mEdtTo - > setFocus ( ) ;
} else {
mEdtTo = 0 ;
mEdtCc = 0 ;
mEdtBcc = 0 ;
mLblTo = 0 ;
mLblCc = 0 ;
mLblBcc = 0 ;
mBtnTo = 0 ;
mBtnCc = 0 ;
mBtnBcc = 0 ;
//mBtnFrom = 0;
mRecipientsEditor = new RecipientsEditor ( mHeadersArea ) ;
connect ( mRecipientsEditor ,
TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
connect ( mRecipientsEditor , TQT_SIGNAL ( sizeHintChanged ( ) ) , TQT_SLOT ( recipientEditorSizeHintChanged ( ) ) ) ;
mRecipientsEditor - > setFocus ( ) ;
}
mEdtSubject = new KMLineEditSpell ( false , mHeadersArea , " subjectLine " ) ;
TQToolTip : : add ( mEdtSubject ,
i18n ( " Set a subject for this message " ) ) ;
mLblIdentity = new TQLabel ( i18n ( " &Identity: " ) , mHeadersArea ) ;
mDictionaryLabel = new TQLabel ( i18n ( " &Dictionary: " ) , mHeadersArea ) ;
mLblFcc = new TQLabel ( i18n ( " &Sent-Mail folder: " ) , mHeadersArea ) ;
mLblTransport = new TQLabel ( i18n ( " &Mail transport: " ) , mHeadersArea ) ;
mLblFrom = new TQLabel ( i18n ( " sender address field " , " &From: " ) , mHeadersArea ) ;
mLblReplyTo = new TQLabel ( i18n ( " &Reply to: " ) , mHeadersArea ) ;
mLblSubject = new TQLabel ( i18n ( " S&ubject: " ) , mHeadersArea ) ;
TQString sticky = i18n ( " Sticky " ) ;
mBtnIdentity = new TQCheckBox ( sticky , mHeadersArea ) ;
TQToolTip : : add ( mBtnIdentity ,
i18n ( " Use the selected value as your identity for future messages " ) ) ;
mBtnFcc = new TQCheckBox ( sticky , mHeadersArea ) ;
TQToolTip : : add ( mBtnFcc ,
i18n ( " Use the selected value as your sent-mail folder for future messages " ) ) ;
mBtnTransport = new TQCheckBox ( sticky , mHeadersArea ) ;
TQToolTip : : add ( mBtnTransport ,
i18n ( " Use the selected value as your outgoing account for future messages " ) ) ;
mBtnDictionary = new TQCheckBox ( sticky , mHeadersArea ) ;
TQToolTip : : add ( mBtnDictionary ,
i18n ( " Use the selected value as your dictionary for future messages " ) ) ;
//setWFlags( WType_TopLevel | WStyle_Dialog );
mHtmlMarkup = GlobalSettings : : self ( ) - > useHtmlMarkup ( ) ;
mShowHeaders = GlobalSettings : : self ( ) - > headers ( ) ;
mDone = false ;
mGrid = 0 ;
mAtmListView = 0 ;
mAtmList . setAutoDelete ( true ) ;
mAtmTempList . setAutoDelete ( true ) ;
mAtmModified = false ;
mAutoDeleteMsg = false ;
mFolder = 0 ;
mAutoCharset = true ;
mFixedFontAction = 0 ;
mTempDir = 0 ;
// the attachment view is separated from the editor by a splitter
mSplitter = new TQSplitter ( Qt : : Vertical , mHeadersToEditorSplitter , " mSplitter " ) ;
mSplitter - > setChildrenCollapsible ( false ) ;
mSnippetSplitter = new TQSplitter ( Qt : : Horizontal , mSplitter , " mSnippetSplitter " ) ;
mSnippetSplitter - > setChildrenCollapsible ( false ) ;
TQWidget * editorAndCryptoStateIndicators = new TQWidget ( mSnippetSplitter ) ;
TQVBoxLayout * vbox = new TQVBoxLayout ( editorAndCryptoStateIndicators ) ;
TQHBoxLayout * hbox = new TQHBoxLayout ( vbox ) ;
{
mSignatureStateIndicator = new TQLabel ( editorAndCryptoStateIndicators ) ;
mSignatureStateIndicator - > setAlignment ( TQt : : AlignHCenter ) ;
hbox - > addWidget ( mSignatureStateIndicator ) ;
TDEConfigGroup reader ( KMKernel : : config ( ) , " Reader " ) ;
TQPalette p ( mSignatureStateIndicator - > palette ( ) ) ;
TQColor defaultSignedColor ( 0x40 , 0xFF , 0x40 ) ; // light green // pgp ok, trusted key
TQColor defaultEncryptedColor ( 0x00 , 0x80 , 0xFF ) ; // light blue // pgp encrypted
p . setColor ( TQColorGroup : : Background , reader . readColorEntry ( " PGPMessageOkKeyOk " , & defaultSignedColor ) ) ;
mSignatureStateIndicator - > setPalette ( p ) ;
mEncryptionStateIndicator = new TQLabel ( editorAndCryptoStateIndicators ) ;
mEncryptionStateIndicator - > setAlignment ( TQt : : AlignHCenter ) ;
hbox - > addWidget ( mEncryptionStateIndicator ) ;
p . setColor ( TQColorGroup : : Background , reader . readColorEntry ( " PGPMessageEncr " , & defaultEncryptedColor ) ) ;
mEncryptionStateIndicator - > setPalette ( p ) ;
}
mEditor = new KMEdit ( editorAndCryptoStateIndicators , this , mDictionaryCombo - > spellConfig ( ) ) ;
vbox - > addWidget ( mEditor ) ;
mSnippetWidget = new SnippetWidget ( mEditor , actionCollection ( ) , mSnippetSplitter ) ;
mSnippetWidget - > setShown ( GlobalSettings : : self ( ) - > showSnippetManager ( ) ) ;
// mSplitter->moveToFirst( editorAndCryptoStateIndicators );
mSplitter - > setOpaqueResize ( true ) ;
mEditor - > initializeAutoSpellChecking ( ) ;
mEditor - > setTextFormat ( TQt : : PlainText ) ;
mEditor - > setAcceptDrops ( true ) ;
TQWhatsThis : : add ( mBtnIdentity ,
GlobalSettings : : self ( ) - > stickyIdentityItem ( ) - > whatsThis ( ) ) ;
TQWhatsThis : : add ( mBtnFcc ,
GlobalSettings : : self ( ) - > stickyFccItem ( ) - > whatsThis ( ) ) ;
TQWhatsThis : : add ( mBtnTransport ,
GlobalSettings : : self ( ) - > stickyTransportItem ( ) - > whatsThis ( ) ) ;
TQWhatsThis : : add ( mBtnTransport ,
GlobalSettings : : self ( ) - > stickyDictionaryItem ( ) - > whatsThis ( ) ) ;
mSpellCheckInProgress = false ;
setCaption ( i18n ( " Composer " ) ) ;
setMinimumSize ( 200 , 200 ) ;
mBtnIdentity - > setFocusPolicy ( TQ_NoFocus ) ;
mBtnFcc - > setFocusPolicy ( TQ_NoFocus ) ;
mBtnTransport - > setFocusPolicy ( TQ_NoFocus ) ;
mBtnDictionary - > setFocusPolicy ( TQ_NoFocus ) ;
mAtmListView = new AttachmentListView ( this , mSplitter ,
" attachment list view " ) ;
mAtmListView - > setSelectionMode ( TQListView : : Extended ) ;
mAtmListView - > addColumn ( i18n ( " Name " ) , 200 ) ;
mAtmListView - > addColumn ( i18n ( " Size " ) , 80 ) ;
mAtmListView - > addColumn ( i18n ( " Encoding " ) , 120 ) ;
int atmColType = mAtmListView - > addColumn ( i18n ( " Type " ) , 120 ) ;
// Stretch "Type".
mAtmListView - > header ( ) - > setStretchEnabled ( true , atmColType ) ;
mAtmEncryptColWidth = 80 ;
mAtmSignColWidth = 80 ;
mAtmCompressColWidth = 100 ;
mAtmColCompress = mAtmListView - > addColumn ( i18n ( " Compress " ) ,
mAtmCompressColWidth ) ;
mAtmColEncrypt = mAtmListView - > addColumn ( i18n ( " Encrypt " ) ,
mAtmEncryptColWidth ) ;
mAtmColSign = mAtmListView - > addColumn ( i18n ( " Sign " ) ,
mAtmSignColWidth ) ;
mAtmListView - > setColumnWidth ( mAtmColEncrypt , 0 ) ;
mAtmListView - > setColumnWidth ( mAtmColSign , 0 ) ;
mAtmListView - > setAllColumnsShowFocus ( true ) ;
connect ( mAtmListView ,
TQT_SIGNAL ( doubleClicked ( TQListViewItem * ) ) ,
TQT_SLOT ( slotAttachEdit ( ) ) ) ;
connect ( mAtmListView ,
TQT_SIGNAL ( rightButtonPressed ( TQListViewItem * , const TQPoint & , int ) ) ,
TQT_SLOT ( slotAttachPopupMenu ( TQListViewItem * , const TQPoint & , int ) ) ) ;
connect ( mAtmListView ,
TQT_SIGNAL ( selectionChanged ( ) ) ,
TQT_SLOT ( slotUpdateAttachActions ( ) ) ) ;
connect ( mAtmListView ,
TQT_SIGNAL ( attachmentDeleted ( ) ) ,
TQT_SLOT ( slotAttachRemove ( ) ) ) ;
connect ( mAtmListView ,
TQT_SIGNAL ( dragStarted ( ) ) ,
TQT_SLOT ( slotAttachmentDragStarted ( ) ) ) ;
mAttachMenu = 0 ;
readConfig ( ) ;
setupStatusBar ( ) ;
setupActions ( ) ;
setupEditor ( ) ;
slotUpdateSignatureAndEncrypionStateIndicators ( ) ;
applyMainWindowSettings ( KMKernel : : config ( ) , " Composer " ) ;
connect ( mEdtSubject , TQT_SIGNAL ( subjectTextSpellChecked ( ) ) ,
TQT_SLOT ( slotSubjectTextSpellChecked ( ) ) ) ;
connect ( mEdtSubject , TQT_SIGNAL ( textChanged ( const TQString & ) ) ,
TQT_SLOT ( slotUpdWinTitle ( const TQString & ) ) ) ;
connect ( mIdentity , TQT_SIGNAL ( identityChanged ( uint ) ) ,
TQT_SLOT ( slotIdentityChanged ( uint ) ) ) ;
connect ( kmkernel - > identityManager ( ) , TQT_SIGNAL ( changed ( uint ) ) ,
TQT_SLOT ( slotIdentityChanged ( uint ) ) ) ;
connect ( mEdtFrom , TQT_SIGNAL ( completionModeChanged ( TDEGlobalSettings : : Completion ) ) ,
TQT_SLOT ( slotCompletionModeChanged ( TDEGlobalSettings : : Completion ) ) ) ;
connect ( kmkernel - > folderMgr ( ) , TQT_SIGNAL ( folderRemoved ( KMFolder * ) ) ,
TQT_SLOT ( slotFolderRemoved ( KMFolder * ) ) ) ;
connect ( kmkernel - > imapFolderMgr ( ) , TQT_SIGNAL ( folderRemoved ( KMFolder * ) ) ,
TQT_SLOT ( slotFolderRemoved ( KMFolder * ) ) ) ;
connect ( kmkernel - > dimapFolderMgr ( ) , TQT_SIGNAL ( folderRemoved ( KMFolder * ) ) ,
TQT_SLOT ( slotFolderRemoved ( KMFolder * ) ) ) ;
connect ( kmkernel , TQT_SIGNAL ( configChanged ( ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotConfigChanged ( ) ) ) ;
connect ( mEditor , TQT_SIGNAL ( spellcheck_done ( int ) ) ,
this , TQT_SLOT ( slotSpellcheckDone ( int ) ) ) ;
connect ( mEditor , TQT_SIGNAL ( attachPNGImageData ( const TQByteArray & ) ) ,
this , TQT_SLOT ( slotAttachPNGImageData ( const TQByteArray & ) ) ) ;
connect ( mEditor , TQT_SIGNAL ( focusChanged ( bool ) ) ,
this , TQT_SLOT ( editorFocusChanged ( bool ) ) ) ;
mMainWidget - > resize ( 480 , 510 ) ;
setCentralWidget ( mMainWidget ) ;
rethinkFields ( ) ;
if ( ! mClassicalRecipients ) {
// This is ugly, but if it isn't called the line edits in the recipients
// editor aren't wide enough until the first resize event comes.
rethinkFields ( ) ;
}
if ( GlobalSettings : : self ( ) - > useExternalEditor ( ) ) {
mEditor - > setUseExternalEditor ( true ) ;
mEditor - > setExternalEditorPath ( GlobalSettings : : self ( ) - > externalEditor ( ) ) ;
}
initAutoSave ( ) ;
slotUpdateSignatureActions ( ) ;
mMsg = 0 ;
if ( aMsg )
setMsg ( aMsg ) ;
fontChanged ( mEditor - > currentFont ( ) ) ; // set toolbar buttons to correct values
mDone = true ;
}
//-----------------------------------------------------------------------------
KMComposeWin : : ~ KMComposeWin ( )
{
writeConfig ( ) ;
if ( mFolder & & mMsg )
{
mAutoDeleteMsg = false ;
mFolder - > addMsg ( mMsg ) ;
// Ensure that the message is correctly and fully parsed
mFolder - > unGetMsg ( mFolder - > count ( ) - 1 ) ;
}
if ( mAutoDeleteMsg ) {
delete mMsg ;
mMsg = 0 ;
}
TQMap < TDEIO : : Job * , atmLoadData > : : Iterator it = mMapAtmLoadData . begin ( ) ;
while ( it ! = mMapAtmLoadData . end ( ) )
{
TDEIO : : Job * job = it . key ( ) ;
mMapAtmLoadData . remove ( it ) ;
job - > kill ( ) ;
it = mMapAtmLoadData . begin ( ) ;
}
deleteAll ( mComposedMessages ) ;
for ( std : : set < KTempDir * > : : iterator it = mTempDirs . begin ( ) ; it ! = mTempDirs . end ( ) ; + + it ) {
delete * it ;
}
}
void KMComposeWin : : setAutoDeleteWindow ( bool f )
{
if ( f )
setWFlags ( getWFlags ( ) | WDestructiveClose ) ;
else
setWFlags ( getWFlags ( ) & ~ WDestructiveClose ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : send ( int how )
{
switch ( how ) {
case 1 :
slotSendNow ( ) ;
break ;
default :
case 0 :
// TODO: find out, what the default send method is and send it this way
case 2 :
slotSendLater ( ) ;
break ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : addAttachmentsAndSend ( const KURL : : List & urls , const TQString & /*comment*/ , int how )
{
if ( urls . isEmpty ( ) )
{
send ( how ) ;
return ;
}
mAttachFilesSend = how ;
mAttachFilesPending = urls ;
connect ( this , TQT_SIGNAL ( attachmentAdded ( const KURL & , bool ) ) , TQT_SLOT ( slotAttachedFile ( const KURL & ) ) ) ;
for ( KURL : : List : : ConstIterator itr = urls . begin ( ) ; itr ! = urls . end ( ) ; + + itr ) {
if ( ! addAttach ( * itr ) )
mAttachFilesPending . remove ( mAttachFilesPending . find ( * itr ) ) ; // only remove one copy of the url
}
if ( mAttachFilesPending . isEmpty ( ) & & mAttachFilesSend = = how )
{
send ( mAttachFilesSend ) ;
mAttachFilesSend = - 1 ;
}
}
void KMComposeWin : : slotAttachedFile ( const KURL & url )
{
if ( mAttachFilesPending . isEmpty ( ) )
return ;
mAttachFilesPending . remove ( mAttachFilesPending . find ( url ) ) ; // only remove one copy of url
if ( mAttachFilesPending . isEmpty ( ) )
{
send ( mAttachFilesSend ) ;
mAttachFilesSend = - 1 ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : addAttachment ( KURL url , TQString /*comment*/ )
{
addAttach ( url ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : addAttachment ( const TQString & name ,
const TQCString & /*cte*/ ,
const TQByteArray & data ,
const TQCString & type ,
const TQCString & subType ,
const TQCString & paramAttr ,
const TQString & paramValue ,
const TQCString & contDisp )
{
if ( ! data . isEmpty ( ) ) {
KMMessagePart * msgPart = new KMMessagePart ;
msgPart - > setName ( name ) ;
if ( type = = " message " & & subType = = " rfc822 " ) {
msgPart - > setMessageBody ( data ) ;
} else {
TQValueList < int > dummy ;
msgPart - > setBodyAndGuessCte ( data , dummy ,
kmkernel - > msgSender ( ) - > sendQuotedPrintable ( ) ) ;
}
msgPart - > setTypeStr ( type ) ;
msgPart - > setSubtypeStr ( subType ) ;
msgPart - > setParameter ( paramAttr , paramValue ) ;
msgPart - > setContentDisposition ( contDisp ) ;
addAttach ( msgPart ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachPNGImageData ( const TQByteArray & image )
{
bool ok ;
TQString attName = KInputDialog : : getText ( " KMail " , i18n ( " Name of the attachment: " ) , TQString ( ) , & ok , this ) ;
if ( ! ok )
return ;
if ( ! attName . lower ( ) . endsWith ( " .png " ) ) attName + = " .png " ;
addAttachment ( attName , " base64 " , image , " image " , " png " , TQCString ( ) , TQString ( ) , TQCString ( ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setBody ( TQString body )
{
mEditor - > setText ( body ) ;
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : event ( TQEvent * e )
{
if ( e - > type ( ) = = TQEvent : : ApplicationPaletteChange )
{
readColorConfig ( ) ;
}
return KMail : : Composer : : event ( e ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : readColorConfig ( void )
{
if ( GlobalSettings : : self ( ) - > useDefaultColors ( ) ) {
mForeColor = TQColor ( kapp - > palette ( ) . active ( ) . text ( ) ) ;
mBackColor = TQColor ( kapp - > palette ( ) . active ( ) . base ( ) ) ;
} else {
mForeColor = GlobalSettings : : self ( ) - > foregroundColor ( ) ;
mBackColor = GlobalSettings : : self ( ) - > backgroundColor ( ) ;
}
// Color setup
mPalette = kapp - > palette ( ) ;
TQColorGroup cgrp = mPalette . active ( ) ;
cgrp . setColor ( TQColorGroup : : Base , mBackColor ) ;
cgrp . setColor ( TQColorGroup : : Text , mForeColor ) ;
mPalette . setDisabled ( cgrp ) ;
mPalette . setActive ( cgrp ) ;
mPalette . setInactive ( cgrp ) ;
mEdtFrom - > setPalette ( mPalette ) ;
mEdtReplyTo - > setPalette ( mPalette ) ;
if ( mClassicalRecipients ) {
mEdtTo - > setPalette ( mPalette ) ;
mEdtCc - > setPalette ( mPalette ) ;
mEdtBcc - > setPalette ( mPalette ) ;
}
mEdtSubject - > setPalette ( mPalette ) ;
mTransport - > setPalette ( mPalette ) ;
mEditor - > setPalette ( mPalette ) ;
mFcc - > setPalette ( mPalette ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : readConfig ( bool reload /* = false */ )
{
mDefCharset = KMMessage : : defaultCharset ( ) ;
mBtnIdentity - > setChecked ( GlobalSettings : : self ( ) - > stickyIdentity ( ) ) ;
if ( mBtnIdentity - > isChecked ( ) ) {
mId = ( GlobalSettings : : self ( ) - > previousIdentity ( ) ! = 0 ) ?
GlobalSettings : : self ( ) - > previousIdentity ( ) : mId ;
}
mBtnFcc - > setChecked ( GlobalSettings : : self ( ) - > stickyFcc ( ) ) ;
mBtnTransport - > setChecked ( GlobalSettings : : self ( ) - > stickyTransport ( ) ) ;
mBtnDictionary - > setChecked ( GlobalSettings : : self ( ) - > stickyDictionary ( ) ) ;
TQStringList transportHistory = GlobalSettings : : self ( ) - > transportHistory ( ) ;
TQString currentTransport = GlobalSettings : : self ( ) - > currentTransport ( ) ;
mEdtFrom - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
mEdtReplyTo - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
if ( mClassicalRecipients ) {
mEdtTo - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
mEdtCc - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
mEdtBcc - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
}
else
mRecipientsEditor - > setCompletionMode ( ( TDEGlobalSettings : : Completion ) GlobalSettings : : self ( ) - > completionMode ( ) ) ;
readColorConfig ( ) ;
if ( GlobalSettings : : self ( ) - > useDefaultFonts ( ) ) {
mBodyFont = TDEGlobalSettings : : generalFont ( ) ;
mFixedFont = TDEGlobalSettings : : fixedFont ( ) ;
} else {
mBodyFont = GlobalSettings : : self ( ) - > composerFont ( ) ;
mFixedFont = GlobalSettings : : self ( ) - > fixedFont ( ) ;
}
slotUpdateFont ( ) ;
mEdtFrom - > setFont ( mBodyFont ) ;
mEdtReplyTo - > setFont ( mBodyFont ) ;
if ( mClassicalRecipients ) {
mEdtTo - > setFont ( mBodyFont ) ;
mEdtCc - > setFont ( mBodyFont ) ;
mEdtBcc - > setFont ( mBodyFont ) ;
}
mEdtSubject - > setFont ( mBodyFont ) ;
if ( ! reload ) {
TQSize siz = GlobalSettings : : self ( ) - > composerSize ( ) ;
if ( siz . width ( ) < 200 ) siz . setWidth ( 200 ) ;
if ( siz . height ( ) < 200 ) siz . setHeight ( 200 ) ;
resize ( siz ) ;
if ( ! GlobalSettings : : self ( ) - > snippetSplitterPosition ( ) . isEmpty ( ) ) {
mSnippetSplitter - > setSizes ( GlobalSettings : : self ( ) - > snippetSplitterPosition ( ) ) ;
} else {
TQValueList < int > defaults ;
defaults < < ( int ) ( width ( ) * 0.8 ) < < ( int ) ( width ( ) * 0.2 ) ;
mSnippetSplitter - > setSizes ( defaults ) ;
}
}
mIdentity - > setCurrentIdentity ( mId ) ;
kdDebug ( 5006 ) < < " KMComposeWin::readConfig. " < < mIdentity - > currentIdentityName ( ) < < endl ;
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - > identityForUoid ( mIdentity - > currentIdentity ( ) ) ;
mTransport - > clear ( ) ;
mTransport - > insertStringList ( KMTransportInfo : : availableTransports ( ) ) ;
while ( transportHistory . count ( ) > ( uint ) GlobalSettings : : self ( ) - > maxTransportEntries ( ) )
transportHistory . remove ( transportHistory . last ( ) ) ;
mTransport - > insertStringList ( transportHistory ) ;
mTransport - > setCurrentText ( GlobalSettings : : self ( ) - > defaultTransport ( ) ) ;
if ( mBtnTransport - > isChecked ( ) ) {
setTransport ( currentTransport ) ;
}
if ( mBtnDictionary - > isChecked ( ) ) {
mDictionaryCombo - > setCurrentByDictionaryName ( GlobalSettings : : self ( ) - > previousDictionary ( ) ) ;
} else {
mDictionaryCombo - > setCurrentByDictionary ( ident . dictionary ( ) ) ;
}
TQString fccName = " " ;
if ( mBtnFcc - > isChecked ( ) ) {
fccName = GlobalSettings : : self ( ) - > previousFcc ( ) ;
} else if ( ! ident . fcc ( ) . isEmpty ( ) ) {
fccName = ident . fcc ( ) ;
}
setFcc ( fccName ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : writeConfig ( void )
{
GlobalSettings : : self ( ) - > setHeaders ( mShowHeaders ) ;
GlobalSettings : : self ( ) - > setStickyFcc ( mBtnFcc - > isChecked ( ) ) ;
if ( ! mIgnoreStickyFields ) {
GlobalSettings : : self ( ) - > setCurrentTransport ( mTransport - > currentText ( ) ) ;
GlobalSettings : : self ( ) - > setStickyTransport ( mBtnTransport - > isChecked ( ) ) ;
GlobalSettings : : self ( ) - > setStickyDictionary ( mBtnDictionary - > isChecked ( ) ) ;
GlobalSettings : : self ( ) - > setStickyIdentity ( mBtnIdentity - > isChecked ( ) ) ;
GlobalSettings : : self ( ) - > setPreviousIdentity ( mIdentity - > currentIdentity ( ) ) ;
}
GlobalSettings : : self ( ) - > setPreviousFcc ( mFcc - > getFolder ( ) - > idString ( ) ) ;
GlobalSettings : : self ( ) - > setPreviousDictionary ( mDictionaryCombo - > currentDictionaryName ( ) ) ;
GlobalSettings : : self ( ) - > setAutoSpellChecking (
mAutoSpellCheckingAction - > isChecked ( ) ) ;
TQStringList transportHistory = GlobalSettings : : self ( ) - > transportHistory ( ) ;
transportHistory . remove ( mTransport - > currentText ( ) ) ;
if ( KMTransportInfo : : availableTransports ( ) . findIndex ( mTransport
- > currentText ( ) ) = = - 1 ) {
transportHistory . prepend ( mTransport - > currentText ( ) ) ;
}
GlobalSettings : : self ( ) - > setTransportHistory ( transportHistory ) ;
GlobalSettings : : self ( ) - > setUseFixedFont ( mFixedFontAction - > isChecked ( ) ) ;
GlobalSettings : : self ( ) - > setUseHtmlMarkup ( mHtmlMarkup ) ;
GlobalSettings : : self ( ) - > setComposerSize ( size ( ) ) ;
GlobalSettings : : self ( ) - > setShowSnippetManager ( mSnippetAction - > isChecked ( ) ) ;
TDEConfigGroupSaver saver ( KMKernel : : config ( ) , " Geometry " ) ;
saveMainWindowSettings ( KMKernel : : config ( ) , " Composer " ) ;
GlobalSettings : : setSnippetSplitterPosition ( mSnippetSplitter - > sizes ( ) ) ;
// make sure config changes are written to disk, cf. bug 127538
GlobalSettings : : self ( ) - > writeConfig ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : autoSaveMessage ( )
{
kdDebug ( 5006 ) < < k_funcinfo < < endl ;
if ( ! mMsg | | mComposer | | mAutoSaveFilename . isEmpty ( ) )
return ;
kdDebug ( 5006 ) < < k_funcinfo < < " autosaving message " < < endl ;
if ( mAutoSaveTimer )
mAutoSaveTimer - > stop ( ) ;
connect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotContinueAutoSave ( ) ) ) ;
// This method is called when KMail crashed, so don't try signing/encryption
// and don't disable controls because it is also called from a timer and
// then the disabling is distracting.
applyChanges ( true , true ) ;
// Don't continue before the applyChanges is done!
}
void KMComposeWin : : slotContinueAutoSave ( )
{
disconnect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotContinueAutoSave ( ) ) ) ;
// Ok, it's done now - continue dead letter saving
if ( mComposedMessages . isEmpty ( ) ) {
kdDebug ( 5006 ) < < " Composing the message failed. " < < endl ;
return ;
}
KMMessage * msg = mComposedMessages . first ( ) ;
if ( ! msg ) // a bit of extra defensiveness
return ;
kdDebug ( 5006 ) < < k_funcinfo < < " opening autoSaveFile " < < mAutoSaveFilename
< < endl ;
const TQString filename =
KMKernel : : localDataPath ( ) + " autosave/cur/ " + mAutoSaveFilename ;
KSaveFile autoSaveFile ( filename , 0600 ) ;
int status = autoSaveFile . status ( ) ;
kdDebug ( 5006 ) < < k_funcinfo < < " autoSaveFile.status() = " < < status < < endl ;
if ( status = = 0 ) { // no error
kdDebug ( 5006 ) < < " autosaving message in " < < filename < < endl ;
int fd = autoSaveFile . handle ( ) ;
const DwString & msgStr = msg - > asDwString ( ) ;
if ( : : write ( fd , msgStr . data ( ) , msgStr . length ( ) ) = = - 1 )
status = errno ;
}
if ( status = = 0 ) {
kdDebug ( 5006 ) < < k_funcinfo < < " closing autoSaveFile " < < endl ;
autoSaveFile . close ( ) ;
mLastAutoSaveErrno = 0 ;
}
else {
kdDebug ( 5006 ) < < k_funcinfo < < " autosaving failed " < < endl ;
autoSaveFile . abort ( ) ;
if ( status ! = mLastAutoSaveErrno ) {
// don't show the same error message twice
KMessageBox : : queuedMessageBox ( 0 , KMessageBox : : Sorry ,
i18n ( " Autosaving the message as %1 "
" failed. \n "
" Reason: %2 " )
. arg ( filename , strerror ( status ) ) ,
i18n ( " Autosaving Failed " ) ) ;
mLastAutoSaveErrno = status ;
}
}
if ( autoSaveInterval ( ) > 0 )
updateAutoSave ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotView ( void )
{
if ( ! mDone )
return ; // otherwise called from rethinkFields during the construction
// which is not the intended behavior
int id ;
//This sucks awfully, but no, I cannot get an activated(int id) from
// actionContainer()
if ( ! TQT_TQOBJECT_CONST ( sender ( ) ) - > isA ( " TDEToggleAction " ) )
return ;
TDEToggleAction * act = ( TDEToggleAction * ) sender ( ) ;
if ( act = = mAllFieldsAction )
id = 0 ;
else if ( act = = mIdentityAction )
id = HDR_IDENTITY ;
else if ( act = = mTransportAction )
id = HDR_TRANSPORT ;
else if ( act = = mFromAction )
id = HDR_FROM ;
else if ( act = = mReplyToAction )
id = HDR_REPLY_TO ;
else if ( act = = mToAction )
id = HDR_TO ;
else if ( act = = mCcAction )
id = HDR_CC ;
else if ( act = = mBccAction )
id = HDR_BCC ;
else if ( act = = mSubjectAction )
id = HDR_SUBJECT ;
else if ( act = = mFccAction )
id = HDR_FCC ;
else if ( act = = mDictionaryAction )
id = HDR_DICTIONARY ;
else
{
id = 0 ;
kdDebug ( 5006 ) < < " Something is wrong (Oh, yeah?) " < < endl ;
return ;
}
// sanders There's a bug here this logic doesn't work if no
// fields are shown and then show all fields is selected.
// Instead of all fields being shown none are.
if ( ! act - > isChecked ( ) )
{
// hide header
if ( id > 0 ) mShowHeaders = mShowHeaders & ~ id ;
else mShowHeaders = abs ( mShowHeaders ) ;
}
else
{
// show header
if ( id > 0 ) mShowHeaders | = id ;
else mShowHeaders = - abs ( mShowHeaders ) ;
}
rethinkFields ( true ) ;
}
int KMComposeWin : : calcColumnWidth ( int which , long allShowing , int width )
{
if ( ( allShowing & which ) = = 0 )
return width ;
TQLabel * w ;
if ( which = = HDR_IDENTITY )
w = mLblIdentity ;
else if ( which = = HDR_DICTIONARY )
w = mDictionaryLabel ;
else if ( which = = HDR_FCC )
w = mLblFcc ;
else if ( which = = HDR_TRANSPORT )
w = mLblTransport ;
else if ( which = = HDR_FROM )
w = mLblFrom ;
else if ( which = = HDR_REPLY_TO )
w = mLblReplyTo ;
else if ( which = = HDR_SUBJECT )
w = mLblSubject ;
else
return width ;
w - > setBuddy ( mEditor ) ; // set dummy so we don't calculate width of '&' for this label.
w - > adjustSize ( ) ;
w - > show ( ) ;
return TQMAX ( width , w - > sizeHint ( ) . width ( ) ) ;
}
void KMComposeWin : : rethinkFields ( bool fromSlot )
{
//This sucks even more but again no ids. sorry (sven)
int mask , row , numRows ;
long showHeaders ;
if ( mShowHeaders < 0 )
showHeaders = HDR_ALL ;
else
showHeaders = mShowHeaders ;
for ( mask = 1 , mNumHeaders = 0 ; mask < = showHeaders ; mask < < = 1 )
if ( ( showHeaders & mask ) ! = 0 ) mNumHeaders + + ;
numRows = mNumHeaders + 1 ;
delete mGrid ;
mGrid = new TQGridLayout ( mHeadersArea , numRows , 3 , KDialogBase : : marginHint ( ) / 2 , KDialogBase : : spacingHint ( ) ) ;
mGrid - > setColStretch ( 0 , 1 ) ;
mGrid - > setColStretch ( 1 , 100 ) ;
mGrid - > setColStretch ( 2 , 1 ) ;
mGrid - > setRowStretch ( mNumHeaders + 1 , 100 ) ;
row = 0 ;
kdDebug ( 5006 ) < < " KMComposeWin::rethinkFields " < < endl ;
if ( mRecipientsEditor )
mLabelWidth = mRecipientsEditor - > setFirstColumnWidth ( 0 ) ;
mLabelWidth = calcColumnWidth ( HDR_IDENTITY , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_DICTIONARY , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_FCC , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_TRANSPORT , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_FROM , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_REPLY_TO , showHeaders , mLabelWidth ) ;
mLabelWidth = calcColumnWidth ( HDR_SUBJECT , showHeaders , mLabelWidth ) ;
if ( ! fromSlot ) mAllFieldsAction - > setChecked ( showHeaders = = HDR_ALL ) ;
if ( ! fromSlot ) mIdentityAction - > setChecked ( abs ( mShowHeaders ) & HDR_IDENTITY ) ;
rethinkHeaderLine ( showHeaders , HDR_IDENTITY , row ,
mLblIdentity , mIdentity , mBtnIdentity ) ;
if ( ! fromSlot ) mDictionaryAction - > setChecked ( abs ( mShowHeaders ) & HDR_DICTIONARY ) ;
rethinkHeaderLine ( showHeaders , HDR_DICTIONARY , row ,
mDictionaryLabel , mDictionaryCombo , mBtnDictionary ) ;
if ( ! fromSlot ) mFccAction - > setChecked ( abs ( mShowHeaders ) & HDR_FCC ) ;
rethinkHeaderLine ( showHeaders , HDR_FCC , row ,
mLblFcc , mFcc , mBtnFcc ) ;
if ( ! fromSlot ) mTransportAction - > setChecked ( abs ( mShowHeaders ) & HDR_TRANSPORT ) ;
rethinkHeaderLine ( showHeaders , HDR_TRANSPORT , row ,
mLblTransport , mTransport , mBtnTransport ) ;
if ( ! fromSlot ) mFromAction - > setChecked ( abs ( mShowHeaders ) & HDR_FROM ) ;
rethinkHeaderLine ( showHeaders , HDR_FROM , row ,
mLblFrom , mEdtFrom /*, mBtnFrom */ ) ;
TQWidget * prevFocus = mEdtFrom ;
if ( ! fromSlot ) mReplyToAction - > setChecked ( abs ( mShowHeaders ) & HDR_REPLY_TO ) ;
rethinkHeaderLine ( showHeaders , HDR_REPLY_TO , row ,
mLblReplyTo , mEdtReplyTo , 0 ) ;
if ( showHeaders & HDR_REPLY_TO ) {
prevFocus = connectFocusMoving ( prevFocus , mEdtReplyTo ) ;
}
if ( mClassicalRecipients ) {
if ( ! fromSlot ) mToAction - > setChecked ( abs ( mShowHeaders ) & HDR_TO ) ;
rethinkHeaderLine ( showHeaders , HDR_TO , row ,
mLblTo , mEdtTo , mBtnTo ,
i18n ( " Primary Recipients " ) ,
i18n ( " <qt>The email addresses you put "
" in this field receive a copy of the email.</qt> " ) ) ;
if ( showHeaders & HDR_TO ) {
prevFocus = connectFocusMoving ( prevFocus , mEdtTo ) ;
}
if ( ! fromSlot ) mCcAction - > setChecked ( abs ( mShowHeaders ) & HDR_CC ) ;
rethinkHeaderLine ( showHeaders , HDR_CC , row ,
mLblCc , mEdtCc , mBtnCc ,
i18n ( " Additional Recipients " ) ,
i18n ( " <qt>The email addresses you put "
" in this field receive a copy of the email. "
" Technically it is the same thing as putting all the "
" addresses in the <b>To:</b> field but differs in "
" that it usually symbolises the receiver of the "
" Carbon Copy (CC) is a listener, not the main "
" recipient.</qt> " ) ) ;
if ( showHeaders & HDR_CC ) {
prevFocus = connectFocusMoving ( prevFocus , mEdtCc ) ;
}
if ( ! fromSlot ) mBccAction - > setChecked ( abs ( mShowHeaders ) & HDR_BCC ) ;
rethinkHeaderLine ( showHeaders , HDR_BCC , row ,
mLblBcc , mEdtBcc , mBtnBcc ,
i18n ( " Hidden Recipients " ) ,
i18n ( " <qt>Essentially the same thing "
" as the <b>Copy To:</b> field but differs in that "
" all other recipients do not see who receives a "
" blind copy.</qt> " ) ) ;
if ( showHeaders & HDR_BCC ) {
prevFocus = connectFocusMoving ( prevFocus , mEdtBcc ) ;
}
} else {
mGrid - > addMultiCellWidget ( mRecipientsEditor , row , row , 0 , 2 ) ;
+ + row ;
if ( showHeaders & HDR_REPLY_TO ) {
connect ( mEdtReplyTo , TQT_SIGNAL ( focusDown ( ) ) , mRecipientsEditor ,
TQT_SLOT ( setFocusTop ( ) ) ) ;
} else {
connect ( mEdtFrom , TQT_SIGNAL ( focusDown ( ) ) , mRecipientsEditor ,
TQT_SLOT ( setFocusTop ( ) ) ) ;
}
if ( showHeaders & HDR_REPLY_TO ) {
connect ( mRecipientsEditor , TQT_SIGNAL ( focusUp ( ) ) , mEdtReplyTo , TQT_SLOT ( setFocus ( ) ) ) ;
} else {
connect ( mRecipientsEditor , TQT_SIGNAL ( focusUp ( ) ) , mEdtFrom , TQT_SLOT ( setFocus ( ) ) ) ;
}
connect ( mRecipientsEditor , TQT_SIGNAL ( focusDown ( ) ) , mEdtSubject ,
TQT_SLOT ( setFocus ( ) ) ) ;
connect ( mEdtSubject , TQT_SIGNAL ( focusUp ( ) ) , mRecipientsEditor ,
TQT_SLOT ( setFocusBottom ( ) ) ) ;
prevFocus = mRecipientsEditor ;
}
if ( ! fromSlot ) mSubjectAction - > setChecked ( abs ( mShowHeaders ) & HDR_SUBJECT ) ;
rethinkHeaderLine ( showHeaders , HDR_SUBJECT , row ,
mLblSubject , mEdtSubject ) ;
connectFocusMoving ( mEdtSubject , mEditor ) ;
assert ( row < = mNumHeaders ) ;
if ( ! mAtmList . isEmpty ( ) )
mAtmListView - > show ( ) ;
else
mAtmListView - > hide ( ) ;
resize ( this - > size ( ) ) ;
repaint ( ) ;
mHeadersArea - > setMaximumHeight ( mHeadersArea - > sizeHint ( ) . height ( ) ) ;
mGrid - > activate ( ) ;
mHeadersArea - > show ( ) ;
slotUpdateAttachActions ( ) ;
mIdentityAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
mDictionaryAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
mTransportAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
mFromAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
if ( mReplyToAction ) mReplyToAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
if ( mToAction ) mToAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
if ( mCcAction ) mCcAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
if ( mBccAction ) mBccAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
mFccAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
mSubjectAction - > setEnabled ( ! mAllFieldsAction - > isChecked ( ) ) ;
if ( mRecipientsEditor )
mRecipientsEditor - > setFirstColumnWidth ( mLabelWidth ) ;
}
TQWidget * KMComposeWin : : connectFocusMoving ( TQWidget * prev , TQWidget * next )
{
connect ( prev , TQT_SIGNAL ( focusDown ( ) ) , next , TQT_SLOT ( setFocus ( ) ) ) ;
connect ( next , TQT_SIGNAL ( focusUp ( ) ) , prev , TQT_SLOT ( setFocus ( ) ) ) ;
return next ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : rethinkHeaderLine ( int aValue , int aMask , int & aRow ,
TQLabel * aLbl ,
TQLineEdit * aEdt , TQPushButton * aBtn ,
const TQString & toolTip , const TQString & whatsThis )
{
if ( aValue & aMask )
{
if ( ! toolTip . isEmpty ( ) )
TQToolTip : : add ( aLbl , toolTip ) ;
if ( ! whatsThis . isEmpty ( ) )
TQWhatsThis : : add ( aLbl , whatsThis ) ;
aLbl - > setFixedWidth ( mLabelWidth ) ;
aLbl - > setBuddy ( aEdt ) ;
mGrid - > addWidget ( aLbl , aRow , 0 ) ;
aEdt - > setBackgroundColor ( mBackColor ) ;
aEdt - > show ( ) ;
if ( aBtn ) {
mGrid - > addWidget ( aEdt , aRow , 1 ) ;
mGrid - > addWidget ( aBtn , aRow , 2 ) ;
aBtn - > show ( ) ;
} else {
mGrid - > addMultiCellWidget ( aEdt , aRow , aRow , 1 , 2 ) ;
}
aRow + + ;
}
else
{
aLbl - > hide ( ) ;
aEdt - > hide ( ) ;
if ( aBtn ) aBtn - > hide ( ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : rethinkHeaderLine ( int aValue , int aMask , int & aRow ,
TQLabel * aLbl ,
TQComboBox * aCbx , TQCheckBox * aChk )
{
if ( aValue & aMask )
{
aLbl - > adjustSize ( ) ;
aLbl - > resize ( ( int ) aLbl - > sizeHint ( ) . width ( ) , aLbl - > sizeHint ( ) . height ( ) + 6 ) ;
aLbl - > setMinimumSize ( aLbl - > size ( ) ) ;
aLbl - > show ( ) ;
aLbl - > setBuddy ( aCbx ) ;
mGrid - > addWidget ( aLbl , aRow , 0 ) ;
aCbx - > show ( ) ;
aCbx - > setMinimumSize ( 100 , aLbl - > height ( ) + 2 ) ;
mGrid - > addWidget ( aCbx , aRow , 1 ) ;
if ( aChk ) {
mGrid - > addWidget ( aChk , aRow , 2 ) ;
aChk - > setFixedSize ( aChk - > sizeHint ( ) . width ( ) , aLbl - > height ( ) ) ;
aChk - > show ( ) ;
}
aRow + + ;
}
else
{
aLbl - > hide ( ) ;
aCbx - > hide ( ) ;
if ( aChk )
aChk - > hide ( ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : getTransportMenu ( )
{
TQStringList availTransports ;
mActNowMenu - > clear ( ) ;
mActLaterMenu - > clear ( ) ;
availTransports = KMail : : TransportManager : : transportNames ( ) ;
TQStringList : : Iterator it ;
int id = 0 ;
for ( it = availTransports . begin ( ) ; it ! = availTransports . end ( ) ; + + it , id + + )
{
mActNowMenu - > insertItem ( ( * it ) . replace ( " & " , " && " ) , id ) ;
mActLaterMenu - > insertItem ( ( * it ) . replace ( " & " , " && " ) , id ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setupActions ( void )
{
TDEActionMenu * actActionNowMenu , * actActionLaterMenu ;
if ( kmkernel - > msgSender ( ) - > sendImmediate ( ) ) //default == send now?
{
//default = send now, alternative = queue
( void ) new TDEAction ( i18n ( " &Send Mail " ) , " mail_send " , CTRL + Key_Return ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSendNow ( ) ) , actionCollection ( ) , " send_default " ) ;
// FIXME: change to mail_send_via icon when this exits.
actActionNowMenu = new TDEActionMenu ( i18n ( " &Send Mail Via " ) , " mail_send " ,
actionCollection ( ) , " send_default_via " ) ;
( void ) new TDEAction ( i18n ( " Send &Later " ) , " queue " , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotSendLater ( ) ) , actionCollection ( ) , " send_alternative " ) ;
actActionLaterMenu = new TDEActionMenu ( i18n ( " Send &Later Via " ) , " queue " ,
actionCollection ( ) , " send_alternative_via " ) ;
}
else //no, default = send later
{
//default = queue, alternative = send now
( void ) new TDEAction ( i18n ( " Send &Later " ) , " queue " ,
CTRL + Key_Return ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSendLater ( ) ) , actionCollection ( ) , " send_default " ) ;
actActionLaterMenu = new TDEActionMenu ( i18n ( " Send &Later Via " ) , " queue " ,
actionCollection ( ) , " send_default_via " ) ;
( void ) new TDEAction ( i18n ( " &Send Mail " ) , " mail_send " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSendNow ( ) ) , actionCollection ( ) , " send_alternative " ) ;
// FIXME: change to mail_send_via icon when this exits.
actActionNowMenu = new TDEActionMenu ( i18n ( " &Send Mail Via " ) , " mail_send " ,
actionCollection ( ) , " send_alternative_via " ) ;
}
// needed for sending "default transport"
actActionNowMenu - > setDelayed ( true ) ;
actActionLaterMenu - > setDelayed ( true ) ;
connect ( actActionNowMenu , TQT_SIGNAL ( activated ( ) ) , this ,
TQT_SLOT ( slotSendNow ( ) ) ) ;
connect ( actActionLaterMenu , TQT_SIGNAL ( activated ( ) ) , this ,
TQT_SLOT ( slotSendLater ( ) ) ) ;
mActNowMenu = actActionNowMenu - > popupMenu ( ) ;
mActLaterMenu = actActionLaterMenu - > popupMenu ( ) ;
connect ( mActNowMenu , TQT_SIGNAL ( activated ( int ) ) , this ,
TQT_SLOT ( slotSendNowVia ( int ) ) ) ;
connect ( mActNowMenu , TQT_SIGNAL ( aboutToShow ( ) ) , this ,
TQT_SLOT ( getTransportMenu ( ) ) ) ;
connect ( mActLaterMenu , TQT_SIGNAL ( activated ( int ) ) , this ,
TQT_SLOT ( slotSendLaterVia ( int ) ) ) ;
connect ( mActLaterMenu , TQT_SIGNAL ( aboutToShow ( ) ) , this ,
TQT_SLOT ( getTransportMenu ( ) ) ) ;
( void ) new TDEAction ( i18n ( " Save as &Draft " ) , " filesave " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSaveDraft ( ) ) ,
actionCollection ( ) , " save_in_drafts " ) ;
( void ) new TDEAction ( i18n ( " Save as &Template " ) , " filesave " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSaveTemplate ( ) ) ,
actionCollection ( ) , " save_in_templates " ) ;
( void ) new TDEAction ( i18n ( " &Insert File... " ) , " fileopen " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotInsertFile ( ) ) ,
actionCollection ( ) , " insert_file " ) ;
mRecentAction = new TDERecentFilesAction ( i18n ( " &Insert File Recent " ) ,
" fileopen " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotInsertRecentFile ( const KURL & ) ) ,
actionCollection ( ) , " insert_file_recent " ) ;
mRecentAction - > loadEntries ( KMKernel : : config ( ) ) ;
( void ) new TDEAction ( i18n ( " &Address Book " ) , " contents " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAddrBook ( ) ) ,
actionCollection ( ) , " addressbook " ) ;
( void ) new TDEAction ( i18n ( " &New Composer " ) , " mail_new " ,
TDEStdAccel : : shortcut ( TDEStdAccel : : New ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotNewComposer ( ) ) ,
actionCollection ( ) , " new_composer " ) ;
( void ) new TDEAction ( i18n ( " New Main &Window " ) , " window_new " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotNewMailReader ( ) ) ,
actionCollection ( ) , " open_mailreader " ) ;
if ( ! mClassicalRecipients ) {
new TDEAction ( i18n ( " Select &Recipients... " ) , CTRL + Key_L , TQT_TQOBJECT ( mRecipientsEditor ) ,
TQT_SLOT ( selectRecipients ( ) ) , actionCollection ( ) , " select_recipients " ) ;
new TDEAction ( i18n ( " Save &Distribution List... " ) , 0 , TQT_TQOBJECT ( mRecipientsEditor ) ,
TQT_SLOT ( saveDistributionList ( ) ) , actionCollection ( ) ,
" save_distribution_list " ) ;
}
//KStdAction::save(TQT_TQOBJECT(this), TQT_SLOT(), actionCollection(), "save_message");
KStdAction : : print ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotPrint ( ) ) , actionCollection ( ) ) ;
KStdAction : : close ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotClose ( ) ) , actionCollection ( ) ) ;
KStdAction : : undo ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotUndo ( ) ) , actionCollection ( ) ) ;
KStdAction : : redo ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotRedo ( ) ) , actionCollection ( ) ) ;
KStdAction : : cut ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotCut ( ) ) , actionCollection ( ) ) ;
KStdAction : : copy ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotCopy ( ) ) , actionCollection ( ) ) ;
KStdAction : : pasteText ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotPasteClipboard ( ) ) , actionCollection ( ) ) ;
KStdAction : : selectAll ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotMarkAll ( ) ) , actionCollection ( ) ) ;
KStdAction : : find ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotFind ( ) ) , actionCollection ( ) ) ;
KStdAction : : findNext ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSearchAgain ( ) ) , actionCollection ( ) ) ;
KStdAction : : replace ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotReplace ( ) ) , actionCollection ( ) ) ;
KStdAction : : spelling ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSpellcheck ( ) ) , actionCollection ( ) , " spellcheck " ) ;
mPasteQuotation = new TDEAction ( i18n ( " Pa&ste as Quotation " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotPasteClipboardAsQuotation ( ) ) ,
actionCollection ( ) , " paste_quoted " ) ;
( void ) new TDEAction ( i18n ( " Paste as Attac&hment " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotPasteClipboardAsAttachment ( ) ) ,
actionCollection ( ) , " paste_att " ) ;
TDEAction * addq = new TDEAction ( i18n ( " Add &Quote Characters " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotAddQuotes ( ) ) , actionCollection ( ) , " tools_quote " ) ;
connect ( mEditor , TQT_SIGNAL ( selectionAvailable ( bool ) ) ,
addq , TQT_SLOT ( setEnabled ( bool ) ) ) ;
TDEAction * remq = new TDEAction ( i18n ( " Re&move Quote Characters " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotRemoveQuotes ( ) ) , actionCollection ( ) , " tools_unquote " ) ;
connect ( mEditor , TQT_SIGNAL ( selectionAvailable ( bool ) ) ,
remq , TQT_SLOT ( setEnabled ( bool ) ) ) ;
( void ) new TDEAction ( i18n ( " Cl&ean Spaces " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotCleanSpace ( ) ) ,
actionCollection ( ) , " clean_spaces " ) ;
mFixedFontAction = new TDEToggleAction ( i18n ( " Use Fi&xed Font " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotUpdateFont ( ) ) , actionCollection ( ) , " toggle_fixedfont " ) ;
mFixedFontAction - > setChecked ( GlobalSettings : : self ( ) - > useFixedFont ( ) ) ;
//these are checkable!!!
mUrgentAction = new TDEToggleAction ( i18n ( " &Urgent " ) , 0 ,
actionCollection ( ) ,
" urgent " ) ;
mRequestMDNAction = new TDEToggleAction ( i18n ( " &Request Disposition Notification " ) , 0 ,
actionCollection ( ) ,
" options_request_mdn " ) ;
mRequestMDNAction - > setChecked ( GlobalSettings : : self ( ) - > requestMDN ( ) ) ;
//----- Message-Encoding Submenu
mEncodingAction = new TDESelectAction ( i18n ( " Se&t Encoding " ) , " charset " ,
0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSetCharset ( ) ) ,
actionCollection ( ) , " charsets " ) ;
mWordWrapAction = new TDEToggleAction ( i18n ( " &Wordwrap " ) , 0 ,
actionCollection ( ) , " wordwrap " ) ;
mWordWrapAction - > setChecked ( GlobalSettings : : self ( ) - > wordWrap ( ) ) ;
connect ( mWordWrapAction , TQT_SIGNAL ( toggled ( bool ) ) , TQT_SLOT ( slotWordWrapToggled ( bool ) ) ) ;
mSnippetAction = new TDEToggleAction ( i18n ( " &Snippets " ) , 0 ,
actionCollection ( ) , " snippets " ) ;
connect ( mSnippetAction , TQT_SIGNAL ( toggled ( bool ) ) , mSnippetWidget , TQT_SLOT ( setShown ( bool ) ) ) ;
mSnippetAction - > setChecked ( GlobalSettings : : self ( ) - > showSnippetManager ( ) ) ;
mAutoSpellCheckingAction =
new TDEToggleAction ( i18n ( " &Automatic Spellchecking " ) , " spellcheck " , 0 ,
actionCollection ( ) , " options_auto_spellchecking " ) ;
const bool spellChecking = GlobalSettings : : self ( ) - > autoSpellChecking ( ) ;
mAutoSpellCheckingAction - > setEnabled ( ! GlobalSettings : : self ( ) - > useExternalEditor ( ) ) ;
mAutoSpellCheckingAction - > setChecked ( ! GlobalSettings : : self ( ) - > useExternalEditor ( ) & & spellChecking ) ;
slotAutoSpellCheckingToggled ( ! GlobalSettings : : self ( ) - > useExternalEditor ( ) & & spellChecking ) ;
connect ( mAutoSpellCheckingAction , TQT_SIGNAL ( toggled ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAutoSpellCheckingToggled ( bool ) ) ) ;
TQStringList encodings = KMMsgBase : : supportedEncodings ( true ) ;
encodings . prepend ( i18n ( " Auto-Detect " ) ) ;
mEncodingAction - > setItems ( encodings ) ;
mEncodingAction - > setCurrentItem ( - 1 ) ;
//these are checkable!!!
markupAction = new TDEToggleAction ( i18n ( " Formatting (HTML) " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotToggleMarkup ( ) ) ,
actionCollection ( ) , " html " ) ;
mAllFieldsAction = new TDEToggleAction ( i18n ( " &All Fields " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_all_fields " ) ;
mIdentityAction = new TDEToggleAction ( i18n ( " &Identity " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_identity " ) ;
mDictionaryAction = new TDEToggleAction ( i18n ( " &Dictionary " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_dictionary " ) ;
mFccAction = new TDEToggleAction ( i18n ( " &Sent-Mail Folder " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_fcc " ) ;
mTransportAction = new TDEToggleAction ( i18n ( " &Mail Transport " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_transport " ) ;
mFromAction = new TDEToggleAction ( i18n ( " &From " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_from " ) ;
mReplyToAction = new TDEToggleAction ( i18n ( " &Reply To " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_reply_to " ) ;
if ( mClassicalRecipients ) {
mToAction = new TDEToggleAction ( i18n ( " &To " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_to " ) ;
mCcAction = new TDEToggleAction ( i18n ( " &CC " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_cc " ) ;
mBccAction = new TDEToggleAction ( i18n ( " &BCC " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_bcc " ) ;
}
mSubjectAction = new TDEToggleAction ( i18n ( " S&ubject " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotView ( ) ) ,
actionCollection ( ) , " show_subject " ) ;
//end of checkable
mAppendSignatureAction = new TDEAction ( i18n ( " Append S&ignature " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotAppendSignature ( ) ) ,
actionCollection ( ) , " append_signature " ) ;
mPrependSignatureAction = new TDEAction ( i18n ( " Prepend S&ignature " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotPrependSignature ( ) ) ,
actionCollection ( ) , " prepend_signature " ) ;
mInsertSignatureAction = new TDEAction ( i18n ( " Insert Signature At C&ursor Position " ) , " edit " , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotInsertSignatureAtCursor ( ) ) ,
actionCollection ( ) , " insert_signature_at_cursor_position " ) ;
mAttachPK = new TDEAction ( i18n ( " Attach &Public Key... " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotInsertPublicKey ( ) ) ,
actionCollection ( ) , " attach_public_key " ) ;
mAttachMPK = new TDEAction ( i18n ( " Attach &My Public Key " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotInsertMyPublicKey ( ) ) ,
actionCollection ( ) , " attach_my_public_key " ) ;
( void ) new TDEAction ( i18n ( " &Attach File... " ) , " attach " ,
0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachFile ( ) ) ,
actionCollection ( ) , " attach " ) ;
mAttachRemoveAction = new TDEAction ( i18n ( " &Remove Attachment " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotAttachRemove ( ) ) ,
actionCollection ( ) , " remove " ) ;
mAttachSaveAction = new TDEAction ( i18n ( " &Save Attachment As... " ) , " filesave " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachSave ( ) ) ,
actionCollection ( ) , " attach_save " ) ;
mAttachPropertiesAction = new TDEAction ( i18n ( " Attachment Pr&operties " ) , 0 , TQT_TQOBJECT ( this ) ,
TQT_SLOT ( slotAttachProperties ( ) ) ,
actionCollection ( ) , " attach_properties " ) ;
setStandardToolBarMenuEnabled ( true ) ;
KStdAction : : keyBindings ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotEditKeys ( ) ) , actionCollection ( ) ) ;
KStdAction : : configureToolbars ( TQT_TQOBJECT ( this ) , TQT_SLOT ( slotEditToolbars ( ) ) , actionCollection ( ) ) ;
KStdAction : : preferences ( kmkernel , TQT_SLOT ( slotShowConfigurationDialog ( ) ) , actionCollection ( ) ) ;
( void ) new TDEAction ( i18n ( " &Spellchecker... " ) , 0 , TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSpellcheckConfig ( ) ) ,
actionCollection ( ) , " setup_spellchecker " ) ;
if ( Kleo : : CryptoBackendFactory : : instance ( ) - > protocol ( " Chiasmus " ) ) {
TDEToggleAction * a = new TDEToggleAction ( i18n ( " Encrypt Message with Chiasmus... " ) ,
" chidecrypted " , 0 , actionCollection ( ) ,
" encrypt_message_chiasmus " ) ;
a - > setCheckedState ( KGuiItem ( i18n ( " Encrypt Message with Chiasmus... " ) , " chiencrypted " ) ) ;
mEncryptChiasmusAction = a ;
connect ( mEncryptChiasmusAction , TQT_SIGNAL ( toggled ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotEncryptChiasmusToggled ( bool ) ) ) ;
} else {
mEncryptChiasmusAction = 0 ;
}
mEncryptAction = new TDEToggleAction ( i18n ( " &Encrypt Message " ) ,
" decrypted " , 0 ,
actionCollection ( ) , " encrypt_message " ) ;
mSignAction = new TDEToggleAction ( i18n ( " &Sign Message " ) ,
" signature " , 0 ,
actionCollection ( ) , " sign_message " ) ;
// get PGP user id for the chosen identity
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - > identityForUoidOrDefault ( mIdentity - > currentIdentity ( ) ) ;
// PENDING(marc): check the uses of this member and split it into
// smime/openpgp and or enc/sign, if necessary:
mLastIdentityHasSigningKey = ! ident . pgpSigningKey ( ) . isEmpty ( ) | | ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
mLastIdentityHasEncryptionKey = ! ident . pgpEncryptionKey ( ) . isEmpty ( ) | | ! ident . smimeEncryptionKey ( ) . isEmpty ( ) ;
mLastEncryptActionState = false ;
mLastSignActionState = GlobalSettings : : self ( ) - > pgpAutoSign ( ) ;
// "Attach public key" is only possible if OpenPGP support is available:
mAttachPK - > setEnabled ( Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) ) ;
// "Attach my public key" is only possible if OpenPGP support is
// available and the user specified his key for the current identity:
mAttachMPK - > setEnabled ( Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) & &
! ident . pgpEncryptionKey ( ) . isEmpty ( ) ) ;
if ( ! Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) & & ! Kleo : : CryptoBackendFactory : : instance ( ) - > smime ( ) ) {
// no crypto whatsoever
mEncryptAction - > setEnabled ( false ) ;
setEncryption ( false ) ;
mSignAction - > setEnabled ( false ) ;
setSigning ( false ) ;
} else {
const bool canOpenPGPSign = Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( )
& & ! ident . pgpSigningKey ( ) . isEmpty ( ) ;
const bool canSMIMESign = Kleo : : CryptoBackendFactory : : instance ( ) - > smime ( )
& & ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
setEncryption ( false ) ;
setSigning ( ( canOpenPGPSign | | canSMIMESign ) & & GlobalSettings : : self ( ) - > pgpAutoSign ( ) ) ;
}
connect ( mEncryptAction , TQT_SIGNAL ( toggled ( bool ) ) ,
TQT_SLOT ( slotEncryptToggled ( bool ) ) ) ;
connect ( mSignAction , TQT_SIGNAL ( toggled ( bool ) ) ,
TQT_SLOT ( slotSignToggled ( bool ) ) ) ;
TQStringList l ;
for ( int i = 0 ; i < numCryptoMessageFormats ; + + i )
l . push_back ( Kleo : : cryptoMessageFormatToLabel ( cryptoMessageFormats [ i ] ) ) ;
mCryptoModuleAction = new TDESelectAction ( i18n ( " &Cryptographic Message Format " ) , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotSelectCryptoModule ( ) ) ,
actionCollection ( ) , " options_select_crypto " ) ;
mCryptoModuleAction - > setItems ( l ) ;
mCryptoModuleAction - > setCurrentItem ( format2cb ( ident . preferredCryptoMessageFormat ( ) ) ) ;
mCryptoModuleAction - > setToolTip ( i18n ( " Select a cryptographic format for this message " ) ) ;
slotSelectCryptoModule ( true /* initialize */ ) ;
TQStringList styleItems ;
styleItems < < i18n ( " Standard " ) ;
styleItems < < i18n ( " Bulleted List (Disc) " ) ;
styleItems < < i18n ( " Bulleted List (Circle) " ) ;
styleItems < < i18n ( " Bulleted List (Square) " ) ;
styleItems < < i18n ( " Ordered List (Decimal) " ) ;
styleItems < < i18n ( " Ordered List (Alpha lower) " ) ;
styleItems < < i18n ( " Ordered List (Alpha upper) " ) ;
listAction = new TDESelectAction ( i18n ( " Select Style " ) , 0 , actionCollection ( ) ,
" text_list " ) ;
listAction - > setItems ( styleItems ) ;
listAction - > setToolTip ( i18n ( " Select a list style " ) ) ;
connect ( listAction , TQT_SIGNAL ( activated ( const TQString & ) ) ,
TQT_SLOT ( slotListAction ( const TQString & ) ) ) ;
fontAction = new TDEFontAction ( " Select Font " , 0 , actionCollection ( ) ,
" text_font " ) ;
fontAction - > setToolTip ( i18n ( " Select a font " ) ) ;
connect ( fontAction , TQT_SIGNAL ( activated ( const TQString & ) ) ,
TQT_SLOT ( slotFontAction ( const TQString & ) ) ) ;
fontSizeAction = new TDEFontSizeAction ( " Select Size " , 0 , actionCollection ( ) ,
" text_size " ) ;
fontSizeAction - > setToolTip ( i18n ( " Select a font size " ) ) ;
connect ( fontSizeAction , TQT_SIGNAL ( fontSizeChanged ( int ) ) ,
TQT_SLOT ( slotSizeAction ( int ) ) ) ;
alignLeftAction = new TDEToggleAction ( i18n ( " Align Left " ) , " text_left " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAlignLeft ( ) ) , actionCollection ( ) ,
" align_left " ) ;
alignLeftAction - > setChecked ( true ) ;
alignRightAction = new TDEToggleAction ( i18n ( " Align Right " ) , " text_right " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAlignRight ( ) ) , actionCollection ( ) ,
" align_right " ) ;
alignCenterAction = new TDEToggleAction ( i18n ( " Align Center " ) , " text_center " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAlignCenter ( ) ) , actionCollection ( ) ,
" align_center " ) ;
textBoldAction = new TDEToggleAction ( i18n ( " &Bold " ) , " text_bold " , CTRL + Key_B ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotTextBold ( ) ) ,
actionCollection ( ) , " text_bold " ) ;
textItalicAction = new TDEToggleAction ( i18n ( " &Italic " ) , " text_italic " , CTRL + Key_I ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotTextItalic ( ) ) ,
actionCollection ( ) , " text_italic " ) ;
textUnderAction = new TDEToggleAction ( i18n ( " &Underline " ) , " text_under " , CTRL + Key_U ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotTextUnder ( ) ) ,
actionCollection ( ) , " text_under " ) ;
actionFormatReset = new TDEAction ( i18n ( " Reset Font Settings " ) , " eraser " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotFormatReset ( ) ) ,
actionCollection ( ) , " format_reset " ) ;
actionFormatColor = new TDEAction ( i18n ( " Text Color... " ) , " colorize " , 0 ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotTextColor ( ) ) ,
actionCollection ( ) , " format_color " ) ;
// editorFocusChanged(false);
createGUI ( " kmcomposerui.rc " ) ;
connect ( toolBar ( " htmlToolBar " ) , TQT_SIGNAL ( visibilityChanged ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( htmlToolBarVisibilityChanged ( bool ) ) ) ;
// In Kontact, this entry would read "Configure Kontact", but bring
// up KMail's config dialog. That's sensible, though, so fix the label.
TDEAction * configureAction = actionCollection ( ) - > action ( " options_configure " ) ;
if ( configureAction )
configureAction - > setText ( i18n ( " Configure KMail... " ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setupStatusBar ( void )
{
statusBar ( ) - > insertItem ( " " , 0 , 1 ) ;
statusBar ( ) - > setItemAlignment ( 0 , AlignLeft | AlignVCenter ) ;
statusBar ( ) - > insertItem ( i18n ( " Spellcheck: %1 " ) . arg ( " " ) , 3 , 0 , true ) ;
statusBar ( ) - > insertItem ( i18n ( " Column: %1 " ) . arg ( " " ) , 2 , 0 , true ) ;
statusBar ( ) - > insertItem ( i18n ( " Line: %1 " ) . arg ( " " ) , 1 , 0 , true ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : updateCursorPosition ( )
{
int col , line ;
TQString temp ;
line = mEditor - > currentLine ( ) ;
col = mEditor - > currentColumn ( ) ;
temp = i18n ( " Line: %1 " ) . arg ( line + 1 ) ;
statusBar ( ) - > changeItem ( temp , 1 ) ;
temp = i18n ( " Column: %1 " ) . arg ( col + 1 ) ;
statusBar ( ) - > changeItem ( temp , 2 ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setupEditor ( void )
{
//TQPopupMenu* menu;
mEditor - > setModified ( false ) ;
TQFontMetrics fm ( mBodyFont ) ;
mEditor - > setTabStopWidth ( fm . width ( TQChar ( ' ' ) ) * 8 ) ;
//mEditor->setFocusPolicy(TQWidget::ClickFocus);
slotWordWrapToggled ( GlobalSettings : : self ( ) - > wordWrap ( ) ) ;
// Font setup
slotUpdateFont ( ) ;
/* installRBPopup() is broken in tdelibs, we should wait for
the new klibtextedit ( dnaber , 2002 - 01 - 01 )
menu = new TQPopupMenu ( this ) ;
//#ifdef BROKEN
menu - > insertItem ( i18n ( " Undo " ) , mEditor ,
TQT_SLOT ( undo ( ) ) , TDEStdAccel : : shortcut ( TDEStdAccel : : Undo ) ) ;
menu - > insertItem ( i18n ( " Redo " ) , mEditor ,
TQT_SLOT ( redo ( ) ) , TDEStdAccel : : shortcut ( TDEStdAccel : : Redo ) ) ;
menu - > insertSeparator ( ) ;
//#endif //BROKEN
menu - > insertItem ( i18n ( " Cut " ) , this , TQT_SLOT ( slotCut ( ) ) ) ;
menu - > insertItem ( i18n ( " Copy " ) , this , TQT_SLOT ( slotCopy ( ) ) ) ;
menu - > insertItem ( i18n ( " Paste " ) , this , TQT_SLOT ( slotPasteClipboard ( ) ) ) ;
menu - > insertItem ( i18n ( " Mark All " ) , this , TQT_SLOT ( slotMarkAll ( ) ) ) ;
menu - > insertSeparator ( ) ;
menu - > insertItem ( i18n ( " Find... " ) , this , TQT_SLOT ( slotFind ( ) ) ) ;
menu - > insertItem ( i18n ( " Replace... " ) , this , TQT_SLOT ( slotReplace ( ) ) ) ;
menu - > insertSeparator ( ) ;
menu - > insertItem ( i18n ( " Fixed Font Widths " ) , this , TQT_SLOT ( slotUpdateFont ( ) ) ) ;
mEditor - > installRBPopup ( menu ) ;
*/
updateCursorPosition ( ) ;
connect ( mEditor , TQT_SIGNAL ( CursorPositionChanged ( ) ) , TQT_SLOT ( updateCursorPosition ( ) ) ) ;
connect ( mEditor , TQT_SIGNAL ( currentFontChanged ( const TQFont & ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( fontChanged ( const TQFont & ) ) ) ;
connect ( mEditor , TQT_SIGNAL ( currentAlignmentChanged ( int ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( alignmentChanged ( int ) ) ) ;
}
//-----------------------------------------------------------------------------
static TQString cleanedUpHeaderString ( const TQString & s )
{
// remove invalid characters from the header strings
TQString res ( s ) ;
res . replace ( ' \r ' , " " ) ;
res . replace ( ' \n ' , " " ) ;
return res . stripWhiteSpace ( ) ;
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : subject ( ) const
{
return cleanedUpHeaderString ( mEdtSubject - > text ( ) ) ;
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : to ( ) const
{
if ( mEdtTo ) {
return cleanedUpHeaderString ( mEdtTo - > text ( ) ) ;
} else if ( mRecipientsEditor ) {
return mRecipientsEditor - > recipientString ( Recipient : : To ) ;
} else {
return TQString ( ) ;
}
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : cc ( ) const
{
if ( mEdtCc & & ! mEdtCc - > isHidden ( ) ) {
return cleanedUpHeaderString ( mEdtCc - > text ( ) ) ;
} else if ( mRecipientsEditor ) {
return mRecipientsEditor - > recipientString ( Recipient : : Cc ) ;
} else {
return TQString ( ) ;
}
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : bcc ( ) const
{
if ( mEdtBcc & & ! mEdtBcc - > isHidden ( ) ) {
return cleanedUpHeaderString ( mEdtBcc - > text ( ) ) ;
} else if ( mRecipientsEditor ) {
return mRecipientsEditor - > recipientString ( Recipient : : Bcc ) ;
} else {
return TQString ( ) ;
}
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : from ( ) const
{
return cleanedUpHeaderString ( mEdtFrom - > text ( ) ) ;
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : replyTo ( ) const
{
if ( mEdtReplyTo ) {
return cleanedUpHeaderString ( mEdtReplyTo - > text ( ) ) ;
} else {
return TQString ( ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : verifyWordWrapLengthIsAdequate ( const TQString & body )
{
int maxLineLength = 0 ;
int curPos ;
int oldPos = 0 ;
if ( mEditor - > TQTextEdit : : wordWrap ( ) = = TQTextEdit : : FixedColumnWidth ) {
for ( curPos = 0 ; curPos < ( int ) body . length ( ) ; + + curPos )
if ( body [ curPos ] = = ' \n ' ) {
if ( ( curPos - oldPos ) > maxLineLength )
maxLineLength = curPos - oldPos ;
oldPos = curPos ;
}
if ( ( curPos - oldPos ) > maxLineLength )
maxLineLength = curPos - oldPos ;
if ( mEditor - > wrapColumnOrWidth ( ) < maxLineLength ) // column
mEditor - > setWrapColumnOrWidth ( maxLineLength ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : decryptOrStripOffCleartextSignature ( TQCString & body )
{
TQPtrList < Kpgp : : Block > pgpBlocks ;
TQStrList nonPgpBlocks ;
if ( Kpgp : : Module : : prepareMessageForDecryption ( body ,
pgpBlocks , nonPgpBlocks ) )
{
// Only decrypt/strip off the signature if there is only one OpenPGP
// block in the message
if ( pgpBlocks . count ( ) = = 1 )
{
Kpgp : : Block * block = pgpBlocks . first ( ) ;
if ( ( block - > type ( ) = = Kpgp : : PgpMessageBlock ) | |
( block - > type ( ) = = Kpgp : : ClearsignedBlock ) )
{
if ( block - > type ( ) = = Kpgp : : PgpMessageBlock )
// try to decrypt this OpenPGP block
block - > decrypt ( ) ;
else
// strip off the signature
block - > verify ( ) ;
body = nonPgpBlocks . first ( )
+ block - > text ( )
+ nonPgpBlocks . last ( ) ;
}
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setTransport ( const TQString & transport )
{
kdDebug ( 5006 ) < < " KMComposeWin::setTransport( \" " < < transport < < " \" ) " < < endl ;
// Don't change the transport combobox if transport is empty
if ( transport . isEmpty ( ) )
return ;
bool transportFound = false ;
for ( int i = 0 ; i < mTransport - > count ( ) ; + + i ) {
if ( mTransport - > text ( i ) = = transport ) {
transportFound = true ;
mTransport - > setCurrentItem ( i ) ;
kdDebug ( 5006 ) < < " transport found, it's no. " < < i < < " in the list " < < endl ;
break ;
}
}
if ( ! transportFound ) { // unknown transport
kdDebug ( 5006 ) < < " unknown transport \" " < < transport < < " \" " < < endl ;
if ( transport . startsWith ( " smtp:// " ) | | transport . startsWith ( " smtps:// " ) | |
transport . startsWith ( " file:// " ) ) {
// set custom transport
mTransport - > setEditText ( transport ) ;
}
else {
// neither known nor custom transport -> use default transport
mTransport - > setCurrentText ( GlobalSettings : : self ( ) - > defaultTransport ( ) ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setMsg ( KMMessage * newMsg , bool mayAutoSign ,
bool allowDecryption , bool isModified )
{
//assert(newMsg!=0);
if ( ! newMsg )
{
kdDebug ( 5006 ) < < " KMComposeWin::setMsg() : newMsg == 0! " < < endl ;
return ;
}
mMsg = newMsg ;
KPIM : : IdentityManager * im = kmkernel - > identityManager ( ) ;
mEdtFrom - > setText ( mMsg - > from ( ) ) ;
mEdtReplyTo - > setText ( mMsg - > replyTo ( ) ) ;
if ( mClassicalRecipients ) {
mEdtTo - > setText ( mMsg - > to ( ) ) ;
mEdtCc - > setText ( mMsg - > cc ( ) ) ;
mEdtBcc - > setText ( mMsg - > bcc ( ) ) ;
} else {
mRecipientsEditor - > setRecipientString ( mMsg - > to ( ) , Recipient : : To ) ;
mRecipientsEditor - > setRecipientString ( mMsg - > cc ( ) , Recipient : : Cc ) ;
mRecipientsEditor - > setRecipientString ( mMsg - > bcc ( ) , Recipient : : Bcc ) ;
mRecipientsEditor - > setFocusBottom ( ) ;
}
mEdtSubject - > setText ( mMsg - > subject ( ) ) ;
const bool stickyIdentity = mBtnIdentity - > isChecked ( ) & & ! mIgnoreStickyFields ;
const bool messageHasIdentity = ! newMsg - > headerField ( " X-KMail-Identity " ) . isEmpty ( ) ;
if ( ! stickyIdentity & & messageHasIdentity )
mId = newMsg - > headerField ( " X-KMail-Identity " ) . stripWhiteSpace ( ) . toUInt ( ) ;
// don't overwrite the header values with identity specific values
// unless the identity is sticky
if ( ! stickyIdentity ) {
disconnect ( mIdentity , TQT_SIGNAL ( identityChanged ( uint ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotIdentityChanged ( uint ) ) ) ;
}
// load the mId into the gui, sticky or not, without emitting
mIdentity - > setCurrentIdentity ( mId ) ;
const uint idToApply = mId ;
if ( ! stickyIdentity ) {
connect ( mIdentity , TQT_SIGNAL ( identityChanged ( uint ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotIdentityChanged ( uint ) ) ) ;
} else {
// load the message's state into the mId, without applying it to the gui
// that's so we can detect that the id changed (because a sticky was set)
// on apply()
if ( messageHasIdentity )
mId = newMsg - > headerField ( " X-KMail-Identity " ) . stripWhiteSpace ( ) . toUInt ( ) ;
else
mId = im - > defaultIdentity ( ) . uoid ( ) ;
}
// manually load the identity's value into the fields; either the one from the
// messge, where appropriate, or the one from the sticky identity. What's in
// mId might have changed meanwhile, thus the save value
slotIdentityChanged ( idToApply ) ;
const KPIM : : Identity & ident = im - > identityForUoid ( mIdentity - > currentIdentity ( ) ) ;
// check for the presence of a DNT header, indicating that MDN's were
// requested
TQString mdnAddr = newMsg - > headerField ( " Disposition-Notification-To " ) ;
mRequestMDNAction - > setChecked ( ( ! mdnAddr . isEmpty ( ) & &
im - > thatIsMe ( mdnAddr ) ) | |
GlobalSettings : : self ( ) - > requestMDN ( ) ) ;
// check for presence of a priority header, indicating urgent mail:
mUrgentAction - > setChecked ( newMsg - > isUrgent ( ) ) ;
if ( ! ident . isXFaceEnabled ( ) | | ident . xface ( ) . isEmpty ( ) )
mMsg - > removeHeaderField ( " X-Face " ) ;
else
{
TQString xface = ident . xface ( ) ;
if ( ! xface . isEmpty ( ) )
{
int numNL = ( xface . length ( ) - 1 ) / 70 ;
for ( int i = numNL ; i > 0 ; - - i )
xface . insert ( i * 70 , " \n \t " ) ;
mMsg - > setHeaderField ( " X-Face " , xface ) ;
}
}
// enable/disable encryption if the message was/wasn't encrypted
switch ( mMsg - > encryptionState ( ) ) {
case KMMsgFullyEncrypted : // fall through
case KMMsgPartiallyEncrypted :
mLastEncryptActionState = true ;
break ;
case KMMsgNotEncrypted :
mLastEncryptActionState = false ;
break ;
default : // nothing
break ;
}
// enable/disable signing if the message was/wasn't signed
switch ( mMsg - > signatureState ( ) ) {
case KMMsgFullySigned : // fall through
case KMMsgPartiallySigned :
mLastSignActionState = true ;
break ;
case KMMsgNotSigned :
mLastSignActionState = false ;
break ;
default : // nothing
break ;
}
// if these headers are present, the state of the message should be overruled
if ( mMsg - > headers ( ) . FindField ( " X-KMail-SignatureActionEnabled " ) )
mLastSignActionState = ( mMsg - > headerField ( " X-KMail-SignatureActionEnabled " ) = = " true " ) ;
if ( mMsg - > headers ( ) . FindField ( " X-KMail-EncryptActionEnabled " ) )
mLastEncryptActionState = ( mMsg - > headerField ( " X-KMail-EncryptActionEnabled " ) = = " true " ) ;
if ( mMsg - > headers ( ) . FindField ( " X-KMail-CryptoMessageFormat " ) )
mCryptoModuleAction - > setCurrentItem ( format2cb ( static_cast < Kleo : : CryptoMessageFormat > (
mMsg - > headerField ( " X-KMail-CryptoMessageFormat " ) . toInt ( ) ) ) ) ;
mLastIdentityHasSigningKey = ! ident . pgpSigningKey ( ) . isEmpty ( ) | | ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
mLastIdentityHasEncryptionKey = ! ident . pgpEncryptionKey ( ) . isEmpty ( ) | | ! ident . smimeEncryptionKey ( ) . isEmpty ( ) ;
if ( Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) | | Kleo : : CryptoBackendFactory : : instance ( ) - > smime ( ) ) {
const bool canOpenPGPSign = Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( )
& & ! ident . pgpSigningKey ( ) . isEmpty ( ) ;
const bool canSMIMESign = Kleo : : CryptoBackendFactory : : instance ( ) - > smime ( )
& & ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
setEncryption ( mLastEncryptActionState ) ;
setSigning ( ( canOpenPGPSign | | canSMIMESign ) & & mLastSignActionState ) ;
}
slotUpdateSignatureAndEncrypionStateIndicators ( ) ;
// "Attach my public key" is only possible if the user uses OpenPGP
// support and he specified his key:
mAttachMPK - > setEnabled ( Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) & &
! ident . pgpEncryptionKey ( ) . isEmpty ( ) ) ;
TQString transport = newMsg - > headerField ( " X-KMail-Transport " ) ;
const bool stickyTransport = mBtnTransport - > isChecked ( ) & & ! mIgnoreStickyFields ;
if ( ! stickyTransport & & ! transport . isEmpty ( ) ) {
setTransport ( transport ) ;
}
// If we are using the default transport, and the originating account name of the original message matches the name of a valid transport, use setTransport() to set it
// See Bug 1239
if ( transport . isEmpty ( ) & & ! mMsg - > originatingAccountName ( ) . isEmpty ( ) ) {
TQString transportCandidate = mMsg - > originatingAccountName ( ) ;
bool transportFound = false ;
for ( int i = 0 ; i < mTransport - > count ( ) ; + + i ) {
if ( mTransport - > text ( i ) = = transportCandidate ) {
transportFound = true ;
setTransport ( transportCandidate ) ;
break ;
}
}
}
if ( ! mBtnFcc - > isChecked ( ) )
{
if ( ! mMsg - > fcc ( ) . isEmpty ( ) )
setFcc ( mMsg - > fcc ( ) ) ;
else
setFcc ( ident . fcc ( ) ) ;
}
const bool stickyDictionary = mBtnDictionary - > isChecked ( ) & & ! mIgnoreStickyFields ;
if ( ! stickyDictionary ) {
mDictionaryCombo - > setCurrentByDictionary ( ident . dictionary ( ) ) ;
}
partNode * root = partNode : : fromMessage ( mMsg ) ;
KMail : : ObjectTreeParser otp ; // all defaults are ok
otp . parseObjectTree ( root ) ;
KMail : : AttachmentCollector ac ;
ac . collectAttachmentsFrom ( root ) ;
for ( std : : vector < partNode * > : : const_iterator it = ac . attachments ( ) . begin ( ) ; it ! = ac . attachments ( ) . end ( ) ; + + it )
addAttach ( new KMMessagePart ( ( * it ) - > msgPart ( ) ) ) ;
mEditor - > setText ( otp . textualContent ( ) ) ;
mCharset = otp . textualContentCharset ( ) ;
if ( partNode * n = root - > findType ( DwMime : : kTypeText , DwMime : : kSubtypeHtml ) )
if ( partNode * p = n - > parentNode ( ) )
if ( p - > hasType ( DwMime : : kTypeMultipart ) & &
p - > hasSubType ( DwMime : : kSubtypeAlternative ) )
if ( mMsg - > headerField ( " X-KMail-Markup " ) = = " true " ) {
toggleMarkup ( true ) ;
// get cte decoded body part
mCharset = n - > msgPart ( ) . charset ( ) ;
TQCString bodyDecoded = n - > msgPart ( ) . bodyDecoded ( ) ;
// respect html part charset
const TQTextCodec * codec = KMMsgBase : : codecForName ( mCharset ) ;
if ( codec ) {
mEditor - > setText ( codec - > toUnicode ( bodyDecoded ) ) ;
} else {
mEditor - > setText ( TQString : : fromLocal8Bit ( bodyDecoded ) ) ;
}
}
if ( mCharset . isEmpty ( ) )
mCharset = mMsg - > charset ( ) ;
if ( mCharset . isEmpty ( ) )
mCharset = mDefCharset ;
setCharset ( mCharset ) ;
/* Handle the special case of non-mime mails */
if ( mMsg - > numBodyParts ( ) = = 0 & & otp . textualContent ( ) . isEmpty ( ) ) {
mCharset = mMsg - > charset ( ) ;
if ( mCharset . isEmpty ( ) | | mCharset = = " default " )
mCharset = mDefCharset ;
TQCString bodyDecoded = mMsg - > bodyDecoded ( ) ;
if ( allowDecryption )
decryptOrStripOffCleartextSignature ( bodyDecoded ) ;
const TQTextCodec * codec = KMMsgBase : : codecForName ( mCharset ) ;
if ( codec ) {
mEditor - > setText ( codec - > toUnicode ( bodyDecoded ) ) ;
} else
mEditor - > setText ( TQString : : fromLocal8Bit ( bodyDecoded ) ) ;
}
# ifdef BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
const int num = mMsg - > numBodyParts ( ) ;
kdDebug ( 5006 ) < < " KMComposeWin::setMsg() mMsg->numBodyParts= "
< < mMsg - > numBodyParts ( ) < < endl ;
if ( num > 0 ) {
KMMessagePart bodyPart ;
int firstAttachment = 0 ;
mMsg - > bodyPart ( 1 , & bodyPart ) ;
if ( bodyPart . typeStr ( ) . lower ( ) = = " text " & &
bodyPart . subtypeStr ( ) . lower ( ) = = " html " ) {
// check whether we are inside a mp/al body part
partNode * root = partNode : : fromMessage ( mMsg ) ;
partNode * node = root - > findType ( DwMime : : kTypeText ,
DwMime : : kSubtypeHtml ) ;
if ( node & & node - > parentNode ( ) & &
node - > parentNode ( ) - > hasType ( DwMime : : kTypeMultipart ) & &
node - > parentNode ( ) - > hasSubType ( DwMime : : kSubtypeAlternative ) ) {
// we have a mp/al body part with a text and an html body
kdDebug ( 5006 ) < < " KMComposeWin::setMsg() : text/html found " < < endl ;
firstAttachment = 2 ;
if ( mMsg - > headerField ( " X-KMail-Markup " ) = = " true " )
toggleMarkup ( true ) ;
}
delete root ; root = 0 ;
}
if ( firstAttachment = = 0 ) {
mMsg - > bodyPart ( 0 , & bodyPart ) ;
if ( bodyPart . typeStr ( ) . lower ( ) = = " text " ) {
// we have a mp/mx body with a text body
kdDebug ( 5006 ) < < " KMComposeWin::setMsg() : text/* found " < < endl ;
firstAttachment = 1 ;
}
}
if ( firstAttachment ! = 0 ) // there's text to show
{
mCharset = bodyPart . charset ( ) ;
if ( mCharset . isEmpty ( ) | | mCharset = = " default " )
mCharset = mDefCharset ;
TQCString bodyDecoded = bodyPart . bodyDecoded ( ) ;
if ( allowDecryption )
decryptOrStripOffCleartextSignature ( bodyDecoded ) ;
// As nobody seems to know the purpose of the following line and
// as it breaks word wrapping of long lines if drafts with attachments
// are opened for editting in the composer (cf. Bug#41102) I comment it
// out. Ingo, 2002-04-21
//verifyWordWrapLengthIsAdequate(bodyDecoded);
const TQTextCodec * codec = KMMsgBase : : codecForName ( mCharset ) ;
if ( codec )
mEditor - > setText ( codec - > toUnicode ( bodyDecoded ) ) ;
else
mEditor - > setText ( TQString : : fromLocal8Bit ( bodyDecoded ) ) ;
//mEditor->insertLine("\n", -1); <-- why ?
} else mEditor - > setText ( " " ) ;
for ( int i = firstAttachment ; i < num ; + + i )
{
KMMessagePart * msgPart = new KMMessagePart ;
mMsg - > bodyPart ( i , msgPart ) ;
TQCString mimeType = msgPart - > typeStr ( ) . lower ( ) + ' / '
+ msgPart - > subtypeStr ( ) . lower ( ) ;
// don't add the detached signature as attachment when editting a
// PGP/MIME signed message
if ( mimeType ! = " application/pgp-signature " ) {
addAttach ( msgPart ) ;
}
}
} else {
mCharset = mMsg - > charset ( ) ;
if ( mCharset . isEmpty ( ) | | mCharset = = " default " )
mCharset = mDefCharset ;
TQCString bodyDecoded = mMsg - > bodyDecoded ( ) ;
if ( allowDecryption )
decryptOrStripOffCleartextSignature ( bodyDecoded ) ;
const TQTextCodec * codec = KMMsgBase : : codecForName ( mCharset ) ;
if ( codec ) {
mEditor - > setText ( codec - > toUnicode ( bodyDecoded ) ) ;
} else
mEditor - > setText ( TQString : : fromLocal8Bit ( bodyDecoded ) ) ;
}
setCharset ( mCharset ) ;
# endif // BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
if ( ( GlobalSettings : : self ( ) - > autoTextSignature ( ) = = " auto " ) & & mayAutoSign ) {
//
// Espen 2000-05-16
// Delay the signature appending. It may start a fileseletor.
// Not user friendy if this modal fileseletor opens before the
// composer.
//
//TQTimer::singleShot( 200, this, TQT_SLOT(slotAppendSignature()) );
if ( GlobalSettings : : self ( ) - > prependSignature ( ) ) {
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( slotPrependSignature ( ) ) ) ;
} else {
TQTimer : : singleShot ( 0 , this , TQT_SLOT ( slotAppendSignature ( ) ) ) ;
}
}
if ( mMsg - > getCursorPos ( ) > 0 ) {
// The message has a cursor position explicitly set, so avoid
// changing it when appending the signature.
mPreserveUserCursorPosition = true ;
}
setModified ( isModified ) ;
// do this even for new messages
mEditor - > setCursorPositionFromStart ( ( unsigned int ) mMsg - > getCursorPos ( ) ) ;
// honor "keep reply in this folder" setting even when the identity is changed later on
mPreventFccOverwrite = ( ! newMsg - > fcc ( ) . isEmpty ( ) & & ident . fcc ( ) ! = newMsg - > fcc ( ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setFcc ( const TQString & idString )
{
// check if the sent-mail folder still exists
if ( ! idString . isEmpty ( ) & & kmkernel - > findFolderById ( idString ) ) {
mFcc - > setFolder ( idString ) ;
} else {
mFcc - > setFolder ( kmkernel - > sentFolder ( ) ) ;
}
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : isModified ( ) const
{
return ( mEditor - > isModified ( ) | |
mEdtFrom - > edited ( ) | |
( mEdtReplyTo & & mEdtReplyTo - > edited ( ) ) | |
( mEdtTo & & mEdtTo - > edited ( ) ) | |
( mEdtCc & & mEdtCc - > edited ( ) ) | |
( mEdtBcc & & mEdtBcc - > edited ( ) ) | |
( mRecipientsEditor & & mRecipientsEditor - > isModified ( ) ) | |
mEdtSubject - > edited ( ) | |
mAtmModified | |
( mTransport - > lineEdit ( ) & & mTransport - > lineEdit ( ) - > edited ( ) ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setModified ( bool modified )
{
mEditor - > setModified ( modified ) ;
if ( ! modified ) {
mEdtFrom - > setEdited ( false ) ;
if ( mEdtReplyTo ) mEdtReplyTo - > setEdited ( false ) ;
if ( mEdtTo ) mEdtTo - > setEdited ( false ) ;
if ( mEdtCc ) mEdtCc - > setEdited ( false ) ;
if ( mEdtBcc ) mEdtBcc - > setEdited ( false ) ;
if ( mRecipientsEditor ) mRecipientsEditor - > clearModified ( ) ;
mEdtSubject - > setEdited ( false ) ;
mAtmModified = false ;
if ( mTransport - > lineEdit ( ) )
mTransport - > lineEdit ( ) - > setEdited ( false ) ;
}
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : queryClose ( )
{
if ( ! mEditor - > checkExternalEditorFinished ( ) )
return false ;
if ( kmkernel - > shuttingDown ( ) | | kapp - > sessionSaving ( ) )
return true ;
if ( mComposer & & mComposer - > isPerformingSignOperation ( ) ) // since the non-gpg-agent gpg plugin gets a passphrase using TQDialog::exec()
return false ; // the user can try to close the window, which destroys mComposer mid-call.
if ( isModified ( ) ) {
bool istemplate = ( mFolder ! = 0 & & mFolder - > isTemplates ( ) ) ;
const TQString savebut = ( istemplate ?
i18n ( " Re&save as Template " ) :
i18n ( " &Save as Draft " ) ) ;
const TQString savetext = ( istemplate ?
i18n ( " Resave this message in the Templates folder. "
" It can then be used at a later time. " ) :
i18n ( " Save this message in the Drafts folder. "
" It can then be edited and sent at a later time. " ) ) ;
const int rc = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " Do you want to save the message for later or discard it? " ) ,
i18n ( " Close Composer " ) ,
KGuiItem ( savebut , " filesave " , TQString ( ) , savetext ) ,
KStdGuiItem : : discard ( ) ) ;
if ( rc = = KMessageBox : : Cancel )
return false ;
else if ( rc = = KMessageBox : : Yes ) {
// doSend will close the window. Just return false from this method
if ( istemplate ) {
slotSaveTemplate ( ) ;
} else {
slotSaveDraft ( ) ;
}
return false ;
}
}
cleanupAutoSave ( ) ;
return true ;
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : userForgotAttachment ( )
{
bool checkForForgottenAttachments =
mCheckForForgottenAttachments & & GlobalSettings : : self ( ) - > showForgottenAttachmentWarning ( ) ;
if ( ! checkForForgottenAttachments | | ( mAtmList . count ( ) > 0 ) )
return false ;
TQStringList attachWordsList = GlobalSettings : : self ( ) - > attachmentKeywords ( ) ;
if ( attachWordsList . isEmpty ( ) ) {
// default value (FIXME: this is duplicated in configuredialog.cpp)
attachWordsList < < TQString : : fromLatin1 ( " attachment " )
< < TQString : : fromLatin1 ( " attached " ) ;
if ( TQString : : fromLatin1 ( " attachment " ) ! = i18n ( " attachment " ) )
attachWordsList < < i18n ( " attachment " ) ;
if ( TQString : : fromLatin1 ( " attached " ) ! = i18n ( " attached " ) )
attachWordsList < < i18n ( " attached " ) ;
}
TQRegExp rx ( TQString : : fromLatin1 ( " \\ b " ) +
attachWordsList . join ( " \\ b| \\ b " ) +
TQString : : fromLatin1 ( " \\ b " ) ) ;
rx . setCaseSensitive ( false ) ;
bool gotMatch = false ;
// check whether the subject contains one of the attachment key words
// unless the message is a reply or a forwarded message
TQString subj = subject ( ) ;
gotMatch = ( KMMessage : : stripOffPrefixes ( subj ) = = subj )
& & ( rx . search ( subj ) > = 0 ) ;
if ( ! gotMatch ) {
// check whether the non-quoted text contains one of the attachment key
// words
TQRegExp quotationRx ( " ^([ \\ t]*([|>:}#]|[A-Za-z]+>) ) + " ) ;
for ( int i = 0 ; i < mEditor - > numLines ( ) ; + + i ) {
TQString line = mEditor - > textLine ( i ) ;
gotMatch = ( quotationRx . search ( line ) < 0 )
& & ( rx . search ( line ) > = 0 ) ;
if ( gotMatch )
break ;
}
}
if ( ! gotMatch )
return false ;
int rc = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " The message you have composed seems to refer to an "
" attached file but you have not attached anything. \n "
" Do you want to attach a file to your message? " ) ,
i18n ( " File Attachment Reminder " ) ,
i18n ( " &Attach File... " ) ,
i18n ( " &Send as Is " ) ) ;
if ( rc = = KMessageBox : : Cancel )
return true ;
if ( rc = = KMessageBox : : Yes ) {
slotAttachFile ( ) ;
//preceed with editing
return true ;
}
return false ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : applyChanges ( bool dontSignNorEncrypt , bool dontDisable )
{
kdDebug ( 5006 ) < < " entering KMComposeWin::applyChanges " < < endl ;
if ( ! mMsg | | mComposer ) {
kdDebug ( 5006 ) < < " KMComposeWin::applyChanges() : mMsg == 0! \n " < < endl ;
emit applyChangesDone ( false ) ;
return ;
}
// Make new job and execute it
mComposer = new MessageComposer ( this ) ;
connect ( mComposer , TQT_SIGNAL ( done ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotComposerDone ( bool ) ) ) ;
// TODO: Add a cancel button for the following operations?
// Disable any input to the window, so that we have a snapshot of the
// composed stuff
if ( ! dontDisable ) setEnabled ( false ) ;
// apply the current state to the composer and let it do it's thing
mComposer - > setDisableBreaking ( mDisableBreaking ) ; // FIXME
mComposer - > applyChanges ( dontSignNorEncrypt ) ;
}
void KMComposeWin : : slotComposerDone ( bool rc )
{
deleteAll ( mComposedMessages ) ;
mComposedMessages = mComposer - > composedMessageList ( ) ;
emit applyChangesDone ( rc ) ;
delete mComposer ;
mComposer = 0 ;
// re-enable the composewin, the messsage composition is now done
setEnabled ( true ) ;
}
const KPIM : : Identity & KMComposeWin : : identity ( ) const {
return kmkernel - > identityManager ( ) - > identityForUoidOrDefault ( mIdentity - > currentIdentity ( ) ) ;
}
uint KMComposeWin : : identityUid ( ) const {
return mIdentity - > currentIdentity ( ) ;
}
Kleo : : CryptoMessageFormat KMComposeWin : : cryptoMessageFormat ( ) const {
if ( ! mCryptoModuleAction )
return Kleo : : AutoFormat ;
return cb2format ( mCryptoModuleAction - > currentItem ( ) ) ;
}
bool KMComposeWin : : encryptToSelf ( ) const {
// return !Kpgp::Module::getKpgp() || Kpgp::Module::getKpgp()->encryptToSelf();
TDEConfigGroup group ( KMKernel : : config ( ) , " Composer " ) ;
return group . readBoolEntry ( " crypto-encrypt-to-self " , true ) ;
}
bool KMComposeWin : : queryExit ( )
{
return true ;
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : addAttach ( const KURL aUrl )
{
if ( ! aUrl . isValid ( ) ) {
KMessageBox : : sorry ( this , i18n ( " <qt><p>KMail could not recognize the location of the attachment (%1);</p> "
" <p>you have to specify the full path if you wish to attach a file.</p></qt> " )
. arg ( aUrl . prettyURL ( ) ) ) ;
return false ;
}
const int maxAttachmentSize = GlobalSettings : : maximumAttachmentSize ( ) ;
const uint maximumAttachmentSizeInByte = maxAttachmentSize * 1024 * 1024 ;
if ( aUrl . isLocalFile ( ) & & TQFileInfo ( aUrl . pathOrURL ( ) ) . size ( ) > maximumAttachmentSizeInByte ) {
KMessageBox : : sorry ( this , i18n ( " <qt><p>Your administrator has disallowed attaching files bigger than %1 MB.</p> " ) . arg ( maxAttachmentSize ) ) ;
return false ;
}
TDEIO : : TransferJob * job = TDEIO : : get ( aUrl ) ;
TDEIO : : Scheduler : : scheduleJob ( job ) ;
atmLoadData ld ;
ld . url = aUrl ;
ld . data = TQByteArray ( ) ;
ld . insert = false ;
if ( ! aUrl . fileEncoding ( ) . isEmpty ( ) )
ld . encoding = aUrl . fileEncoding ( ) . latin1 ( ) ;
mMapAtmLoadData . insert ( job , ld ) ;
mAttachJobs [ job ] = aUrl ;
connect ( job , TQT_SIGNAL ( result ( TDEIO : : Job * ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachFileResult ( TDEIO : : Job * ) ) ) ;
connect ( job , TQT_SIGNAL ( data ( TDEIO : : Job * , const TQByteArray & ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachFileData ( TDEIO : : Job * , const TQByteArray & ) ) ) ;
return true ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : addAttach ( const KMMessagePart * msgPart )
{
mAtmList . append ( msgPart ) ;
// show the attachment listbox if it does not up to now
if ( mAtmList . count ( ) = = 1 )
{
mAtmListView - > resize ( mAtmListView - > width ( ) , 50 ) ;
mAtmListView - > show ( ) ;
resize ( size ( ) ) ;
}
// add a line in the attachment listbox
KMAtmListViewItem * lvi = new KMAtmListViewItem ( mAtmListView ) ;
msgPartToItem ( msgPart , lvi ) ;
mAtmItemList . append ( lvi ) ;
// the Attach file job has finished, so the possibly present tmp dir can be deleted now.
if ( mTempDir ! = 0 ) {
delete mTempDir ;
mTempDir = 0 ;
}
connect ( lvi , TQT_SIGNAL ( compress ( int ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( compressAttach ( int ) ) ) ;
connect ( lvi , TQT_SIGNAL ( uncompress ( int ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( uncompressAttach ( int ) ) ) ;
slotUpdateAttachActions ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotUpdateAttachActions ( )
{
int selectedCount = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it ) {
if ( ( * it ) - > isSelected ( ) ) {
+ + selectedCount ;
}
}
mAttachRemoveAction - > setEnabled ( selectedCount > = 1 ) ;
mAttachSaveAction - > setEnabled ( selectedCount = = 1 ) ;
mAttachPropertiesAction - > setEnabled ( selectedCount = = 1 ) ;
}
//-----------------------------------------------------------------------------
TQString KMComposeWin : : prettyMimeType ( const TQString & type )
{
TQString t = type . lower ( ) ;
KServiceType : : Ptr st = KServiceType : : serviceType ( t ) ;
return st ? st - > comment ( ) : t ;
}
void KMComposeWin : : msgPartToItem ( const KMMessagePart * msgPart ,
KMAtmListViewItem * lvi , bool loadDefaults )
{
assert ( msgPart ! = 0 ) ;
if ( ! msgPart - > fileName ( ) . isEmpty ( ) )
lvi - > setText ( 0 , msgPart - > fileName ( ) ) ;
else
lvi - > setText ( 0 , msgPart - > name ( ) ) ;
lvi - > setText ( 1 , TDEIO : : convertSize ( msgPart - > decodedSize ( ) ) ) ;
lvi - > setText ( 2 , msgPart - > contentTransferEncodingStr ( ) ) ;
lvi - > setText ( 3 , prettyMimeType ( msgPart - > typeStr ( ) + " / " + msgPart - > subtypeStr ( ) ) ) ;
lvi - > setAttachmentSize ( msgPart - > decodedSize ( ) ) ;
if ( loadDefaults ) {
if ( canSignEncryptAttachments ( ) ) {
lvi - > enableCryptoCBs ( true ) ;
lvi - > setEncrypt ( mEncryptAction - > isChecked ( ) ) ;
lvi - > setSign ( mSignAction - > isChecked ( ) ) ;
} else {
lvi - > enableCryptoCBs ( false ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : removeAttach ( const TQString & aUrl )
{
int idx ;
KMMessagePart * msgPart ;
for ( idx = 0 , msgPart = mAtmList . first ( ) ; msgPart ;
msgPart = mAtmList . next ( ) , idx + + ) {
if ( msgPart - > name ( ) = = aUrl ) {
removeAttach ( idx ) ;
return ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : removeAttach ( int idx )
{
mAtmModified = true ;
KMAtmListViewItem * item = static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( idx ) ) ;
if ( item - > itemBelow ( ) )
mAtmSelectNew = item - > itemBelow ( ) ;
else if ( item - > itemAbove ( ) )
mAtmSelectNew = item - > itemAbove ( ) ;
mAtmList . remove ( idx ) ;
delete mAtmItemList . take ( idx ) ;
if ( mAtmList . isEmpty ( ) )
{
mAtmListView - > hide ( ) ;
mAtmListView - > setMinimumSize ( 0 , 0 ) ;
resize ( size ( ) ) ;
}
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : encryptFlagOfAttachment ( int idx )
{
return ( int ) ( mAtmItemList . count ( ) ) > idx
? static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( idx ) ) - > isEncrypt ( )
: false ;
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : signFlagOfAttachment ( int idx )
{
return ( int ) ( mAtmItemList . count ( ) ) > idx
? ( ( KMAtmListViewItem * ) ( mAtmItemList . at ( idx ) ) ) - > isSign ( )
: false ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : addrBookSelInto ( )
{
if ( mClassicalRecipients ) {
if ( GlobalSettings : : self ( ) - > addresseeSelectorType ( ) = =
GlobalSettings : : EnumAddresseeSelectorType : : New ) {
addrBookSelIntoNew ( ) ;
} else {
addrBookSelIntoOld ( ) ;
}
} else {
kdWarning ( ) < < " To be implemented: call recipients picker. " < < endl ;
}
}
void KMComposeWin : : addrBookSelIntoOld ( )
{
AddressesDialog dlg ( this ) ;
TQString txt ;
TQStringList lst ;
txt = to ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
dlg . setSelectedTo ( lst ) ;
}
txt = mEdtCc - > text ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
dlg . setSelectedCC ( lst ) ;
}
txt = mEdtBcc - > text ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
dlg . setSelectedBCC ( lst ) ;
}
dlg . setRecentAddresses ( RecentAddresses : : self ( KMKernel : : config ( ) ) - > tdeabcAddresses ( ) ) ;
if ( dlg . exec ( ) = = TQDialog : : Rejected ) return ;
mEdtTo - > setText ( dlg . to ( ) . join ( " , " ) ) ;
mEdtTo - > setEdited ( true ) ;
mEdtCc - > setText ( dlg . cc ( ) . join ( " , " ) ) ;
mEdtCc - > setEdited ( true ) ;
mEdtBcc - > setText ( dlg . bcc ( ) . join ( " , " ) ) ;
mEdtBcc - > setEdited ( true ) ;
//Make sure BCC field is shown if needed
if ( ! mEdtBcc - > text ( ) . isEmpty ( ) ) {
mShowHeaders | = HDR_BCC ;
rethinkFields ( false ) ;
}
}
void KMComposeWin : : addrBookSelIntoNew ( )
{
AddresseeEmailSelection selection ;
AddresseeSelectorDialog dlg ( & selection ) ;
TQString txt ;
TQStringList lst ;
txt = to ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
selection . setSelectedTo ( lst ) ;
}
txt = mEdtCc - > text ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
selection . setSelectedCC ( lst ) ;
}
txt = mEdtBcc - > text ( ) ;
if ( ! txt . isEmpty ( ) ) {
lst = KPIM : : splitEmailAddrList ( txt ) ;
selection . setSelectedBCC ( lst ) ;
}
if ( dlg . exec ( ) = = TQDialog : : Rejected ) return ;
TQStringList list = selection . to ( ) + selection . toDistributionLists ( ) ;
mEdtTo - > setText ( list . join ( " , " ) ) ;
mEdtTo - > setEdited ( true ) ;
list = selection . cc ( ) + selection . ccDistributionLists ( ) ;
mEdtCc - > setText ( list . join ( " , " ) ) ;
mEdtCc - > setEdited ( true ) ;
list = selection . bcc ( ) + selection . bccDistributionLists ( ) ;
mEdtBcc - > setText ( list . join ( " , " ) ) ;
mEdtBcc - > setEdited ( true ) ;
//Make sure BCC field is shown if needed
if ( ! mEdtBcc - > text ( ) . isEmpty ( ) ) {
mShowHeaders | = HDR_BCC ;
rethinkFields ( false ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setCharset ( const TQCString & aCharset , bool forceDefault )
{
if ( ( forceDefault & & GlobalSettings : : self ( ) - > forceReplyCharset ( ) ) | | aCharset . isEmpty ( ) )
mCharset = mDefCharset ;
else
mCharset = aCharset . lower ( ) ;
if ( mCharset . isEmpty ( ) | | mCharset = = " default " )
mCharset = mDefCharset ;
if ( mAutoCharset )
{
mEncodingAction - > setCurrentItem ( 0 ) ;
return ;
}
TQStringList encodings = mEncodingAction - > items ( ) ;
int i = 0 ;
bool charsetFound = false ;
for ( TQStringList : : Iterator it = encodings . begin ( ) ; it ! = encodings . end ( ) ;
+ + it , i + + )
{
if ( i > 0 & & ( ( mCharset = = " us-ascii " & & i = = 1 ) | |
( i ! = 1 & & TDEGlobal : : charsets ( ) - > codecForName (
TDEGlobal : : charsets ( ) - > encodingForName ( * it ) )
= = TDEGlobal : : charsets ( ) - > codecForName ( mCharset ) ) ) )
{
mEncodingAction - > setCurrentItem ( i ) ;
slotSetCharset ( ) ;
charsetFound = true ;
break ;
}
}
if ( ! aCharset . isEmpty ( ) & & ! charsetFound ) setCharset ( " " , true ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAddrBook ( )
{
KAddrBookExternal : : openAddressBook ( this ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAddrBookFrom ( )
{
addrBookSelInto ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAddrBookReplyTo ( )
{
addrBookSelInto ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAddrBookTo ( )
{
addrBookSelInto ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachFile ( )
{
// Create File Dialog and return selected file(s)
// We will not care about any permissions, existence or whatsoever in
// this function.
// Handle the case where the last savedir is gone. kolab/issue4057
TQString recent ;
KURL recentURL = KFileDialog : : getStartURL ( TQString ( ) , recent ) ;
if ( ! recentURL . url ( ) . isEmpty ( ) & &
! TDEIO : : NetAccess : : exists ( recentURL , true , this ) ) {
recentURL = KURL ( TQDir : : homeDirPath ( ) ) ;
}
KFileDialog fdlg ( recentURL . url ( ) , TQString ( ) , this , 0 , true ) ;
fdlg . setOperationMode ( KFileDialog : : Other ) ;
fdlg . setCaption ( i18n ( " Attach File " ) ) ;
fdlg . okButton ( ) - > setGuiItem ( KGuiItem ( i18n ( " &Attach " ) , " fileopen " ) ) ;
fdlg . setMode ( KFile : : Files ) ;
fdlg . exec ( ) ;
KURL : : List files = fdlg . selectedURLs ( ) ;
for ( KURL : : List : : Iterator it = files . begin ( ) ; it ! = files . end ( ) ; + + it )
addAttach ( * it ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachFileData ( TDEIO : : Job * job , const TQByteArray & data )
{
TQMap < TDEIO : : Job * , atmLoadData > : : Iterator it = mMapAtmLoadData . find ( job ) ;
assert ( it ! = mMapAtmLoadData . end ( ) ) ;
TQBuffer buff ( ( * it ) . data ) ;
buff . open ( IO_WriteOnly | IO_Append ) ;
buff . writeBlock ( data . data ( ) , data . size ( ) ) ;
buff . close ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachFileResult ( TDEIO : : Job * job )
{
TQMap < TDEIO : : Job * , atmLoadData > : : Iterator it = mMapAtmLoadData . find ( job ) ;
assert ( it ! = mMapAtmLoadData . end ( ) ) ;
KURL attachURL ;
TQMap < TDEIO : : Job * , KURL > : : iterator jit = mAttachJobs . find ( job ) ;
bool attachURLfound = ( jit ! = mAttachJobs . end ( ) ) ;
if ( attachURLfound )
{
attachURL = jit . data ( ) ;
mAttachJobs . remove ( jit ) ;
}
if ( job - > error ( ) )
{
mMapAtmLoadData . remove ( it ) ;
job - > showErrorDialog ( ) ;
if ( attachURLfound )
emit attachmentAdded ( attachURL , false ) ;
return ;
}
if ( ( * it ) . insert )
{
( * it ) . data . resize ( ( * it ) . data . size ( ) + 1 ) ;
( * it ) . data [ ( * it ) . data . size ( ) - 1 ] = ' \0 ' ;
if ( const TQTextCodec * codec = TDEGlobal : : charsets ( ) - > codecForName ( ( * it ) . encoding ) )
mEditor - > insert ( codec - > toUnicode ( ( * it ) . data ) ) ;
else
mEditor - > insert ( TQString : : fromLocal8Bit ( ( * it ) . data ) ) ;
mMapAtmLoadData . remove ( it ) ;
if ( attachURLfound )
emit attachmentAdded ( attachURL , true ) ;
return ;
}
TQCString partCharset ;
if ( ! ( * it ) . url . fileEncoding ( ) . isEmpty ( ) ) {
partCharset = TQCString ( ( * it ) . url . fileEncoding ( ) . latin1 ( ) ) ;
} else {
EncodingDetector ed ;
TDELocale * loc = TDEGlobal : : locale ( ) ;
ed . setAutoDetectLanguage ( EncodingDetector : : scriptForLanguageCode ( loc - > language ( ) ) ) ;
ed . analyze ( ( * it ) . data ) ;
partCharset = ed . encoding ( ) ;
if ( partCharset . isEmpty ( ) ) //shouldn't happen
partCharset = mCharset ;
}
KMMessagePart * msgPart ;
KCursorSaver busy ( KBusyPtr : : busy ( ) ) ;
TQString name ( ( * it ) . url . fileName ( ) ) ;
// ask the job for the mime type of the file
TQString mimeType = static_cast < TDEIO : : MimetypeJob * > ( job ) - > mimetype ( ) ;
if ( name . isEmpty ( ) ) {
// URL ends with '/' (e.g. http://www.kde.org/)
// guess a reasonable filename
if ( mimeType = = " text/html " )
name = " index.html " ;
else {
// try to determine a reasonable extension
TQStringList patterns ( KMimeType : : mimeType ( mimeType ) - > patterns ( ) ) ;
TQString ext ;
if ( ! patterns . isEmpty ( ) ) {
ext = patterns [ 0 ] ;
int i = ext . findRev ( ' . ' ) ;
if ( i = = - 1 )
ext . prepend ( ' . ' ) ;
else if ( i > 0 )
ext = ext . mid ( i ) ;
}
name = TQString ( " unknown " ) + = ext ;
}
}
name . truncate ( 256 ) ; // is this needed?
TQCString encoding = KMMsgBase : : autoDetectCharset ( partCharset ,
KMMessage : : preferredCharsets ( ) , name ) ;
if ( encoding . isEmpty ( ) )
encoding = " utf-8 " ;
TQCString encName ;
if ( GlobalSettings : : self ( ) - > outlookCompatibleAttachments ( ) )
encName = KMMsgBase : : encodeRFC2047String ( name , encoding ) ;
else
encName = KMMsgBase : : encodeRFC2231String ( name , encoding ) ;
bool RFC2231encoded = false ;
if ( ! GlobalSettings : : self ( ) - > outlookCompatibleAttachments ( ) )
RFC2231encoded = name ! = TQString ( encName ) ;
// create message part
msgPart = new KMMessagePart ;
msgPart - > setName ( name ) ;
TQValueList < int > allowedCTEs ;
if ( mimeType = = " message/rfc822 " ) {
msgPart - > setMessageBody ( ( * it ) . data ) ;
allowedCTEs < < DwMime : : kCte7bit ;
allowedCTEs < < DwMime : : kCte8bit ;
} else {
msgPart - > setBodyAndGuessCte ( ( * it ) . data , allowedCTEs ,
! kmkernel - > msgSender ( ) - > sendQuotedPrintable ( ) ) ;
kdDebug ( 5006 ) < < " autodetected cte: " < < msgPart - > cteStr ( ) < < endl ;
}
int slash = mimeType . find ( ' / ' ) ;
if ( slash = = - 1 )
slash = mimeType . length ( ) ;
msgPart - > setTypeStr ( mimeType . left ( slash ) . latin1 ( ) ) ;
msgPart - > setSubtypeStr ( mimeType . mid ( slash + 1 ) . latin1 ( ) ) ;
msgPart - > setContentDisposition ( TQCString ( " attachment; \n \t filename " )
+ ( RFC2231encoded ? " *= " + encName : " = \" " + encName + ' " ' ) ) ;
mMapAtmLoadData . remove ( it ) ;
if ( msgPart - > typeStr ( ) . lower ( ) = = " text " ) {
msgPart - > setCharset ( partCharset ) ;
}
// show message part dialog, if not configured away (default):
TDEConfigGroup composer ( KMKernel : : config ( ) , " Composer " ) ;
if ( GlobalSettings : : self ( ) - > showMessagePartDialogOnAttach ( ) ) {
const KCursorSaver saver ( TQCursor : : ArrowCursor ) ;
KMMsgPartDialogCompat dlg ( mMainWidget ) ;
int encodings = 0 ;
for ( TQValueListConstIterator < int > it = allowedCTEs . begin ( ) ;
it ! = allowedCTEs . end ( ) ; + + it )
switch ( * it ) {
case DwMime : : kCteBase64 : encodings | = KMMsgPartDialog : : Base64 ; break ;
case DwMime : : kCteQp : encodings | = KMMsgPartDialog : : QuotedPrintable ; break ;
case DwMime : : kCte7bit : encodings | = KMMsgPartDialog : : SevenBit ; break ;
case DwMime : : kCte8bit : encodings | = KMMsgPartDialog : : EightBit ; break ;
default : ;
}
dlg . setShownEncodings ( encodings ) ;
dlg . setMsgPart ( msgPart ) ;
if ( ! dlg . exec ( ) ) {
delete msgPart ;
msgPart = 0 ;
if ( attachURLfound )
emit attachmentAdded ( attachURL , false ) ;
return ;
}
}
mAtmModified = true ;
// add the new attachment to the list
addAttach ( msgPart ) ;
if ( attachURLfound )
emit attachmentAdded ( attachURL , true ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotInsertFile ( )
{
KFileDialog fdlg ( TQString ( ) , TQString ( ) , this , 0 , true ) ;
fdlg . setOperationMode ( KFileDialog : : Opening ) ;
fdlg . okButton ( ) - > setText ( i18n ( " &Insert " ) ) ;
fdlg . setCaption ( i18n ( " Insert File " ) ) ;
fdlg . toolBar ( ) - > insertCombo ( KMMsgBase : : supportedEncodings ( false ) , 4711 ,
false , 0 , 0 , 0 ) ;
KComboBox * combo = fdlg . toolBar ( ) - > getCombo ( 4711 ) ;
for ( int i = 0 ; i < combo - > count ( ) ; i + + )
if ( TDEGlobal : : charsets ( ) - > codecForName ( TDEGlobal : : charsets ( ) - >
encodingForName ( combo - > text ( i ) ) )
= = TQTextCodec : : codecForLocale ( ) ) combo - > setCurrentItem ( i ) ;
if ( ! fdlg . exec ( ) ) return ;
KURL u = fdlg . selectedURL ( ) ;
mRecentAction - > addURL ( u ) ;
// Prevent race condition updating list when multiple composers are open
{
TDEConfig * config = KMKernel : : config ( ) ;
TDEConfigGroupSaver saver ( config , " Composer " ) ;
TQString encoding = TDEGlobal : : charsets ( ) - > encodingForName ( combo - > currentText ( ) ) . latin1 ( ) ;
TQStringList urls = config - > readListEntry ( " recent-urls " ) ;
TQStringList encodings = config - > readListEntry ( " recent-encodings " ) ;
// Prevent config file from growing without bound
// Would be nicer to get this constant from TDERecentFilesAction
uint mMaxRecentFiles = 30 ;
while ( urls . count ( ) > mMaxRecentFiles )
urls . erase ( urls . fromLast ( ) ) ;
while ( encodings . count ( ) > mMaxRecentFiles )
encodings . erase ( encodings . fromLast ( ) ) ;
// sanity check
if ( urls . count ( ) ! = encodings . count ( ) ) {
urls . clear ( ) ;
encodings . clear ( ) ;
}
urls . prepend ( u . prettyURL ( ) ) ;
encodings . prepend ( encoding ) ;
config - > writeEntry ( " recent-urls " , urls ) ;
config - > writeEntry ( " recent-encodings " , encodings ) ;
mRecentAction - > saveEntries ( config ) ;
}
slotInsertRecentFile ( u ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotInsertRecentFile ( const KURL & u )
{
if ( u . fileName ( ) . isEmpty ( ) ) return ;
TDEIO : : Job * job = TDEIO : : get ( u ) ;
atmLoadData ld ;
ld . url = u ;
ld . data = TQByteArray ( ) ;
ld . insert = true ;
// Get the encoding previously used when inserting this file
{
TDEConfig * config = KMKernel : : config ( ) ;
TDEConfigGroupSaver saver ( config , " Composer " ) ;
TQStringList urls = config - > readListEntry ( " recent-urls " ) ;
TQStringList encodings = config - > readListEntry ( " recent-encodings " ) ;
int index = urls . findIndex ( u . prettyURL ( ) ) ;
if ( index ! = - 1 ) {
TQString encoding = encodings [ index ] ;
ld . encoding = encoding . latin1 ( ) ;
}
}
mMapAtmLoadData . insert ( job , ld ) ;
connect ( job , TQT_SIGNAL ( result ( TDEIO : : Job * ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachFileResult ( TDEIO : : Job * ) ) ) ;
connect ( job , TQT_SIGNAL ( data ( TDEIO : : Job * , const TQByteArray & ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotAttachFileData ( TDEIO : : Job * , const TQByteArray & ) ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSetCharset ( )
{
if ( mEncodingAction - > currentItem ( ) = = 0 )
{
mAutoCharset = true ;
return ;
}
mAutoCharset = false ;
mCharset = TDEGlobal : : charsets ( ) - > encodingForName ( mEncodingAction - >
currentText ( ) ) . latin1 ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSelectCryptoModule ( bool init )
{
if ( ! init ) {
setModified ( true ) ;
}
if ( canSignEncryptAttachments ( ) ) {
// if the encrypt/sign columns are hidden then show them
if ( 0 = = mAtmListView - > columnWidth ( mAtmColEncrypt ) ) {
// set/unset signing/encryption for all attachments according to the
// state of the global sign/encrypt action
if ( ! mAtmList . isEmpty ( ) ) {
for ( KMAtmListViewItem * lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . first ( ) ) ;
lvi ;
lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . next ( ) ) ) {
lvi - > setSign ( mSignAction - > isChecked ( ) ) ;
lvi - > setEncrypt ( mEncryptAction - > isChecked ( ) ) ;
}
}
int totalWidth = 0 ;
// determine the total width of the columns
for ( int col = 0 ; col < mAtmColEncrypt ; col + + )
totalWidth + = mAtmListView - > columnWidth ( col ) ;
int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
- mAtmSignColWidth ;
// reduce the width of all columns so that the encrypt and sign column
// fit
int usedWidth = 0 ;
for ( int col = 0 ; col < mAtmColEncrypt - 1 ; col + + ) {
int newWidth = mAtmListView - > columnWidth ( col ) * reducedTotalWidth
/ totalWidth ;
mAtmListView - > setColumnWidth ( col , newWidth ) ;
usedWidth + = newWidth ;
}
// the last column before the encrypt column gets the remaining space
// (because of rounding errors the width of this column isn't calculated
// the same way as the width of the other columns)
mAtmListView - > setColumnWidth ( mAtmColEncrypt - 1 ,
reducedTotalWidth - usedWidth ) ;
mAtmListView - > setColumnWidth ( mAtmColEncrypt , mAtmEncryptColWidth ) ;
mAtmListView - > setColumnWidth ( mAtmColSign , mAtmSignColWidth ) ;
for ( KMAtmListViewItem * lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . first ( ) ) ;
lvi ;
lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . next ( ) ) ) {
lvi - > enableCryptoCBs ( true ) ;
}
}
} else {
// if the encrypt/sign columns are visible then hide them
if ( 0 ! = mAtmListView - > columnWidth ( mAtmColEncrypt ) ) {
mAtmEncryptColWidth = mAtmListView - > columnWidth ( mAtmColEncrypt ) ;
mAtmSignColWidth = mAtmListView - > columnWidth ( mAtmColSign ) ;
int totalWidth = 0 ;
// determine the total width of the columns
for ( int col = 0 ; col < mAtmListView - > columns ( ) ; col + + )
totalWidth + = mAtmListView - > columnWidth ( col ) ;
int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
- mAtmSignColWidth ;
// increase the width of all columns so that the visible columns take
// up the whole space
int usedWidth = 0 ;
for ( int col = 0 ; col < mAtmColEncrypt - 1 ; col + + ) {
int newWidth = mAtmListView - > columnWidth ( col ) * totalWidth
/ reducedTotalWidth ;
mAtmListView - > setColumnWidth ( col , newWidth ) ;
usedWidth + = newWidth ;
}
// the last column before the encrypt column gets the remaining space
// (because of rounding errors the width of this column isn't calculated
// the same way as the width of the other columns)
mAtmListView - > setColumnWidth ( mAtmColEncrypt - 1 , totalWidth - usedWidth ) ;
mAtmListView - > setColumnWidth ( mAtmColEncrypt , 0 ) ;
mAtmListView - > setColumnWidth ( mAtmColSign , 0 ) ;
for ( KMAtmListViewItem * lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . first ( ) ) ;
lvi ;
lvi = static_cast < KMAtmListViewItem * > ( mAtmItemList . next ( ) ) ) {
lvi - > enableCryptoCBs ( false ) ;
}
}
}
}
static void showExportError ( TQWidget * w , const GpgME : : Error & err ) {
assert ( err ) ;
const TQString msg = i18n ( " <qt><p>An error occurred while trying to export "
" the key from the backend:</p> "
" <p><b>%1</b></p></qt> " )
. arg ( TQString : : fromLocal8Bit ( err . asString ( ) ) ) ;
KMessageBox : : error ( w , msg , i18n ( " Key Export Failed " ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotInsertMyPublicKey ( )
{
// get PGP user id for the chosen identity
mFingerprint =
kmkernel - > identityManager ( ) - > identityForUoidOrDefault ( mIdentity - > currentIdentity ( ) ) . pgpEncryptionKey ( ) ;
if ( ! mFingerprint . isEmpty ( ) )
startPublicKeyExport ( ) ;
}
void KMComposeWin : : startPublicKeyExport ( ) {
if ( mFingerprint . isEmpty ( ) | | ! Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) )
return ;
Kleo : : ExportJob * job = Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) - > publicKeyExportJob ( true ) ;
assert ( job ) ;
connect ( job , TQT_SIGNAL ( result ( const GpgME : : Error & , const TQByteArray & ) ) ,
this , TQT_SLOT ( slotPublicKeyExportResult ( const GpgME : : Error & , const TQByteArray & ) ) ) ;
const GpgME : : Error err = job - > start ( mFingerprint ) ;
if ( err )
showExportError ( this , err ) ;
else
( void ) new Kleo : : ProgressDialog ( job , i18n ( " Exporting key... " ) , this ) ;
}
void KMComposeWin : : slotPublicKeyExportResult ( const GpgME : : Error & err , const TQByteArray & keydata ) {
if ( err ) {
showExportError ( this , err ) ;
return ;
}
// create message part
KMMessagePart * msgPart = new KMMessagePart ( ) ;
msgPart - > setName ( i18n ( " OpenPGP key 0x%1 " ) . arg ( mFingerprint ) ) ;
msgPart - > setTypeStr ( " application " ) ;
msgPart - > setSubtypeStr ( " pgp-keys " ) ;
TQValueList < int > dummy ;
msgPart - > setBodyAndGuessCte ( keydata , dummy , false ) ;
msgPart - > setContentDisposition ( " attachment; \n \t filename=0x " + TQCString ( mFingerprint . latin1 ( ) ) + " .asc " ) ;
// add the new attachment to the list
addAttach ( msgPart ) ;
rethinkFields ( ) ; //work around initial-size bug in TQt-1.32
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotInsertPublicKey ( )
{
Kleo : : KeySelectionDialog dlg ( i18n ( " Attach Public OpenPGP Key " ) ,
i18n ( " Select the public key which should "
" be attached. " ) ,
std : : vector < GpgME : : Key > ( ) ,
Kleo : : KeySelectionDialog : : PublicKeys | Kleo : : KeySelectionDialog : : OpenPGPKeys ,
false /* no multi selection */ ,
false /* no remember choice box */ ,
this , " attach public key selection dialog " ) ;
if ( dlg . exec ( ) ! = TQDialog : : Accepted )
return ;
mFingerprint = dlg . fingerprint ( ) ;
startPublicKeyExport ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachPopupMenu ( TQListViewItem * , const TQPoint & , int )
{
if ( ! mAttachMenu )
{
mAttachMenu = new TQPopupMenu ( this ) ;
mOpenId = mAttachMenu - > insertItem ( i18n ( " to open " , " Open " ) , this ,
TQT_SLOT ( slotAttachOpen ( ) ) ) ;
mOpenWithId = mAttachMenu - > insertItem ( i18n ( " Open With... " ) , this ,
TQT_SLOT ( slotAttachOpenWith ( ) ) ) ;
mViewId = mAttachMenu - > insertItem ( i18n ( " to view " , " View " ) , this ,
TQT_SLOT ( slotAttachView ( ) ) ) ;
mEditId = mAttachMenu - > insertItem ( i18n ( " Edit " ) , this , TQT_SLOT ( slotAttachEdit ( ) ) ) ;
mEditWithId = mAttachMenu - > insertItem ( i18n ( " Edit With... " ) , this ,
TQT_SLOT ( slotAttachEditWith ( ) ) ) ;
mRemoveId = mAttachMenu - > insertItem ( i18n ( " Remove " ) , this , TQT_SLOT ( slotAttachRemove ( ) ) ) ;
mSaveAsId = mAttachMenu - > insertItem ( SmallIconSet ( " filesaveas " ) , i18n ( " Save As... " ) , this ,
TQT_SLOT ( slotAttachSave ( ) ) ) ;
mPropertiesId = mAttachMenu - > insertItem ( i18n ( " Properties " ) , this ,
TQT_SLOT ( slotAttachProperties ( ) ) ) ;
mAttachMenu - > insertSeparator ( ) ;
mAttachMenu - > insertItem ( i18n ( " Add Attachment... " ) , this , TQT_SLOT ( slotAttachFile ( ) ) ) ;
}
int selectedCount = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it ) {
if ( ( * it ) - > isSelected ( ) ) {
+ + selectedCount ;
}
}
mAttachMenu - > setItemEnabled ( mOpenId , selectedCount > 0 ) ;
mAttachMenu - > setItemEnabled ( mOpenWithId , selectedCount > 0 ) ;
mAttachMenu - > setItemEnabled ( mViewId , selectedCount > 0 ) ;
mAttachMenu - > setItemEnabled ( mEditId , selectedCount = = 1 ) ;
mAttachMenu - > setItemEnabled ( mEditWithId , selectedCount = = 1 ) ;
mAttachMenu - > setItemEnabled ( mRemoveId , selectedCount > 0 ) ;
mAttachMenu - > setItemEnabled ( mSaveAsId , selectedCount = = 1 ) ;
mAttachMenu - > setItemEnabled ( mPropertiesId , selectedCount = = 1 ) ;
mAttachMenu - > popup ( TQCursor : : pos ( ) ) ;
}
//-----------------------------------------------------------------------------
int KMComposeWin : : currentAttachmentNum ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i )
if ( * it = = mAtmListView - > currentItem ( ) )
return i ;
return - 1 ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachProperties ( )
{
int idx = currentAttachmentNum ( ) ;
if ( idx < 0 ) return ;
KMMessagePart * msgPart = mAtmList . at ( idx ) ;
KMMsgPartDialogCompat dlg ( mMainWidget ) ;
dlg . setMsgPart ( msgPart ) ;
KMAtmListViewItem * listItem = ( KMAtmListViewItem * ) ( mAtmItemList . at ( idx ) ) ;
if ( canSignEncryptAttachments ( ) & & listItem ) {
dlg . setCanSign ( true ) ;
dlg . setCanEncrypt ( true ) ;
dlg . setSigned ( listItem - > isSign ( ) ) ;
dlg . setEncrypted ( listItem - > isEncrypt ( ) ) ;
} else {
dlg . setCanSign ( false ) ;
dlg . setCanEncrypt ( false ) ;
}
if ( dlg . exec ( ) )
{
mAtmModified = true ;
// values may have changed, so recreate the listbox line
if ( listItem ) {
msgPartToItem ( msgPart , listItem ) ;
if ( canSignEncryptAttachments ( ) ) {
listItem - > setSign ( dlg . isSigned ( ) ) ;
listItem - > setEncrypt ( dlg . isEncrypted ( ) ) ;
}
}
}
if ( msgPart - > typeStr ( ) . lower ( ) ! = " text " ) msgPart - > setCharset ( TQCString ( ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : compressAttach ( int idx )
{
if ( idx < 0 ) return ;
unsigned int i ;
for ( i = 0 ; i < mAtmItemList . count ( ) ; + + i )
if ( mAtmItemList . at ( i ) - > itemPos ( ) = = idx )
break ;
if ( i > mAtmItemList . count ( ) )
return ;
KMMessagePart * msgPart ;
msgPart = mAtmList . at ( i ) ;
TQByteArray array ;
TQBuffer dev ( array ) ;
KZip zip ( & TQT_TQIODEVICE_OBJECT ( dev ) ) ;
TQByteArray decoded = msgPart - > bodyDecodedBinary ( ) ;
if ( ! zip . open ( IO_WriteOnly ) ) {
KMessageBox : : sorry ( 0 , i18n ( " KMail could not compress the file. " ) ) ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setCompress ( false ) ;
return ;
}
zip . setCompression ( KZip : : DeflateCompression ) ;
if ( ! zip . writeFile ( msgPart - > name ( ) , " " , " " , decoded . size ( ) ,
decoded . data ( ) ) ) {
KMessageBox : : sorry ( 0 , i18n ( " KMail could not compress the file. " ) ) ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setCompress ( false ) ;
return ;
}
zip . close ( ) ;
if ( array . size ( ) > = decoded . size ( ) ) {
if ( KMessageBox : : questionYesNo ( this , i18n ( " The compressed file is larger "
" than the original. Do you want to keep the original one? " ) , TQString ( ) , i18n ( " Keep " ) , i18n ( " Compress " ) )
= = KMessageBox : : Yes ) {
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setCompress ( false ) ;
return ;
}
}
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setUncompressedCodec (
msgPart - > cteStr ( ) ) ;
msgPart - > setCteStr ( " base64 " ) ;
msgPart - > setBodyEncodedBinary ( array ) ;
TQString name = msgPart - > name ( ) + " .zip " ;
msgPart - > setName ( name ) ;
TQCString cDisp = " attachment; " ;
TQCString encoding = KMMsgBase : : autoDetectCharset ( msgPart - > charset ( ) ,
KMMessage : : preferredCharsets ( ) , name ) ;
kdDebug ( 5006 ) < < " encoding: " < < encoding < < endl ;
if ( encoding . isEmpty ( ) ) encoding = " utf-8 " ;
kdDebug ( 5006 ) < < " encoding after: " < < encoding < < endl ;
TQCString encName ;
if ( GlobalSettings : : self ( ) - > outlookCompatibleAttachments ( ) )
encName = KMMsgBase : : encodeRFC2047String ( name , encoding ) ;
else
encName = KMMsgBase : : encodeRFC2231String ( name , encoding ) ;
cDisp + = " \n \t filename " ;
if ( name ! = TQString ( encName ) )
cDisp + = " *= " + encName ;
else
cDisp + = " = \" " + encName + ' " ' ;
msgPart - > setContentDisposition ( cDisp ) ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setUncompressedMimeType (
msgPart - > typeStr ( ) , msgPart - > subtypeStr ( ) ) ;
msgPart - > setTypeStr ( " application " ) ;
msgPart - > setSubtypeStr ( " x-zip " ) ;
KMAtmListViewItem * listItem = static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) ;
msgPartToItem ( msgPart , listItem , false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : uncompressAttach ( int idx )
{
if ( idx < 0 ) return ;
unsigned int i ;
for ( i = 0 ; i < mAtmItemList . count ( ) ; + + i )
if ( mAtmItemList . at ( i ) - > itemPos ( ) = = idx )
break ;
if ( i > mAtmItemList . count ( ) )
return ;
KMMessagePart * msgPart ;
msgPart = mAtmList . at ( i ) ;
TQBuffer dev ( msgPart - > bodyDecodedBinary ( ) ) ;
KZip zip ( & TQT_TQIODEVICE_OBJECT ( dev ) ) ;
TQByteArray decoded ;
decoded = msgPart - > bodyDecodedBinary ( ) ;
if ( ! zip . open ( IO_ReadOnly ) ) {
KMessageBox : : sorry ( 0 , i18n ( " KMail could not uncompress the file. " ) ) ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setCompress ( true ) ;
return ;
}
const KArchiveDirectory * dir = zip . directory ( ) ;
KZipFileEntry * entry ;
if ( dir - > entries ( ) . count ( ) ! = 1 ) {
KMessageBox : : sorry ( 0 , i18n ( " KMail could not uncompress the file. " ) ) ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > setCompress ( true ) ;
return ;
}
entry = ( KZipFileEntry * ) dir - > entry ( dir - > entries ( ) [ 0 ] ) ;
msgPart - > setCteStr (
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > uncompressedCodec ( ) ) ;
msgPart - > setBodyEncodedBinary ( entry - > data ( ) ) ;
TQString name = entry - > name ( ) ;
msgPart - > setName ( name ) ;
zip . close ( ) ;
TQCString cDisp = " attachment; " ;
TQCString encoding = KMMsgBase : : autoDetectCharset ( msgPart - > charset ( ) ,
KMMessage : : preferredCharsets ( ) , name ) ;
if ( encoding . isEmpty ( ) ) encoding = " utf-8 " ;
TQCString encName ;
if ( GlobalSettings : : self ( ) - > outlookCompatibleAttachments ( ) )
encName = KMMsgBase : : encodeRFC2047String ( name , encoding ) ;
else
encName = KMMsgBase : : encodeRFC2231String ( name , encoding ) ;
cDisp + = " \n \t filename " ;
if ( name ! = TQString ( encName ) )
cDisp + = " *= " + encName ;
else
cDisp + = " = \" " + encName + ' " ' ;
msgPart - > setContentDisposition ( cDisp ) ;
TQCString type , subtype ;
static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) - > uncompressedMimeType ( type ,
subtype ) ;
msgPart - > setTypeStr ( type ) ;
msgPart - > setSubtypeStr ( subtype ) ;
KMAtmListViewItem * listItem = static_cast < KMAtmListViewItem * > ( mAtmItemList . at ( i ) ) ;
msgPartToItem ( msgPart , listItem , false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachView ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i ) {
if ( ( * it ) - > isSelected ( ) ) {
viewAttach ( i ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachOpen ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i ) {
if ( ( * it ) - > isSelected ( ) ) {
openAttach ( i , false ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachOpenWith ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i ) {
if ( ( * it ) - > isSelected ( ) ) {
openAttach ( i , true ) ;
}
}
}
void KMComposeWin : : slotAttachEdit ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i ) {
if ( ( * it ) - > isSelected ( ) ) {
editAttach ( i , false ) ;
}
}
}
void KMComposeWin : : slotAttachEditWith ( )
{
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + i ) {
if ( ( * it ) - > isSelected ( ) ) {
editAttach ( i , true ) ;
}
}
}
//-----------------------------------------------------------------------------
bool KMComposeWin : : inlineSigningEncryptionSelected ( ) {
if ( ! mSignAction - > isChecked ( ) & & ! mEncryptAction - > isChecked ( ) )
return false ;
return cryptoMessageFormat ( ) = = Kleo : : InlineOpenPGPFormat ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : viewAttach ( int index )
{
TQString pname ;
KMMessagePart * msgPart ;
msgPart = mAtmList . at ( index ) ;
pname = msgPart - > name ( ) . stripWhiteSpace ( ) ;
if ( pname . isEmpty ( ) ) pname = msgPart - > contentDescription ( ) ;
if ( pname . isEmpty ( ) ) pname = " unnamed " ;
KTempFile * atmTempFile = new KTempFile ( ) ;
mAtmTempList . append ( atmTempFile ) ;
atmTempFile - > setAutoDelete ( true ) ;
KPIM : : kByteArrayToFile ( msgPart - > bodyDecodedBinary ( ) , atmTempFile - > name ( ) , false , false ,
false ) ;
KMReaderMainWin * win = new KMReaderMainWin ( msgPart , false ,
atmTempFile - > name ( ) , pname , mCharset ) ;
win - > show ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : openAttach ( int index , bool with )
{
KMMessagePart * msgPart = mAtmList . at ( index ) ;
const TQString contentTypeStr =
( msgPart - > typeStr ( ) + ' / ' + msgPart - > subtypeStr ( ) ) . lower ( ) ;
KMimeType : : Ptr mimetype ;
mimetype = KMimeType : : mimeType ( contentTypeStr ) ;
KTempFile * atmTempFile = new KTempFile ( ) ;
mAtmTempList . append ( atmTempFile ) ;
const bool autoDelete = true ;
atmTempFile - > setAutoDelete ( autoDelete ) ;
KURL url ;
url . setPath ( atmTempFile - > name ( ) ) ;
KPIM : : kByteArrayToFile ( msgPart - > bodyDecodedBinary ( ) , atmTempFile - > name ( ) , false , false ,
false ) ;
if ( : : chmod ( TQFile : : encodeName ( atmTempFile - > name ( ) ) , S_IRUSR ) ! = 0 ) {
TQFile : : remove ( url . path ( ) ) ;
return ;
}
KService : : Ptr offer =
KServiceTypeProfile : : preferredService ( mimetype - > name ( ) , " Application " ) ;
if ( with | | ! offer | | mimetype - > name ( ) = = " application/octet-stream " ) {
if ( ( ! KRun : : displayOpenWithDialog ( url , autoDelete ) ) & & autoDelete ) {
TQFile : : remove ( url . path ( ) ) ;
}
}
else {
if ( ( ! KRun : : run ( * offer , url , autoDelete ) ) & & autoDelete ) {
TQFile : : remove ( url . path ( ) ) ;
}
}
}
void KMComposeWin : : editAttach ( int index , bool openWith )
{
KMMessagePart * msgPart = mAtmList . at ( index ) ;
const TQString contentTypeStr =
( msgPart - > typeStr ( ) + ' / ' + msgPart - > subtypeStr ( ) ) . lower ( ) ;
KTempFile * atmTempFile = new KTempFile ( ) ;
mAtmTempList . append ( atmTempFile ) ;
atmTempFile - > setAutoDelete ( true ) ;
atmTempFile - > file ( ) - > writeBlock ( msgPart - > bodyDecodedBinary ( ) ) ;
atmTempFile - > file ( ) - > flush ( ) ;
KMail : : EditorWatcher * watcher =
new KMail : : EditorWatcher ( KURL ( atmTempFile - > name ( ) ) , contentTypeStr , openWith ,
TQT_TQOBJECT ( this ) , this ) ;
connect ( watcher , TQT_SIGNAL ( editDone ( KMail : : EditorWatcher * ) ) , TQT_SLOT ( slotEditDone ( KMail : : EditorWatcher * ) ) ) ;
if ( watcher - > start ( ) ) {
mEditorMap . insert ( watcher , msgPart ) ;
mEditorTempFiles . insert ( watcher , atmTempFile ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachSave ( )
{
KMMessagePart * msgPart ;
TQString fileName , pname ;
int idx = currentAttachmentNum ( ) ;
if ( idx < 0 ) return ;
msgPart = mAtmList . at ( idx ) ;
pname = msgPart - > name ( ) ;
if ( pname . isEmpty ( ) ) pname = " unnamed " ;
KURL url = KFileDialog : : getSaveURL ( pname , TQString ( ) , 0 , i18n ( " Save Attachment As " ) ) ;
if ( url . isEmpty ( ) )
return ;
kmkernel - > byteArrayToRemoteFile ( msgPart - > bodyDecodedBinary ( ) , url ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAttachRemove ( )
{
mAtmSelectNew = 0 ;
bool attachmentRemoved = false ;
int i = 0 ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; ) {
if ( ( * it ) - > isSelected ( ) ) {
removeAttach ( i ) ;
attachmentRemoved = true ;
}
else {
+ + it ;
+ + i ;
}
}
if ( attachmentRemoved ) {
setModified ( true ) ;
slotUpdateAttachActions ( ) ;
if ( mAtmSelectNew ) {
mAtmListView - > setSelected ( mAtmSelectNew , true ) ;
mAtmListView - > setCurrentItem ( mAtmSelectNew ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotFind ( )
{
mEditor - > search ( ) ;
}
void KMComposeWin : : slotSearchAgain ( )
{
mEditor - > repeatSearch ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotReplace ( )
{
mEditor - > replace ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotUpdateFont ( )
{
kdDebug ( ) < < " KMComposeWin::slotUpdateFont " < < endl ;
if ( ! mFixedFontAction ) {
return ;
}
mEditor - > setFont ( mFixedFontAction - > isChecked ( ) ? mFixedFont : mBodyFont ) ;
}
TQString KMComposeWin : : quotePrefixName ( ) const
{
if ( ! msg ( ) )
return TQString ( ) ;
int languageNr = GlobalSettings : : self ( ) - > replyCurrentLanguage ( ) ;
ReplyPhrases replyPhrases ( TQString : : number ( languageNr ) ) ;
replyPhrases . readConfig ( ) ;
TQString quotePrefix = msg ( ) - > formatString (
replyPhrases . indentPrefix ( ) ) ;
quotePrefix = msg ( ) - > formatString ( quotePrefix ) ;
return quotePrefix ;
}
void KMComposeWin : : slotPasteClipboardAsQuotation ( )
{
if ( mEditor - > hasFocus ( ) & & msg ( ) )
{
TQString s = TQApplication : : clipboard ( ) - > text ( ) ;
if ( ! s . isEmpty ( ) )
mEditor - > insert ( addQuotesToText ( s ) ) ;
}
}
void KMComposeWin : : slotPasteClipboardAsAttachment ( )
{
KURL url ( TQApplication : : clipboard ( ) - > text ( TQClipboard : : Clipboard ) ) ;
if ( url . isValid ( ) ) {
addAttach ( TQApplication : : clipboard ( ) - > text ( TQClipboard : : Clipboard ) ) ;
return ;
}
TQMimeSource * mimeSource = TQApplication : : clipboard ( ) - > data ( ) ;
if ( TQImageDrag : : canDecode ( mimeSource ) ) {
slotAttachPNGImageData ( mimeSource - > encodedData ( " image/png " ) ) ;
}
else {
bool ok ;
TQString attName = KInputDialog : : getText ( " KMail " , i18n ( " Name of the attachment: " ) , TQString ( ) , & ok , this ) ;
if ( ! ok )
return ;
KMMessagePart * msgPart = new KMMessagePart ;
msgPart - > setName ( attName ) ;
TQValueList < int > dummy ;
msgPart - > setBodyAndGuessCte ( TQCString ( TQApplication : : clipboard ( ) - > text ( ) . latin1 ( ) ) , dummy ,
kmkernel - > msgSender ( ) - > sendQuotedPrintable ( ) ) ;
addAttach ( msgPart ) ;
}
}
void KMComposeWin : : slotAddQuotes ( )
{
if ( mEditor - > hasFocus ( ) & & msg ( ) )
{
// TODO: I think this is backwards.
// i.e, if no region is marked then add quotes to every line
// else add quotes only on the lines that are marked.
if ( mEditor - > hasMarkedText ( ) ) {
TQString s = mEditor - > markedText ( ) ;
if ( ! s . isEmpty ( ) )
mEditor - > insert ( addQuotesToText ( s ) ) ;
} else {
int l = mEditor - > currentLine ( ) ;
int c = mEditor - > currentColumn ( ) ;
TQString s = mEditor - > textLine ( l ) ;
s . prepend ( quotePrefixName ( ) ) ;
mEditor - > insertLine ( s , l ) ;
mEditor - > removeLine ( l + 1 ) ;
mEditor - > setCursorPosition ( l , c + 2 ) ;
}
}
}
TQString KMComposeWin : : addQuotesToText ( const TQString & inputText )
{
TQString answer = TQString ( inputText ) ;
TQString indentStr = quotePrefixName ( ) ;
answer . replace ( ' \n ' , ' \n ' + indentStr ) ;
answer . prepend ( indentStr ) ;
answer + = ' \n ' ;
return KMMessage : : smartQuote ( answer , GlobalSettings : : self ( ) - > lineWrapWidth ( ) ) ;
}
TQString KMComposeWin : : removeQuotesFromText ( const TQString & inputText )
{
TQString s = inputText ;
// remove first leading quote
TQString quotePrefix = ' ^ ' + quotePrefixName ( ) ;
TQRegExp rx ( quotePrefix ) ;
s . remove ( rx ) ;
// now remove all remaining leading quotes
quotePrefix = ' \n ' + quotePrefixName ( ) ;
rx = quotePrefix ;
s . replace ( rx , " \n " ) ;
return s ;
}
void KMComposeWin : : slotRemoveQuotes ( )
{
if ( mEditor - > hasFocus ( ) & & msg ( ) )
{
// TODO: I think this is backwards.
// i.e, if no region is marked then remove quotes from every line
// else remove quotes only on the lines that are marked.
if ( mEditor - > hasMarkedText ( ) ) {
TQString s = mEditor - > markedText ( ) ;
mEditor - > insert ( removeQuotesFromText ( s ) ) ;
} else {
int l = mEditor - > currentLine ( ) ;
int c = mEditor - > currentColumn ( ) ;
TQString s = mEditor - > textLine ( l ) ;
mEditor - > insertLine ( removeQuotesFromText ( s ) , l ) ;
mEditor - > removeLine ( l + 1 ) ;
mEditor - > setCursorPosition ( l , c - 2 ) ;
}
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotUndo ( )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
if ( : : tqqt_cast < KEdit * > ( fw ) )
static_cast < TQTextEdit * > ( fw ) - > undo ( ) ;
else if ( : : tqqt_cast < TQLineEdit * > ( fw ) )
static_cast < TQLineEdit * > ( fw ) - > undo ( ) ;
}
void KMComposeWin : : slotRedo ( )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
if ( : : tqqt_cast < KEdit * > ( fw ) )
static_cast < KEdit * > ( fw ) - > redo ( ) ;
else if ( : : tqqt_cast < TQLineEdit * > ( fw ) )
static_cast < TQLineEdit * > ( fw ) - > redo ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotCut ( )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
if ( : : tqqt_cast < KEdit * > ( fw ) )
static_cast < KEdit * > ( fw ) - > cut ( ) ;
else if ( : : tqqt_cast < TQLineEdit * > ( fw ) )
static_cast < TQLineEdit * > ( fw ) - > cut ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotCopy ( )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
# ifdef KeyPress
# undef KeyPress
# endif
TQKeyEvent k ( TQEvent : : KeyPress , Key_C , 0 , ControlButton ) ;
kapp - > notify ( TQT_TQOBJECT ( fw ) , TQT_TQEVENT ( & k ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotPasteClipboard ( )
{
paste ( TQClipboard : : Clipboard ) ;
}
void KMComposeWin : : paste ( TQClipboard : : Mode mode )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
TQMimeSource * mimeSource = TQApplication : : clipboard ( ) - > data ( mode ) ;
if ( mimeSource - > provides ( " image/png " ) ) {
slotAttachPNGImageData ( mimeSource - > encodedData ( " image/png " ) ) ;
} else if ( KURLDrag : : canDecode ( mimeSource ) ) {
KURL : : List urlList ;
if ( KURLDrag : : decode ( mimeSource , urlList ) ) {
const TQString asText = i18n ( " Add as Text " ) ;
const TQString asAttachment = i18n ( " Add as Attachment " ) ;
const TQString text = i18n ( " Please select whether you want to insert the content as text into the editor, "
" or append the referenced file as an attachment. " ) ;
const TQString caption = i18n ( " Paste as text or attachment? " ) ;
int id = KMessageBox : : questionYesNoCancel ( this , text , caption ,
KGuiItem ( asText ) , KGuiItem ( asAttachment ) ) ;
switch ( id ) {
case KMessageBox : : Yes :
for ( KURL : : List : : Iterator it = urlList . begin ( ) ;
it ! = urlList . end ( ) ; + + it ) {
mEditor - > insert ( ( * it ) . url ( ) ) ;
}
break ;
case KMessageBox : : No :
for ( KURL : : List : : Iterator it = urlList . begin ( ) ;
it ! = urlList . end ( ) ; + + it ) {
addAttach ( * it ) ;
}
break ;
}
}
} else if ( TQTextDrag : : canDecode ( mimeSource ) ) {
TQString s ;
if ( TQTextDrag : : decode ( mimeSource , s ) )
mEditor - > insert ( s ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotMarkAll ( )
{
TQWidget * fw = focusWidget ( ) ;
if ( ! fw ) return ;
if ( : : tqqt_cast < TQLineEdit * > ( fw ) )
static_cast < TQLineEdit * > ( fw ) - > selectAll ( ) ;
else if ( : : tqqt_cast < KEdit * > ( fw ) )
static_cast < KEdit * > ( fw ) - > selectAll ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotClose ( )
{
close ( false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotNewComposer ( )
{
KMComposeWin * win ;
KMMessage * msg = new KMMessage ;
msg - > initHeader ( ) ;
win = new KMComposeWin ( msg ) ;
win - > show ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotNewMailReader ( )
{
KMMainWin * kmmwin = new KMMainWin ( 0 ) ;
kmmwin - > show ( ) ;
//d->resize(d->size());
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotUpdWinTitle ( const TQString & text )
{
TQString s ( text ) ;
// Remove characters that show badly in most window decorations:
// newlines tend to become boxes.
if ( text . isEmpty ( ) )
setCaption ( " ( " + i18n ( " unnamed " ) + " ) " ) ;
else setCaption ( s . replace ( TQChar ( ' \n ' ) , ' ' ) ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotEncryptToggled ( bool on )
{
setEncryption ( on , true /* set by the user */ ) ;
slotUpdateSignatureAndEncrypionStateIndicators ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setEncryption ( bool encrypt , bool setByUser )
{
bool wasModified = isModified ( ) ;
if ( setByUser )
setModified ( true ) ;
if ( ! mEncryptAction - > isEnabled ( ) )
encrypt = false ;
// check if the user wants to encrypt messages to himself and if he defined
// an encryption key for the current identity
else if ( encrypt & & encryptToSelf ( ) & & ! mLastIdentityHasEncryptionKey ) {
if ( setByUser ) {
KMessageBox : : sorry ( this ,
i18n ( " <qt><p>You have requested that messages be "
" encrypted to yourself, but the currently selected "
" identity does not define an (OpenPGP or S/MIME) "
" encryption key to use for this.</p> "
" <p>Please select the key(s) to use "
" in the identity configuration.</p> "
" </qt> " ) ,
i18n ( " Undefined Encryption Key " ) ) ;
setModified ( wasModified ) ;
}
encrypt = false ;
}
// make sure the mEncryptAction is in the right state
mEncryptAction - > setChecked ( encrypt ) ;
// show the appropriate icon
if ( encrypt )
mEncryptAction - > setIcon ( " encrypted " ) ;
else
mEncryptAction - > setIcon ( " decrypted " ) ;
// mark the attachments for (no) encryption
if ( canSignEncryptAttachments ( ) ) {
for ( KMAtmListViewItem * entry =
static_cast < KMAtmListViewItem * > ( mAtmItemList . first ( ) ) ;
entry ;
entry = static_cast < KMAtmListViewItem * > ( mAtmItemList . next ( ) ) )
entry - > setEncrypt ( encrypt ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSignToggled ( bool on )
{
setSigning ( on , true /* set by the user */ ) ;
slotUpdateSignatureAndEncrypionStateIndicators ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : setSigning ( bool sign , bool setByUser )
{
bool wasModified = isModified ( ) ;
if ( setByUser )
setModified ( true ) ;
if ( ! mSignAction - > isEnabled ( ) )
sign = false ;
// check if the user defined a signing key for the current identity
if ( sign & & ! mLastIdentityHasSigningKey ) {
if ( setByUser ) {
KMessageBox : : sorry ( this ,
i18n ( " <qt><p>In order to be able to sign "
" this message you first have to "
" define the (OpenPGP or S/MIME) signing key "
" to use.</p> "
" <p>Please select the key to use "
" in the identity configuration.</p> "
" </qt> " ) ,
i18n ( " Undefined Signing Key " ) ) ;
setModified ( wasModified ) ;
}
sign = false ;
}
// make sure the mSignAction is in the right state
mSignAction - > setChecked ( sign ) ;
// mark the attachments for (no) signing
if ( canSignEncryptAttachments ( ) ) {
for ( KMAtmListViewItem * entry =
static_cast < KMAtmListViewItem * > ( mAtmItemList . first ( ) ) ;
entry ;
entry = static_cast < KMAtmListViewItem * > ( mAtmItemList . next ( ) ) )
entry - > setSign ( sign ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotWordWrapToggled ( bool on )
{
if ( on )
{
mEditor - > setWordWrap ( TQTextEdit : : FixedColumnWidth ) ;
mEditor - > setWrapColumnOrWidth ( GlobalSettings : : self ( ) - > lineWrapWidth ( ) ) ;
}
else
{
mEditor - > setWordWrap ( TQTextEdit : : WidgetWidth ) ;
}
}
void KMComposeWin : : disableWordWrap ( )
{
mEditor - > setWordWrap ( TQTextEdit : : NoWrap ) ;
}
void KMComposeWin : : disableRecipientNumberCheck ( )
{
mCheckForRecipients = false ;
}
void KMComposeWin : : disableForgottenAttachmentsCheck ( )
{
mCheckForForgottenAttachments = false ;
}
void KMComposeWin : : ignoreStickyFields ( )
{
mIgnoreStickyFields = true ;
mBtnTransport - > setChecked ( false ) ;
mBtnDictionary - > setChecked ( false ) ;
mBtnIdentity - > setChecked ( false ) ;
mBtnTransport - > setEnabled ( false ) ;
mBtnDictionary - > setEnabled ( false ) ;
mBtnIdentity - > setEnabled ( false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotPrint ( )
{
mMessageWasModified = isModified ( ) ;
connect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotContinuePrint ( bool ) ) ) ;
applyChanges ( true ) ;
}
void KMComposeWin : : slotContinuePrint ( bool rc )
{
disconnect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotContinuePrint ( bool ) ) ) ;
if ( rc ) {
if ( mComposedMessages . isEmpty ( ) ) {
kdDebug ( 5006 ) < < " Composing the message failed. " < < endl ;
return ;
}
KMCommand * command = new KMPrintCommand ( this , mComposedMessages . first ( ) ) ;
command - > start ( ) ;
setModified ( mMessageWasModified ) ;
}
}
//----------------------------------------------------------------------------
bool KMComposeWin : : validateAddresses ( TQWidget * parent , const TQString & addresses )
{
TQString brokenAddress ;
KPIM : : EmailParseResult errorCode = KMMessage : : isValidEmailAddressList ( KMMessage : : expandAliases ( addresses ) , brokenAddress ) ;
if ( ! ( errorCode = = KPIM : : AddressOk | | errorCode = = KPIM : : AddressEmpty ) ) {
TQString errorMsg ( " <qt><p><b> " + brokenAddress +
" </b></p><p> " + KPIM : : emailParseResultToString ( errorCode ) +
" </p></qt> " ) ;
KMessageBox : : sorry ( parent , errorMsg , i18n ( " Invalid Email Address " ) ) ;
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : doSend ( KMail : : MessageSender : : SendMethod method ,
KMComposeWin : : SaveIn saveIn )
{
if ( method ! = KMail : : MessageSender : : SendLater & & kmkernel - > isOffline ( ) ) {
KMessageBox : : information ( this ,
i18n ( " KMail is currently in offline mode, "
" your messages will be kept in the outbox until you go online. " ) ,
i18n ( " Online/Offline " ) , " kmailIsOffline " ) ;
mSendMethod = KMail : : MessageSender : : SendLater ;
} else {
mSendMethod = method ;
}
mSaveIn = saveIn ;
if ( saveIn = = KMComposeWin : : None ) {
if ( KPIM : : getFirstEmailAddress ( from ( ) ) . isEmpty ( ) ) {
if ( ! ( mShowHeaders & HDR_FROM ) ) {
mShowHeaders | = HDR_FROM ;
rethinkFields ( false ) ;
}
mEdtFrom - > setFocus ( ) ;
KMessageBox : : sorry ( this ,
i18n ( " You must enter your email address in the "
" From: field. You should also set your email "
" address for all identities, so that you do "
" not have to enter it for each message. " ) ) ;
return ;
}
if ( to ( ) . isEmpty ( ) )
{
if ( cc ( ) . isEmpty ( ) & & bcc ( ) . isEmpty ( ) ) {
if ( mEdtTo ) mEdtTo - > setFocus ( ) ;
KMessageBox : : information ( this ,
i18n ( " You must specify at least one receiver, "
" either in the To: field or as CC or as BCC. " ) ) ;
return ;
}
else {
if ( mEdtTo ) mEdtTo - > setFocus ( ) ;
int rc =
KMessageBox : : questionYesNo ( this ,
i18n ( " To field is missing. "
" Send message anyway? " ) ,
i18n ( " No To: specified " ) ) ;
if ( rc = = KMessageBox : : No ) {
return ;
}
}
}
// Validate the To:, CC: and BCC fields
if ( ! validateAddresses ( this , to ( ) . stripWhiteSpace ( ) ) ) {
return ;
}
if ( ! validateAddresses ( this , cc ( ) . stripWhiteSpace ( ) ) ) {
return ;
}
if ( ! validateAddresses ( this , bcc ( ) . stripWhiteSpace ( ) ) ) {
return ;
}
if ( subject ( ) . isEmpty ( ) )
{
mEdtSubject - > setFocus ( ) ;
int rc =
KMessageBox : : questionYesNo ( this ,
i18n ( " You did not specify a subject. "
" Send message anyway? " ) ,
i18n ( " No Subject Specified " ) ,
i18n ( " S&end as Is " ) ,
i18n ( " &Specify the Subject " ) ,
" no_subject_specified " ) ;
if ( rc = = KMessageBox : : No )
{
return ;
}
}
if ( userForgotAttachment ( ) )
return ;
}
KCursorSaver busy ( KBusyPtr : : busy ( ) ) ;
mMsg - > setDateToday ( ) ;
// If a user sets up their outgoing messages preferences wrong and then
// sends mail that gets 'stuck' in their outbox, they should be able to
// rectify the problem by editing their outgoing preferences and
// resending.
// Hence this following conditional
TQString hf = mMsg - > headerField ( " X-KMail-Transport " ) ;
if ( ( mTransport - > currentText ( ) ! = mTransport - > text ( 0 ) ) | |
( ! hf . isEmpty ( ) & & ( hf ! = mTransport - > text ( 0 ) ) ) )
mMsg - > setHeaderField ( " X-KMail-Transport " , mTransport - > currentText ( ) ) ;
mDisableBreaking = ( saveIn ! = KMComposeWin : : None ) ;
const bool neverEncrypt = ( mDisableBreaking & & GlobalSettings : : self ( ) - > neverEncryptDrafts ( ) )
| | mSigningAndEncryptionExplicitlyDisabled ;
connect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_SLOT ( slotContinueDoSend ( bool ) ) ) ;
if ( mEditor - > textFormat ( ) = = TQt : : RichText )
mMsg - > setHeaderField ( " X-KMail-Markup " , " true " ) ;
else
mMsg - > removeHeaderField ( " X-KMail-Markup " ) ;
if ( mEditor - > textFormat ( ) = = TQt : : RichText & & inlineSigningEncryptionSelected ( ) ) {
TQString keepBtnText = mEncryptAction - > isChecked ( ) ?
mSignAction - > isChecked ( ) ? i18n ( " &Keep markup, do not sign/encrypt " )
: i18n ( " &Keep markup, do not encrypt " )
: i18n ( " &Keep markup, do not sign " ) ;
TQString yesBtnText = mEncryptAction - > isChecked ( ) ?
mSignAction - > isChecked ( ) ? i18n ( " Sign/Encrypt (delete markup) " )
: i18n ( " Encrypt (delete markup) " )
: i18n ( " Sign (delete markup) " ) ;
int ret = KMessageBox : : warningYesNoCancel ( this ,
i18n ( " <qt><p>Inline signing/encrypting of HTML messages is not possible;</p> "
" <p>do you want to delete your markup?</p></qt> " ) ,
i18n ( " Sign/Encrypt Message? " ) ,
KGuiItem ( yesBtnText ) ,
KGuiItem ( keepBtnText ) ) ;
if ( KMessageBox : : Cancel = = ret )
return ;
if ( KMessageBox : : No = = ret ) {
mEncryptAction - > setChecked ( false ) ;
mSignAction - > setChecked ( false ) ;
}
else {
toggleMarkup ( false ) ;
}
}
if ( neverEncrypt & & saveIn ! = KMComposeWin : : None ) {
// we can't use the state of the mail itself, to remember the
// signing and encryption state, so let's add a header instead
mMsg - > setHeaderField ( " X-KMail-SignatureActionEnabled " , mSignAction - > isChecked ( ) ? " true " : " false " ) ;
mMsg - > setHeaderField ( " X-KMail-EncryptActionEnabled " , mEncryptAction - > isChecked ( ) ? " true " : " false " ) ;
mMsg - > setHeaderField ( " X-KMail-CryptoMessageFormat " , TQString : : number ( cryptoMessageFormat ( ) ) ) ;
} else {
mMsg - > removeHeaderField ( " X-KMail-SignatureActionEnabled " ) ;
mMsg - > removeHeaderField ( " X-KMail-EncryptActionEnabled " ) ;
mMsg - > removeHeaderField ( " X-KMail-CryptoMessageFormat " ) ;
}
kdDebug ( 5006 ) < < " KMComposeWin::doSend() - calling applyChanges() "
< < endl ;
applyChanges ( neverEncrypt ) ;
}
bool KMComposeWin : : saveDraftOrTemplate ( const TQString & folderName ,
KMMessage * msg )
{
KMFolder * theFolder = 0 , * imapTheFolder = 0 ;
// get the draftsFolder
if ( ! folderName . isEmpty ( ) ) {
theFolder = kmkernel - > folderMgr ( ) - > findIdString ( folderName ) ;
if ( theFolder = = 0 )
// This is *NOT* supposed to be "imapDraftsFolder", because a
// dIMAP folder works like a normal folder
theFolder = kmkernel - > dimapFolderMgr ( ) - > findIdString ( folderName ) ;
if ( theFolder = = 0 )
imapTheFolder = kmkernel - > imapFolderMgr ( ) - > findIdString ( folderName ) ;
if ( ! theFolder & & ! imapTheFolder ) {
const KPIM : : Identity & id = kmkernel - > identityManager ( )
- > identityForUoidOrDefault ( msg - > headerField ( " X-KMail-Identity " ) . stripWhiteSpace ( ) . toUInt ( ) ) ;
KMessageBox : : information ( 0 ,
i18n ( " The custom drafts or templates folder for "
" identify \" %1 \" does not exist (anymore); "
" therefore, the default drafts or templates "
" folder will be used. " )
. arg ( id . identityName ( ) ) ) ;
}
}
if ( imapTheFolder & & imapTheFolder - > noContent ( ) )
imapTheFolder = 0 ;
bool didOpen = false ;
if ( theFolder = = 0 ) {
theFolder = ( mSaveIn = = KMComposeWin : : Drafts ?
kmkernel - > draftsFolder ( ) : kmkernel - > templatesFolder ( ) ) ;
} else {
//XXX this looks really, really fishy
theFolder - > open ( " composer " ) ;
didOpen = true ;
}
kdDebug ( 5006 ) < < k_funcinfo < < " theFolder= " < < theFolder - > name ( ) < < endl ;
if ( imapTheFolder )
kdDebug ( 5006 ) < < k_funcinfo < < " imapTheFolder= " < < imapTheFolder - > name ( ) < < endl ;
bool sentOk = ! ( theFolder - > addMsg ( msg ) ) ;
// Ensure the message is correctly and fully parsed
theFolder - > unGetMsg ( theFolder - > count ( ) - 1 ) ;
msg = theFolder - > getMsg ( theFolder - > count ( ) - 1 ) ;
// Does that assignment needs to be propagated out to the caller?
// Assuming the send is OK, the iterator is set to 0 immediately afterwards.
if ( imapTheFolder ) {
// move the message to the imap-folder and highlight it
imapTheFolder - > moveMsg ( msg ) ;
( static_cast < KMFolderImap * > ( imapTheFolder - > storage ( ) ) ) - > getFolder ( ) ;
}
if ( didOpen )
theFolder - > close ( " composer " ) ;
return sentOk ;
}
void KMComposeWin : : slotContinueDoSend ( bool sentOk )
{
kdDebug ( 5006 ) < < " KMComposeWin::slotContinueDoSend( " < < sentOk < < " ) "
< < endl ;
disconnect ( this , TQT_SIGNAL ( applyChangesDone ( bool ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( slotContinueDoSend ( bool ) ) ) ;
if ( ! sentOk ) {
mDisableBreaking = false ;
return ;
}
for ( TQValueVector < KMMessage * > : : iterator it = mComposedMessages . begin ( ) ; it ! = mComposedMessages . end ( ) ; + + it ) {
// remove fields that contain no data (e.g. an empty Cc: or Bcc:)
( * it ) - > cleanupHeader ( ) ;
// needed for imap
( * it ) - > setComplete ( true ) ;
if ( mSaveIn = = KMComposeWin : : Drafts ) {
sentOk = saveDraftOrTemplate ( ( * it ) - > drafts ( ) , ( * it ) ) ;
} else if ( mSaveIn = = KMComposeWin : : Templates ) {
sentOk = saveDraftOrTemplate ( ( * it ) - > templates ( ) , ( * it ) ) ;
} else {
( * it ) - > setTo ( KMMessage : : expandAliases ( to ( ) ) ) ;
( * it ) - > setCc ( KMMessage : : expandAliases ( cc ( ) ) ) ;
if ( ! mComposer - > originalBCC ( ) . isEmpty ( ) )
( * it ) - > setBcc ( KMMessage : : expandAliases ( mComposer - > originalBCC ( ) ) ) ;
TQString recips = ( * it ) - > headerField ( " X-KMail-Recipients " ) ;
if ( ! recips . isEmpty ( ) ) {
( * it ) - > setHeaderField ( " X-KMail-Recipients " , KMMessage : : expandAliases ( recips ) , KMMessage : : Address ) ;
}
( * it ) - > cleanupHeader ( ) ;
sentOk = kmkernel - > msgSender ( ) - > send ( ( * it ) , mSendMethod ) ;
}
if ( ! sentOk )
return ;
* it = 0 ; // don't kill it later...
}
RecentAddresses : : self ( KMKernel : : config ( ) ) - > add ( bcc ( ) ) ;
RecentAddresses : : self ( KMKernel : : config ( ) ) - > add ( cc ( ) ) ;
RecentAddresses : : self ( KMKernel : : config ( ) ) - > add ( to ( ) ) ;
setModified ( false ) ;
mAutoDeleteMsg = false ;
mFolder = 0 ;
cleanupAutoSave ( ) ;
close ( ) ;
return ;
}
bool KMComposeWin : : checkTransport ( ) const
{
if ( KMail : : TransportManager : : transportNames ( ) . isEmpty ( ) ) {
KMessageBox : : information ( mMainWidget ,
i18n ( " Please create an account for sending and try again. " ) ) ;
return false ;
}
return true ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSendLater ( )
{
if ( ! checkTransport ( ) )
return ;
if ( ! checkRecipientNumber ( ) )
return ;
if ( mEditor - > checkExternalEditorFinished ( ) )
doSend ( KMail : : MessageSender : : SendLater ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSaveDraft ( ) {
if ( mEditor - > checkExternalEditorFinished ( ) )
doSend ( KMail : : MessageSender : : SendLater , KMComposeWin : : Drafts ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSaveTemplate ( ) {
if ( mEditor - > checkExternalEditorFinished ( ) )
doSend ( KMail : : MessageSender : : SendLater , KMComposeWin : : Templates ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSendNowVia ( int item )
{
TQStringList availTransports = KMail : : TransportManager : : transportNames ( ) ;
TQString customTransport = availTransports [ item ] ;
mTransport - > setCurrentText ( customTransport ) ;
slotSendNow ( ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSendLaterVia ( int item )
{
TQStringList availTransports = KMail : : TransportManager : : transportNames ( ) ;
TQString customTransport = availTransports [ item ] ;
mTransport - > setCurrentText ( customTransport ) ;
slotSendLater ( ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotSendNow ( ) {
if ( ! mEditor - > checkExternalEditorFinished ( ) )
return ;
if ( ! checkTransport ( ) )
return ;
if ( ! checkRecipientNumber ( ) )
return ;
if ( GlobalSettings : : self ( ) - > confirmBeforeSend ( ) )
{
int rc = KMessageBox : : warningYesNoCancel ( mMainWidget ,
i18n ( " About to send email... " ) ,
i18n ( " Send Confirmation " ) ,
i18n ( " &Send Now " ) ,
i18n ( " Send &Later " ) ) ;
if ( rc = = KMessageBox : : Yes )
doSend ( KMail : : MessageSender : : SendImmediate ) ;
else if ( rc = = KMessageBox : : No )
doSend ( KMail : : MessageSender : : SendLater ) ;
}
else
doSend ( KMail : : MessageSender : : SendImmediate ) ;
}
//----------------------------------------------------------------------------
bool KMComposeWin : : checkRecipientNumber ( ) const
{
uint thresHold = GlobalSettings : : self ( ) - > recipientThreshold ( ) ;
if ( mCheckForRecipients & &
GlobalSettings : : self ( ) - > tooManyRecipients ( ) & &
mRecipientsEditor - > recipients ( ) . count ( ) > thresHold ) {
if ( KMessageBox : : questionYesNo ( mMainWidget ,
i18n ( " You are trying to send the mail to more than %1 recipients. Send message anyway? " ) . arg ( thresHold ) ,
i18n ( " Too many receipients " ) ,
i18n ( " &Send as Is " ) ,
i18n ( " &Edit Recipients " ) ) = = KMessageBox : : No ) {
return false ;
}
}
return true ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotAppendSignature ( )
{
insertSignature ( ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotPrependSignature ( )
{
insertSignature ( Prepend ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : slotInsertSignatureAtCursor ( )
{
insertSignature ( AtCursor ) ;
}
//----------------------------------------------------------------------------
void KMComposeWin : : insertSignature ( SignaturePlacement placement )
{
bool mod = mEditor - > isModified ( ) ;
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - >
identityForUoidOrDefault ( mIdentity - > currentIdentity ( ) ) ;
mOldSigText = GlobalSettings : : self ( ) - > prependSignature ( ) ? ident . signature ( ) . rawText ( ) : ident . signatureText ( ) ;
if ( ! mOldSigText . isEmpty ( ) )
{
mEditor - > sync ( ) ;
int paragraph , index ;
mEditor - > getCursorPosition ( & paragraph , & index ) ;
index = mEditor - > indexOfCurrentLineStart ( paragraph , index ) ;
switch ( placement ) {
case Append :
mEditor - > setText ( mEditor - > text ( ) + mOldSigText ) ;
break ;
case Prepend :
mOldSigText = " \n \n " + mOldSigText + " \n " ;
mEditor - > insertAt ( mOldSigText , paragraph , index ) ;
break ;
case AtCursor :
// If there is text in the same line, add a newline so that the stuff in
// the current line moves after the signature. Also remove a leading newline, it is not
// needed here.
if ( mEditor - > paragraphLength ( paragraph ) > 0 )
mOldSigText = mOldSigText + " \n " ;
if ( mOldSigText . startsWith ( " \n " ) )
mOldSigText = mOldSigText . remove ( 0 , 1 ) ;
// If we are inserting into a wordwrapped line, add a newline at the start to make
// the text edit hard-wrap the line here
if ( index ! = 0 )
mOldSigText = " \n " + mOldSigText ;
mEditor - > insertAt ( mOldSigText , paragraph , index ) ;
break ;
}
mEditor - > update ( ) ;
mEditor - > setModified ( mod ) ;
if ( mPreserveUserCursorPosition ) {
mEditor - > setCursorPositionFromStart ( ( unsigned int ) mMsg - > getCursorPos ( ) ) ;
// Only keep the cursor from the mMsg *once* based on the
// preserve-cursor-position setting; this handles the case where
// the message comes from a template with a specific cursor
// position set and the signature is appended automatically.
mPreserveUserCursorPosition = false ;
} else {
// for append and prepend, move the cursor to 0,0, for insertAt,
// keep it in the same row, but move to first column
if ( index = = 0 ) {
mEditor - > setCursorPosition ( paragraph , 0 ) ;
} else {
// For word-wrapped lines, we have created a new paragraph, so change to that one
mEditor - > setCursorPosition ( paragraph + 1 , 0 ) ;
}
if ( placement = = Prepend | | placement = = Append )
mEditor - > setContentsPos ( 0 , 0 ) ;
}
mEditor - > sync ( ) ;
}
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotHelp ( )
{
kapp - > invokeHelp ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotCleanSpace ( )
{
// Originally we simply used the KEdit::cleanWhiteSpace() method,
// but that code doesn't handle quoted-lines or signatures, so instead
// we now simply use regexp's to squeeze sequences of tabs and spaces
// into a single space, and make sure all our lines are single-spaced.
//
// Yes, extra space in a quote string is squeezed.
// Signatures are respected (i.e. not cleaned).
TQString s ;
if ( mEditor - > hasMarkedText ( ) ) {
s = mEditor - > markedText ( ) ;
if ( s . isEmpty ( ) )
return ;
} else {
s = mEditor - > text ( ) ;
}
// Remove the signature for now.
TQString sig ;
bool restore = false ;
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - > identityForUoid ( mId ) ;
if ( ! ident . isNull ( ) ) {
sig = ident . signatureText ( ) ;
if ( ! sig . isEmpty ( ) ) {
if ( s . endsWith ( sig ) ) {
s . truncate ( s . length ( ) - sig . length ( ) ) ;
restore = true ;
}
}
}
// Squeeze tabs and spaces
TQRegExp squeeze ( " [ \t ]+ " ) ;
s . replace ( squeeze , TQChar ( ' ' ) ) ;
// Remove trailing whitespace
TQRegExp trailing ( " \\ s+$ " ) ;
s . replace ( trailing , TQChar ( ' \n ' ) ) ;
// Single space lines
TQRegExp singleSpace ( " [ \n ]{2,} " ) ;
s . replace ( singleSpace , TQChar ( ' \n ' ) ) ;
// Restore the signature
if ( restore )
s . append ( sig ) ;
// Put the new text in place.
// The lines below do not clear the undo history, but unfortuately cause
// the side-effect that you need to press Ctrl-Z twice (first Ctrl-Z will
// show cleared text area) to get back the original, pre-cleaned text.
// If you use mEditor->setText( s ) then the undo history is cleared so
// that isn't a good solution either.
// TODO: is TQt4 better at handling the undo history??
if ( ! mEditor - > hasMarkedText ( ) )
mEditor - > clear ( ) ;
mEditor - > insert ( s ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotToggleMarkup ( )
{
if ( markupAction - > isChecked ( ) ) {
mHtmlMarkup = true ;
toolBar ( " htmlToolBar " ) - > show ( ) ;
// markup will be toggled as soon as markup is actually used
fontChanged ( mEditor - > currentFont ( ) ) ; // set buttons in correct position
mSaveFont = mEditor - > currentFont ( ) ;
}
else
toggleMarkup ( false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : toggleMarkup ( bool markup )
{
if ( markup ) {
if ( ! mUseHTMLEditor ) {
kdDebug ( 5006 ) < < " setting RichText editor " < < endl ;
mUseHTMLEditor = true ; // set it directly to true. setColor hits another toggleMarkup
mHtmlMarkup = true ;
// set all highlighted text caused by spelling back to black
int paraFrom , indexFrom , paraTo , indexTo ;
mEditor - > getSelection ( & paraFrom , & indexFrom , & paraTo , & indexTo ) ;
mEditor - > selectAll ( ) ;
// save the buttonstates because setColor calls fontChanged
bool _bold = textBoldAction - > isChecked ( ) ;
bool _italic = textItalicAction - > isChecked ( ) ;
mEditor - > setColor ( TQColor ( 0 , 0 , 0 ) ) ;
textBoldAction - > setChecked ( _bold ) ;
textItalicAction - > setChecked ( _italic ) ;
mEditor - > setSelection ( paraFrom , indexFrom , paraTo , indexTo ) ;
mEditor - > setTextFormat ( TQt : : RichText ) ;
mEditor - > setModified ( true ) ;
markupAction - > setChecked ( true ) ;
toolBar ( " htmlToolBar " ) - > show ( ) ;
mEditor - > deleteAutoSpellChecking ( ) ;
mAutoSpellCheckingAction - > setChecked ( false ) ;
slotAutoSpellCheckingToggled ( false ) ;
}
} else { // markup is to be turned off
kdDebug ( 5006 ) < < " setting PlainText editor " < < endl ;
mHtmlMarkup = false ;
toolBar ( " htmlToolBar " ) - > hide ( ) ;
if ( mUseHTMLEditor ) { // it was turned on
mUseHTMLEditor = false ;
mEditor - > setTextFormat ( TQt : : PlainText ) ;
TQString text = mEditor - > text ( ) ;
mEditor - > setText ( text ) ; // otherwise the text still looks formatted
mEditor - > setModified ( true ) ;
slotAutoSpellCheckingToggled ( true ) ;
}
}
}
void KMComposeWin : : htmlToolBarVisibilityChanged ( bool visible )
{
// disable markup if the user hides the HTML toolbar
if ( ! visible ) {
markupAction - > setChecked ( false ) ;
toggleMarkup ( false ) ;
}
}
void KMComposeWin : : slotSubjectTextSpellChecked ( )
{
mSubjectTextWasSpellChecked = true ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotAutoSpellCheckingToggled ( bool on )
{
if ( mEditor - > autoSpellChecking ( on ) = = - 1 ) {
mAutoSpellCheckingAction - > setChecked ( false ) ; // set it to false again
}
TQString temp ;
if ( on )
temp = i18n ( " Spellcheck: on " ) ;
else
temp = i18n ( " Spellcheck: off " ) ;
statusBar ( ) - > changeItem ( temp , 3 ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSpellcheck ( )
{
if ( mSpellCheckInProgress ) return ;
mSubjectTextWasSpellChecked = false ;
mSpellCheckInProgress = true ;
/*
connect ( mEditor , TQT_SIGNAL ( spellcheck_progress ( unsigned ) ) ,
this , TQT_SLOT ( spell_progress ( unsigned ) ) ) ;
*/
mEditor - > spellcheck ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotUpdateSignatureActions ( )
{
//Check if an identity has signature or not and turn on/off actions in the
//edit menu accordingly.
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - > identityForUoidOrDefault ( mIdentity - > currentIdentity ( ) ) ;
TQString sig = ident . signatureText ( ) ;
if ( sig . isEmpty ( ) ) {
mAppendSignatureAction - > setEnabled ( false ) ;
mPrependSignatureAction - > setEnabled ( false ) ;
mInsertSignatureAction - > setEnabled ( false ) ;
}
else {
mAppendSignatureAction - > setEnabled ( true ) ;
mPrependSignatureAction - > setEnabled ( true ) ;
mInsertSignatureAction - > setEnabled ( true ) ;
}
}
void KMComposeWin : : polish ( )
{
// Ensure the html toolbar is appropriately shown/hidden
markupAction - > setChecked ( mHtmlMarkup ) ;
if ( mHtmlMarkup )
toolBar ( " htmlToolBar " ) - > show ( ) ;
else
toolBar ( " htmlToolBar " ) - > hide ( ) ;
KMail : : Composer : : polish ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSpellcheckDone ( int result )
{
kdDebug ( 5006 ) < < " spell check complete: result = " < < result < < endl ;
mSpellCheckInProgress = false ;
switch ( result )
{
case KS_CANCEL :
statusBar ( ) - > changeItem ( i18n ( " Spell check canceled. " ) , 0 ) ;
break ;
case KS_STOP :
statusBar ( ) - > changeItem ( i18n ( " Spell check stopped. " ) , 0 ) ;
break ;
default :
statusBar ( ) - > changeItem ( i18n ( " Spell check complete. " ) , 0 ) ;
break ;
}
TQTimer : : singleShot ( 2000 , this , TQT_SLOT ( slotSpellcheckDoneClearStatus ( ) ) ) ;
}
void KMComposeWin : : slotSpellcheckDoneClearStatus ( )
{
statusBar ( ) - > changeItem ( " " , 0 ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotIdentityChanged ( uint uoid )
{
const KPIM : : Identity & ident =
kmkernel - > identityManager ( ) - > identityForUoid ( uoid ) ;
if ( ident . isNull ( ) ) return ;
//Turn on/off signature actions if identity has no signature.
slotUpdateSignatureActions ( ) ;
if ( ! ident . fullEmailAddr ( ) . isNull ( ) )
mEdtFrom - > setText ( ident . fullEmailAddr ( ) ) ;
// make sure the From field is shown if it does not contain a valid email address
if ( KPIM : : getFirstEmailAddress ( from ( ) ) . isEmpty ( ) )
mShowHeaders | = HDR_FROM ;
if ( mEdtReplyTo ) mEdtReplyTo - > setText ( ident . replyToAddr ( ) ) ;
if ( mRecipientsEditor ) {
// remove BCC of old identity and add BCC of new identity (if they differ)
const KPIM : : Identity & oldIdentity =
kmkernel - > identityManager ( ) - > identityForUoidOrDefault ( mId ) ;
if ( oldIdentity . bcc ( ) ! = ident . bcc ( ) ) {
mRecipientsEditor - > removeRecipient ( oldIdentity . bcc ( ) , Recipient : : Bcc ) ;
mRecipientsEditor - > addRecipient ( ident . bcc ( ) , Recipient : : Bcc ) ;
mRecipientsEditor - > setFocusBottom ( ) ;
}
}
// don't overwrite the BCC field under certain circomstances
// NOT edited and preset BCC from the identity
if ( mEdtBcc & & ! mEdtBcc - > edited ( ) & & ! ident . bcc ( ) . isEmpty ( ) ) {
// BCC NOT empty AND contains a diff adress then the preset BCC
// of the new identity
if ( ! mEdtBcc - > text ( ) . isEmpty ( ) & & mEdtBcc - > text ( ) ! = ident . bcc ( ) & & ! mEdtBcc - > edited ( ) ) {
mEdtBcc - > setText ( ident . bcc ( ) ) ;
} else {
// user type into the editbox an address that != to the preset bcc
// of the identity, we assume that since the user typed it
// they want to keep it
if ( mEdtBcc - > text ( ) ! = ident . bcc ( ) & & ! mEdtBcc - > text ( ) . isEmpty ( ) ) {
TQString temp_string ( mEdtBcc - > text ( ) + TQString : : fromLatin1 ( " , " ) + ident . bcc ( ) ) ;
mEdtBcc - > setText ( temp_string ) ;
} else {
// if the user typed the same address as the preset BCC
// from the identity we will overwrite it to avoid duplicates.
mEdtBcc - > setText ( ident . bcc ( ) ) ;
}
}
}
// user edited the bcc box and has a preset bcc in the identity
// we will append whatever the user typed to the preset address
// allowing the user to keep all addresses
if ( mEdtBcc & & mEdtBcc - > edited ( ) & & ! ident . bcc ( ) . isEmpty ( ) ) {
if ( ! mEdtBcc - > text ( ) . isEmpty ( ) ) {
TQString temp_string ( mEdtBcc - > text ( ) + TQString : : fromLatin1 ( " , " ) + ident . bcc ( ) ) ;
mEdtBcc - > setText ( temp_string ) ;
} else {
mEdtBcc - > setText ( ident . bcc ( ) ) ;
}
}
// user typed nothing and the identity does not have a preset bcc
// we then reset the value to get rid of any previous
// values if the user changed identity mid way through.
if ( mEdtBcc & & ! mEdtBcc - > edited ( ) & & ident . bcc ( ) . isEmpty ( ) ) {
mEdtBcc - > setText ( ident . bcc ( ) ) ;
}
// make sure the BCC field is shown because else it's ignored
if ( ! ident . bcc ( ) . isEmpty ( ) ) {
mShowHeaders | = HDR_BCC ;
}
if ( ident . organization ( ) . isEmpty ( ) )
mMsg - > removeHeaderField ( " Organization " ) ;
else
mMsg - > setHeaderField ( " Organization " , ident . organization ( ) ) ;
if ( ! ident . isXFaceEnabled ( ) | | ident . xface ( ) . isEmpty ( ) )
mMsg - > removeHeaderField ( " X-Face " ) ;
else
{
TQString xface = ident . xface ( ) ;
if ( ! xface . isEmpty ( ) )
{
int numNL = ( xface . length ( ) - 1 ) / 70 ;
for ( int i = numNL ; i > 0 ; - - i )
xface . insert ( i * 70 , " \n \t " ) ;
mMsg - > setHeaderField ( " X-Face " , xface ) ;
}
}
if ( ! mBtnTransport - > isChecked ( ) & & ! mIgnoreStickyFields ) {
TQString transp = ident . transport ( ) ;
if ( transp . isEmpty ( ) )
{
mMsg - > removeHeaderField ( " X-KMail-Transport " ) ;
transp = GlobalSettings : : self ( ) - > defaultTransport ( ) ;
}
else
mMsg - > setHeaderField ( " X-KMail-Transport " , transp ) ;
setTransport ( transp ) ;
}
if ( ! mBtnDictionary - > isChecked ( ) & & ! mIgnoreStickyFields ) {
mDictionaryCombo - > setCurrentByDictionary ( ident . dictionary ( ) ) ;
}
if ( ! mBtnFcc - > isChecked ( ) & & ! mPreventFccOverwrite ) {
setFcc ( ident . fcc ( ) ) ;
}
TQString edtText = mEditor - > text ( ) ;
if ( mOldSigText . isEmpty ( ) ) {
const KPIM : : Identity & id =
kmkernel - >
identityManager ( ) - >
identityForUoidOrDefault ( mMsg - > headerField ( " X-KMail-Identity " ) .
stripWhiteSpace ( ) . toUInt ( ) ) ;
mOldSigText = GlobalSettings : : self ( ) - > prependSignature ( ) ? id . signature ( ) . rawText ( ) : id . signatureText ( ) ;
}
if ( ! GlobalSettings : : prependSignature ( ) ) {
// try to truncate the old sig
// First remove any trailing whitespace
while ( ! edtText . isEmpty ( ) & & edtText [ edtText . length ( ) - 1 ] . isSpace ( ) )
edtText . truncate ( edtText . length ( ) - 1 ) ;
// From the sig too, just in case
while ( ! mOldSigText . isEmpty ( ) & & mOldSigText [ mOldSigText . length ( ) - 1 ] . isSpace ( ) )
mOldSigText . truncate ( mOldSigText . length ( ) - 1 ) ;
if ( edtText . endsWith ( mOldSigText ) )
edtText . truncate ( edtText . length ( ) - mOldSigText . length ( ) ) ;
// now append the new sig
mOldSigText = ident . signatureText ( ) ;
if ( ( ! mOldSigText . isEmpty ( ) ) & &
( GlobalSettings : : self ( ) - > autoTextSignature ( ) = = " auto " ) ) {
edtText . append ( mOldSigText ) ;
}
mEditor - > setText ( edtText ) ;
} else {
const int pos = edtText . find ( mOldSigText ) ;
if ( pos > = 0 & & ! mOldSigText . isEmpty ( ) ) {
const int oldLength = mOldSigText . length ( ) ;
mOldSigText = " \n \n " + ident . signature ( ) . rawText ( ) + " \n " ; // see insertSignature()
edtText = edtText . replace ( pos , oldLength , mOldSigText ) ;
mEditor - > setText ( edtText ) ;
} else {
insertSignature ( Append ) ;
}
}
// disable certain actions if there is no PGP user identity set
// for this profile
bool bNewIdentityHasSigningKey = ! ident . pgpSigningKey ( ) . isEmpty ( ) | | ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
bool bNewIdentityHasEncryptionKey = ! ident . pgpSigningKey ( ) . isEmpty ( ) | | ! ident . smimeSigningKey ( ) . isEmpty ( ) ;
mAttachMPK - > setEnabled ( Kleo : : CryptoBackendFactory : : instance ( ) - > openpgp ( ) & &
! ident . pgpEncryptionKey ( ) . isEmpty ( ) ) ;
// save the state of the sign and encrypt button
if ( ! bNewIdentityHasEncryptionKey & & mLastIdentityHasEncryptionKey ) {
mLastEncryptActionState = mEncryptAction - > isChecked ( ) ;
setEncryption ( false ) ;
}
if ( ! bNewIdentityHasSigningKey & & mLastIdentityHasSigningKey ) {
mLastSignActionState = mSignAction - > isChecked ( ) ;
setSigning ( false ) ;
}
// restore the last state of the sign and encrypt button
if ( bNewIdentityHasEncryptionKey & & ! mLastIdentityHasEncryptionKey )
setEncryption ( mLastEncryptActionState ) ;
if ( bNewIdentityHasSigningKey & & ! mLastIdentityHasSigningKey )
setSigning ( mLastSignActionState ) ;
mLastIdentityHasSigningKey = bNewIdentityHasSigningKey ;
mLastIdentityHasEncryptionKey = bNewIdentityHasEncryptionKey ;
setModified ( true ) ;
mId = uoid ;
// make sure the From and BCC fields are shown if necessary
rethinkFields ( false ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotSpellcheckConfig ( )
{
KDialogBase dlg ( KDialogBase : : Plain , i18n ( " Spellchecker " ) ,
KDialogBase : : Ok | KDialogBase : : Cancel , KDialogBase : : Ok ,
TQT_TQWIDGET ( this ) , 0 , true , true ) ;
KWin twin ;
TQTabDialog qtd ( this , " tabdialog " , true ) ;
KSpellConfig mKSpellConfig ( & qtd ) ;
mKSpellConfig . layout ( ) - > setMargin ( KDialog : : marginHint ( ) ) ;
qtd . addTab ( & mKSpellConfig , i18n ( " Spellchecker " ) ) ;
qtd . setCancelButton ( ) ;
twin . setIcons ( qtd . winId ( ) , kapp - > icon ( ) , kapp - > miniIcon ( ) ) ;
qtd . setCancelButton ( KStdGuiItem : : cancel ( ) . text ( ) ) ;
qtd . setOkButton ( KStdGuiItem : : ok ( ) . text ( ) ) ;
if ( qtd . exec ( ) )
mKSpellConfig . writeGlobalSettings ( ) ;
}
//-----------------------------------------------------------------------------
void KMComposeWin : : slotStatusMessage ( const TQString & message )
{
statusBar ( ) - > changeItem ( message , 0 ) ;
}
void KMComposeWin : : slotEditToolbars ( )
{
saveMainWindowSettings ( KMKernel : : config ( ) , " Composer " ) ;
KEditToolbar dlg ( guiFactory ( ) , this ) ;
connect ( & dlg , TQT_SIGNAL ( newToolbarConfig ( ) ) ,
TQT_SLOT ( slotUpdateToolbars ( ) ) ) ;
dlg . exec ( ) ;
}
void KMComposeWin : : slotUpdateToolbars ( )
{
createGUI ( " kmcomposerui.rc " ) ;
applyMainWindowSettings ( KMKernel : : config ( ) , " Composer " ) ;
}
void KMComposeWin : : slotEditKeys ( )
{
KKeyDialog : : configure ( actionCollection ( ) ,
false /*don't allow one-letter shortcuts*/
) ;
}
void KMComposeWin : : setReplyFocus ( bool hasMessage )
{
mEditor - > setFocus ( ) ;
if ( hasMessage ) {
if ( mMsg - > getCursorPos ( ) ) {
mEditor - > setCursorPositionFromStart ( ( unsigned int ) mMsg - > getCursorPos ( ) ) ;
} else {
mEditor - > setCursorPosition ( 1 , 0 ) ;
}
}
}
void KMComposeWin : : setFocusToSubject ( )
{
mEdtSubject - > setFocus ( ) ;
}
int KMComposeWin : : autoSaveInterval ( ) const
{
return GlobalSettings : : self ( ) - > autosaveInterval ( ) * 1000 * 60 ;
}
void KMComposeWin : : initAutoSave ( )
{
kdDebug ( 5006 ) < < k_funcinfo < < endl ;
// make sure the autosave folder exists
KMFolderMaildir : : createMaildirFolders ( KMKernel : : localDataPath ( ) + " autosave " ) ;
if ( mAutoSaveFilename . isEmpty ( ) ) {
mAutoSaveFilename = KMFolderMaildir : : constructValidFileName ( ) ;
}
updateAutoSave ( ) ;
}
void KMComposeWin : : updateAutoSave ( )
{
if ( autoSaveInterval ( ) = = 0 ) {
delete mAutoSaveTimer ; mAutoSaveTimer = 0 ;
}
else {
if ( ! mAutoSaveTimer ) {
mAutoSaveTimer = new TQTimer ( this , " mAutoSaveTimer " ) ;
connect ( mAutoSaveTimer , TQT_SIGNAL ( timeout ( ) ) ,
TQT_TQOBJECT ( this ) , TQT_SLOT ( autoSaveMessage ( ) ) ) ;
}
mAutoSaveTimer - > start ( autoSaveInterval ( ) ) ;
}
}
void KMComposeWin : : setAutoSaveFilename ( const TQString & filename )
{
mAutoSaveFilename = filename ;
}
void KMComposeWin : : cleanupAutoSave ( )
{
delete mAutoSaveTimer ; mAutoSaveTimer = 0 ;
if ( ! mAutoSaveFilename . isEmpty ( ) ) {
kdDebug ( 5006 ) < < k_funcinfo < < " deleting autosave file "
< < mAutoSaveFilename < < endl ;
KMFolderMaildir : : removeFile ( KMKernel : : localDataPath ( ) + " autosave " ,
mAutoSaveFilename ) ;
mAutoSaveFilename = TQString ( ) ;
}
}
void KMComposeWin : : slotCompletionModeChanged ( TDEGlobalSettings : : Completion mode )
{
GlobalSettings : : self ( ) - > setCompletionMode ( ( int ) mode ) ;
// sync all the lineedits to the same completion mode
mEdtFrom - > setCompletionMode ( mode ) ;
mEdtReplyTo - > setCompletionMode ( mode ) ;
if ( mClassicalRecipients ) {
mEdtTo - > setCompletionMode ( mode ) ;
mEdtCc - > setCompletionMode ( mode ) ;
mEdtBcc - > setCompletionMode ( mode ) ;
} else
mRecipientsEditor - > setCompletionMode ( mode ) ;
}
void KMComposeWin : : slotConfigChanged ( )
{
readConfig ( true /*reload*/ ) ;
updateAutoSave ( ) ;
rethinkFields ( ) ;
slotWordWrapToggled ( mWordWrapAction - > isChecked ( ) ) ;
}
/*
* checks if the drafts - folder has been deleted
* that is not nice so we set the system - drafts - folder
*/
void KMComposeWin : : slotFolderRemoved ( KMFolder * folder )
{
// TODO: need to handle templates here?
if ( ( mFolder ) & & ( folder - > idString ( ) = = mFolder - > idString ( ) ) )
{
mFolder = kmkernel - > draftsFolder ( ) ;
kdDebug ( 5006 ) < < " restoring drafts to " < < mFolder - > idString ( ) < < endl ;
}
if ( mMsg ) mMsg - > setParent ( 0 ) ;
}
void KMComposeWin : : editorFocusChanged ( bool gained )
{
mPasteQuotation - > setEnabled ( gained ) ;
}
void KMComposeWin : : slotSetAlwaysSend ( bool bAlways )
{
mAlwaysSend = bAlways ;
}
void KMComposeWin : : slotListAction ( const TQString & style )
{
toggleMarkup ( true ) ;
if ( style = = i18n ( " Standard " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayBlock , TQStyleSheetItem : : ListDisc ) ;
else if ( style = = i18n ( " Bulleted List (Disc) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListDisc ) ;
else if ( style = = i18n ( " Bulleted List (Circle) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListCircle ) ;
else if ( style = = i18n ( " Bulleted List (Square) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListSquare ) ;
else if ( style = = i18n ( " Ordered List (Decimal) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListDecimal ) ;
else if ( style = = i18n ( " Ordered List (Alpha lower) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListLowerAlpha ) ;
else if ( style = = i18n ( " Ordered List (Alpha upper) " ) )
mEditor - > setParagType ( TQStyleSheetItem : : DisplayListItem , TQStyleSheetItem : : ListUpperAlpha ) ;
mEditor - > viewport ( ) - > setFocus ( ) ;
}
void KMComposeWin : : slotFontAction ( const TQString & font )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setFamily ( font ) ;
mEditor - > viewport ( ) - > setFocus ( ) ;
}
void KMComposeWin : : slotSizeAction ( int size )
{
toggleMarkup ( true ) ;
mEditor - > setPointSize ( size ) ;
mEditor - > viewport ( ) - > setFocus ( ) ;
}
void KMComposeWin : : slotAlignLeft ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setAlignment ( AlignLeft ) ;
}
void KMComposeWin : : slotAlignCenter ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setAlignment ( AlignHCenter ) ;
}
void KMComposeWin : : slotAlignRight ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setAlignment ( AlignRight ) ;
}
void KMComposeWin : : slotTextBold ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setBold ( textBoldAction - > isChecked ( ) ) ;
}
void KMComposeWin : : slotTextItalic ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setItalic ( textItalicAction - > isChecked ( ) ) ;
}
void KMComposeWin : : slotTextUnder ( )
{
toggleMarkup ( true ) ;
mEditor - > TQTextEdit : : setUnderline ( textUnderAction - > isChecked ( ) ) ;
}
void KMComposeWin : : slotFormatReset ( )
{
mEditor - > setColor ( mForeColor ) ;
mEditor - > setCurrentFont ( mSaveFont ) ; // fontChanged is called now
}
void KMComposeWin : : slotTextColor ( )
{
TQColor color = mEditor - > color ( ) ;
if ( KColorDialog : : getColor ( color , this ) ) {
toggleMarkup ( true ) ;
mEditor - > setColor ( color ) ;
}
}
void KMComposeWin : : fontChanged ( const TQFont & f )
{
TQFont fontTemp = f ;
fontTemp . setBold ( true ) ;
fontTemp . setItalic ( true ) ;
TQFontInfo fontInfo ( fontTemp ) ;
if ( fontInfo . bold ( ) ) {
textBoldAction - > setChecked ( f . bold ( ) ) ;
textBoldAction - > setEnabled ( true ) ;
} else {
textBoldAction - > setEnabled ( false ) ;
}
if ( fontInfo . italic ( ) ) {
textItalicAction - > setChecked ( f . italic ( ) ) ;
textItalicAction - > setEnabled ( true ) ;
} else {
textItalicAction - > setEnabled ( false ) ;
}
textUnderAction - > setChecked ( f . underline ( ) ) ;
fontAction - > setFont ( f . family ( ) ) ;
fontSizeAction - > setFontSize ( f . pointSize ( ) ) ;
}
void KMComposeWin : : alignmentChanged ( int a )
{
//toggleMarkup();
alignLeftAction - > setChecked ( ( a = = AlignAuto ) | | ( a & AlignLeft ) ) ;
alignCenterAction - > setChecked ( ( a & AlignHCenter ) ) ;
alignRightAction - > setChecked ( ( a & AlignRight ) ) ;
}
namespace {
class TDEToggleActionResetter {
TDEToggleAction * mAction ;
bool mOn ;
public :
TDEToggleActionResetter ( TDEToggleAction * action , bool on )
: mAction ( action ) , mOn ( on ) { }
~ TDEToggleActionResetter ( ) {
if ( mAction )
mAction - > setChecked ( mOn ) ;
}
void disable ( ) { mAction = 0 ; }
} ;
}
void KMComposeWin : : slotEncryptChiasmusToggled ( bool on ) {
mEncryptWithChiasmus = false ;
if ( ! on )
return ;
TDEToggleActionResetter resetter ( mEncryptChiasmusAction , false ) ;
const Kleo : : CryptoBackend : : Protocol * chiasmus =
Kleo : : CryptoBackendFactory : : instance ( ) - > protocol ( " Chiasmus " ) ;
if ( ! chiasmus ) {
const TQString msg = Kleo : : CryptoBackendFactory : : instance ( ) - > knowsAboutProtocol ( " Chiasmus " )
? i18n ( " Please configure a Crypto Backend to use for "
" Chiasmus encryption first. \n "
" You can do this in the Crypto Backends tab of "
" the configure dialog's Security page. " )
: i18n ( " It looks as though libkleopatra was compiled without "
" Chiasmus support. You might want to recompile "
" libkleopatra with --enable-chiasmus. " ) ;
KMessageBox : : information ( this , msg , i18n ( " No Chiasmus Backend Configured " ) ) ;
return ;
}
STD_NAMESPACE_PREFIX auto_ptr < Kleo : : SpecialJob > job ( chiasmus - > specialJob ( " x-obtain-keys " , TQMap < TQString , TQVariant > ( ) ) ) ;
if ( ! job . get ( ) ) {
const TQString msg = i18n ( " Chiasmus backend does not offer the "
" \" x-obtain-keys \" function. Please report this bug. " ) ;
KMessageBox : : error ( this , msg , i18n ( " Chiasmus Backend Error " ) ) ;
return ;
}
if ( job - > exec ( ) ) {
job - > showErrorDialog ( this , i18n ( " Chiasmus Backend Error " ) ) ;
return ;
}
const TQVariant result = job - > property ( " result " ) ;
if ( result . type ( ) ! = TQVariant : : StringList ) {
const TQString msg = i18n ( " Unexpected return value from Chiasmus backend: "
" The \" x-obtain-keys \" function did not return a "
" string list. Please report this bug. " ) ;
KMessageBox : : error ( this , msg , i18n ( " Chiasmus Backend Error " ) ) ;
return ;
}
const TQStringList keys = result . toStringList ( ) ;
if ( keys . empty ( ) ) {
const TQString msg = i18n ( " No keys have been found. Please check that a "
" valid key path has been set in the Chiasmus "
" configuration. " ) ;
KMessageBox : : information ( this , msg , i18n ( " No Chiasmus Keys Found " ) ) ;
return ;
}
ChiasmusKeySelector selectorDlg ( this , i18n ( " Chiasmus Encryption Key Selection " ) ,
keys , GlobalSettings : : chiasmusKey ( ) ,
GlobalSettings : : chiasmusOptions ( ) ) ;
if ( selectorDlg . exec ( ) ! = TQDialog : : Accepted )
return ;
GlobalSettings : : setChiasmusOptions ( selectorDlg . options ( ) ) ;
GlobalSettings : : setChiasmusKey ( selectorDlg . key ( ) ) ;
assert ( ! GlobalSettings : : chiasmusKey ( ) . isEmpty ( ) ) ;
mEncryptWithChiasmus = true ;
resetter . disable ( ) ;
}
void KMComposeWin : : slotEditDone ( KMail : : EditorWatcher * watcher )
{
kdDebug ( 5006 ) < < k_funcinfo < < endl ;
KMMessagePart * part = mEditorMap [ watcher ] ;
KTempFile * tf = mEditorTempFiles [ watcher ] ;
mEditorMap . remove ( watcher ) ;
mEditorTempFiles . remove ( watcher ) ;
if ( ! watcher - > fileChanged ( ) )
return ;
tf - > file ( ) - > reset ( ) ;
TQByteArray data = tf - > file ( ) - > readAll ( ) ;
part - > setBodyEncodedBinary ( data ) ;
}
void KMComposeWin : : slotUpdateSignatureAndEncrypionStateIndicators ( )
{
const bool showIndicatorsAlways = false ; // FIXME config option?
mSignatureStateIndicator - > setText ( mSignAction - > isChecked ( ) ? i18n ( " Message will be signed " ) : i18n ( " Message will not be signed " ) ) ;
mEncryptionStateIndicator - > setText ( mEncryptAction - > isChecked ( ) ? i18n ( " Message will be encrypted " ) : i18n ( " Message will not be encrypted " ) ) ;
if ( ! showIndicatorsAlways ) {
mSignatureStateIndicator - > setShown ( mSignAction - > isChecked ( ) ) ;
mEncryptionStateIndicator - > setShown ( mEncryptAction - > isChecked ( ) ) ;
}
}
void KMComposeWin : : slotAttachmentDragStarted ( )
{
kdDebug ( 5006 ) < < k_funcinfo < < endl ;
int idx = 0 ;
TQStringList filenames ;
for ( TQPtrListIterator < TQListViewItem > it ( mAtmItemList ) ; * it ; + + it , + + idx ) {
if ( ( * it ) - > isSelected ( ) ) {
KMMessagePart * msgPart = mAtmList . at ( idx ) ;
KTempDir * tempDir = new KTempDir ( ) ; // will be deleted on composer close
tempDir - > setAutoDelete ( true ) ;
mTempDirs . insert ( tempDir ) ;
const TQString fileName = tempDir - > name ( ) + " / " + msgPart - > name ( ) ;
KPIM : : kByteArrayToFile ( msgPart - > bodyDecodedBinary ( ) ,
fileName ,
false , false , false ) ;
KURL url ;
url . setPath ( fileName ) ;
filenames < < url . path ( ) ;
}
}
if ( filenames . isEmpty ( ) ) return ;
TQUriDrag * drag = new TQUriDrag ( mAtmListView ) ;
drag - > setFileNames ( filenames ) ;
drag - > dragCopy ( ) ;
}
void KMComposeWin : : recipientEditorSizeHintChanged ( )
{
TQTimer : : singleShot ( 1 , this , TQT_SLOT ( setMaximumHeaderSize ( ) ) ) ;
}
void KMComposeWin : : setMaximumHeaderSize ( )
{
mHeadersArea - > setMaximumHeight ( mHeadersArea - > sizeHint ( ) . height ( ) ) ;
}