--- kmail/configuredialog.cpp 2006/11/02 10:03:21 601149 +++ kmail/configuredialog.cpp 2006/11/02 10:06:27 601150 @@ -2557,6 +2557,24 @@ connect( mAutoAppSignFileCheck, SIGNAL( stateChanged(int) ), this, SLOT( slotEmitChanged( void ) ) ); + mTopQuoteCheck = + new QCheckBox( GlobalSettings::self()->prependSignatureItem()->label(), this ); + mTopQuoteCheck->setEnabled( false ); + vlay->addWidget( mTopQuoteCheck); + connect( mTopQuoteCheck, SIGNAL( stateChanged(int) ), + this, SLOT( slotEmitChanged( void ) ) ); + connect( mAutoAppSignFileCheck, SIGNAL(toggled(bool)), + mTopQuoteCheck, SLOT(setEnabled(bool)) ); + + mDashDashCheck = + new QCheckBox( GlobalSettings::self()->dashDashSignatureItem()->label(), this ); + mDashDashCheck->setEnabled( false ); + vlay->addWidget( mDashDashCheck); + connect( mDashDashCheck, SIGNAL( stateChanged(int) ), + this, SLOT( slotEmitChanged( void ) ) ); + connect( mAutoAppSignFileCheck, SIGNAL(toggled(bool)), + mDashDashCheck, SLOT(setEnabled(bool)) ); + mSmartQuoteCheck = new QCheckBox( GlobalSettings::self()->smartQuoteItem()->label(), this, "kcfg_SmartQuote" ); @@ -2674,6 +2689,8 @@ mAutoAppSignFileCheck->setChecked( GlobalSettings::self()->autoTextSignature()=="auto" ); + mTopQuoteCheck->setChecked( GlobalSettings::self()->prependSignature() ); + mDashDashCheck->setChecked( GlobalSettings::self()->dashDashSignature() ); mSmartQuoteCheck->setChecked( GlobalSettings::self()->smartQuote() ); mAutoRequestMDNCheck->setChecked( GlobalSettings::self()->requestMDN() ); mWordWrapCheck->setChecked( GlobalSettings::self()->wordWrap() ); @@ -2694,6 +2711,12 @@ bool state = composer.readBoolEntry("signature"); mAutoAppSignFileCheck->setChecked( state ); } + if ( composer.hasKey( "prepend-signature" ) ) + mTopQuoteCheck->setChecked( composer.readBoolEntry( "prepend-signature" ) ); + + if ( composer.hasKey( "dash-dash-signature" ) ) + mDashDashCheck->setChecked( composer.readBoolEntry( "dash-dash-signature" ) ); + if ( composer.hasKey( "smart-quote" ) ) mSmartQuoteCheck->setChecked( composer.readBoolEntry( "smart-quote" ) ); if ( composer.hasKey( "request-mdn" ) ) @@ -2715,6 +2738,8 @@ void ComposerPage::GeneralTab::save() { GlobalSettings::self()->setAutoTextSignature( mAutoAppSignFileCheck->isChecked() ? "auto" : "manual" ); + GlobalSettings::self()->setPrependSignature( mTopQuoteCheck->isChecked()); + GlobalSettings::self()->setDashDashSignature( mDashDashCheck->isChecked()); GlobalSettings::self()->setSmartQuote( mSmartQuoteCheck->isChecked() ); GlobalSettings::self()->setRequestMDN( mAutoRequestMDNCheck->isChecked() ); GlobalSettings::self()->setWordWrap( mWordWrapCheck->isChecked() ); --- kmail/configuredialog_p.h 2006/11/02 10:03:21 601149 +++ kmail/configuredialog_p.h 2006/11/02 10:06:27 601150 @@ -604,6 +604,8 @@ private: QCheckBox *mAutoAppSignFileCheck; + QCheckBox *mTopQuoteCheck; + QCheckBox *mDashDashCheck; QCheckBox *mSmartQuoteCheck; QCheckBox *mAutoRequestMDNCheck; QCheckBox *mShowRecentAddressesInComposer; --- kmail/kmail.kcfg 2006/11/02 10:03:21 601149 +++ kmail/kmail.kcfg 2006/11/02 10:06:27 601150 @@ -253,7 +253,7 @@ false - + auto @@ -350,6 +350,17 @@ A backup copy of the text in the composer window can be created regularly. The interval used to create the backups is set here. You can disable autosaving by setting it to the value 0. 2 + + + + false + + + + + true + + Re\\s*:,Re\\[\\d+\\]:,Re\\d+: --- kmail/kmcomposerui.rc 2006/11/02 10:03:21 601149 +++ kmail/kmcomposerui.rc 2006/11/02 10:06:27 601150 @@ -63,6 +63,9 @@ &Attach + + + --- kmail/kmcomposewin.cpp 2006/11/02 10:03:21 601149 +++ kmail/kmcomposewin.cpp 2006/11/02 10:06:27 601150 @@ -1331,6 +1331,14 @@ (void) new KAction (i18n("Append S&ignature"), 0, this, SLOT(slotAppendSignature()), actionCollection(), "append_signature"); + (void) new KAction (i18n("Prepend S&ignature"), 0, this, + SLOT(slotPrependSignature()), + actionCollection(), "prepend_signature"); + (void) new KAction (i18n("Insert Signature At C&ursor Position"), "edit", 0, this, + SLOT(slotInsertSignatureAtCursor()), + actionCollection(), "insert_signature_at_cursor_position"); + + mAttachPK = new KAction (i18n("Attach &Public Key..."), 0, this, SLOT(slotInsertPublicKey()), actionCollection(), "attach_public_key"); @@ -2022,7 +2030,13 @@ // Not user friendy if this modal fileseletor opens before the // composer. // - QTimer::singleShot( 200, this, SLOT(slotAppendSignature()) ); + //QTimer::singleShot( 200, this, SLOT(slotAppendSignature()) ); + if ( GlobalSettings::self()->prependSignature() ) { + QTimer::singleShot( 0, this, SLOT(slotPrependSignature()) ); + } else { + QTimer::singleShot( 0, this, SLOT(slotAppendSignature()) ); + } + } setModified( isModified ); @@ -4146,6 +4160,24 @@ //---------------------------------------------------------------------------- void KMComposeWin::slotAppendSignature() { + insertSignature(); +} + +//---------------------------------------------------------------------------- +void KMComposeWin::slotPrependSignature() +{ + insertSignature( false ); +} + +//---------------------------------------------------------------------------- +void KMComposeWin::slotInsertSignatureAtCursor() +{ + insertSignature( false, mEditor->currentLine() ); +} + +//---------------------------------------------------------------------------- +void KMComposeWin::insertSignature( bool append, int pos ) +{ bool mod = mEditor->isModified(); const KPIM::Identity & ident = @@ -4150,10 +4180,18 @@ const KPIM::Identity & ident = kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() ); mOldSigText = ident.signatureText(); + + if ( !GlobalSettings::self()->dashDashSignature() && !mOldSigText.isEmpty() ) + mOldSigText = mOldSigText.remove( 0, 4 ); if( !mOldSigText.isEmpty() ) { - mEditor->append(mOldSigText); + if ( append ) { + mEditor->append(mOldSigText); + } else { + mEditor->insertAt(mOldSigText, pos, 0); + } + mEditor->setModified(mod); // mEditor->setContentsPos( 0, 0 ); if ( mPreserveUserCursorPosition ) { @@ -4156,13 +4200,30 @@ mEditor->setModified(mod); // mEditor->setContentsPos( 0, 0 ); - 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; - } + + // if the cursor is explicitly set in a template, set the cursor position + // to the template position, offsetting for the prepended signature length + // if applicable, otherwise set it to above the sig for {pre,ap}pend/insert + if ( mPreserveUserCursorPosition ) { + if ( append && pos == 0 ) + mEditor->setCursorPositionFromStart( (unsigned int) mMsg->getCursorPos() ); + else + mEditor->setCursorPositionFromStart( (unsigned int) mMsg->getCursorPos() + mOldSigText.length() ); + // 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 { if ( append ) { + QString tmpMsgText = mEditor->text(); + mEditor->setCursorPositionFromStart( tmpMsgText.length() - mOldSigText.length() ); + } + else { if ( pos != 0 ) + mEditor->setCursorPosition( pos, 0 ); + else + mEditor->setCursorPosition( 0 , 0 ); + } + } + mEditor->sync(); } } --- kmail/kmcomposewin.cpp 2006/11/02 10:03:21 601149 +++ kmail/kmcomposewin.cpp 2006/11/02 10:06:27 601150 @@ -4500,15 +4553,56 @@ while ( !mOldSigText.isEmpty() && mOldSigText[mOldSigText.length()-1].isSpace() ) mOldSigText.truncate( mOldSigText.length() - 1 ); - if( edtText.endsWith( mOldSigText ) ) - edtText.truncate( edtText.length() - mOldSigText.length() ); + mNewSigText = ident.signatureText(); + if ( !GlobalSettings::self()->dashDashSignature() && !mNewSigText.isEmpty() ) + mNewSigText = mNewSigText.remove( 0, 4 ); + // if the user has auto signatures enabled and a new sig, replace the + // current sig on identity change if there's a sig set, otherwise prepend + // the new sig if they want prepended, or append otherwise and finally + // delete the sig if they don't have auto signatures enabled or if + // the new signature is empty and old sig isn't empty + if ( ( GlobalSettings::self()->autoTextSignature() == "auto" ) && + !mNewSigText.isEmpty() ) { + if ( ( edtText.find( mOldSigText, 0, true) != -1 ) && !mOldSigText.isEmpty() ) { + edtText = edtText.replace( edtText.find( mOldSigText, 0, true), + mOldSigText.length(), mNewSigText ); + } else { if ( GlobalSettings::self()->prependSignature() ) { + // if we have tracking info and I can find it in the text, place the + // sig there, otherwise prepend it (with \n\n if they've already typed) + if ( !mTrackSig.isNull() && ( edtText.find( mTrackSig, 0, true) != -1 ) ) { + if ( mTrackSig == "!!!APPEND!!!" ) + edtText.append( mNewSigText ); + else + edtText.insert( edtText.find( mTrackSig, 0, true) , mNewSigText ); + mTrackSig = QString::null; + } + else { if ( !edtText[1].isSpace() ) + edtText.prepend( mNewSigText + QString::fromLatin1( "\n\n" ) ); + else + edtText.prepend( mNewSigText ); + } + } else { + edtText.append( mNewSigText ); + } + } + } else if ( !mOldSigText.isEmpty() ) { + // if switching to an ident with no sig, track its position for later in case + // the user switches to one with a sig for intelligent placement + // caveat: this is based on the assumption that the user won't change + // the 20 characters after the signature (seems reasonable in reply/fwd) + if ( mNewSigText.isEmpty() ) { + // oops, there's actually nothing after the signature, just append later + if ( edtText.find( mOldSigText, 0, true) + mOldSigText.length() == edtText.length() ) + mTrackSig = "!!!APPEND!!!"; + else + mTrackSig = edtText.mid( edtText.find( mOldSigText, 0, true) + + mOldSigText.length(), 20 ); + } + edtText = edtText.remove( edtText.find( mOldSigText, 0, true), + mOldSigText.length() ); + } + mOldSigText = mNewSigText; - // now append the new sig - mOldSigText = ident.signatureText(); - if( ( !mOldSigText.isEmpty() ) && - ( GlobalSettings::self()->autoTextSignature() == "auto" ) ) { - edtText.append( mOldSigText ); - } mEditor->setText( edtText ); // disable certain actions if there is no PGP user identity set --- kmail/kmcomposewin.h 2006/11/02 10:03:21 601149 +++ kmail/kmcomposewin.h 2006/11/02 10:06:27 601150 @@ -369,6 +369,16 @@ void slotAppendSignature(); /** + * Prepend signature file at the beginning of the text in the editor. + */ + void slotPrependSignature(); + + /** + * Insert signature file at the cursor position of the text in the editor. + */ + void slotInsertSignatureAtCursor(); + + /** * Attach sender's public key. */ void slotInsertMyPublicKey(); @@ -663,6 +673,12 @@ */ void setTransport( const QString & transport ); + /** + * Helper to insert the signature of the current identy at the + * beginning or end of the editor. + */ + void insertSignature( bool append = true, int pos = 0 ); + private slots: /** * Compress an attachemnt with the given index @@ -757,6 +773,9 @@ QMap mAttachJobs; KURL::List mAttachFilesPending; int mAttachFilesSend; + + QString mTrackSig; + QString mNewSigText; private: // helper method for slotInsert(My)PublicKey() --- libkpimidentities/identity.h 2006/11/02 10:03:21 601149 +++ libkpimidentities/identity.h 2006/11/02 10:06:27 601150 @@ -227,6 +227,7 @@ void setSignature( const Signature & sig ) { mSignature = sig; } Signature & signature() /* _not_ const! */ { return mSignature; } + const Signature & signature() const { return mSignature; } protected: /** @return true if the signature is read from the output of a command */