--===============0747105636== Content-type: multipart/signed; micalg=pgp-sha1; protocol="application/pgp-signature"; boundary=nextPart1692063.pyseZVHO3Q Content-transfer-encoding: 7bit --nextPart1692063.pyseZVHO3Q Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline On Saturday 20 August 2005 14:55, Jonathan Marten wrote: > Here's my try at a feature that lots of people have apparently been > wanting for a long time: mail templates (bug 1015). Maybe too late > for the 3.5 feature freeze, but hopefully suitable for inclusion in a > future KMail release. Again, thanks a lot for looking into this. I've now reviewed your patch. > There is a new special folder "templates"; messages can be copied > into here just like any other, or saved here using the 'Message - > Save as Template' menu option in the composer window. This folder > works similarly to the "drafts" folder; double-clicking on a message > or choosing the "Use Template" option on the popup menu starts the > composer on a copy of that message, but does not of course delete the > original template message. I think something like =46ile =2D>New Message from Template ->some template another template would be better than having to switch to the Templates folder in order=20 to create a new message from a template. But of course for editting=20 templates the above drafts-like functionality still makes sense. > A template can also be used to insert text into a message being > composed, via the 'Message - Insert Template Text' menu option. This > will display a list of template messages (subject and summary of > start of body); selecting one in this list and clicking "OK" will > insert the body text into the message being composed. (The subject > is ignored for this operation). I'm not sure whether this is such a good idea because the user will=20 clutter his Template folder with two different types of things, namely=20 with message templates and with standard text blocks. > There is (currently) no facility for inserting variable fields into > the inserted template, but IMHO I agree with the bug comments that > mail-merge does not really belong in KMail. Something like Reply Using Template with macro replacement would be very=20 nice and is probably more often used then creating a new message from a=20 template without any context. Anyway, that can be added at a later=20 time. > Still to do (if required): GUI for an identity-specific templates > folder (if required), and the option to have the templates folder on > an IMAP server. Templates folder on the IMAP server will definitely be needed. I'm not=20 sure how useful identity specific templates folders are. > I also haven't tested this facility with HTML=20 > messages, but see no reason why it shouldn't work... =46amous last words. :-) > Patch follows (against KDE 3.4.2). There are two new source files > (kmail/selecttemplatedialog.cpp and kmail/selecttemplatedialog.h) to > handle the insert selection list as above. There are also some minor > changes to libkdepim (sorting of the templates folder in the folder > tree) and libkpimidentities (only needed if a per-identity template > folder is required). The patch is also at > http://www.keelhaul.demon.co.uk/kde/mailtemplates.patch in case it > should get damaged in the post. > > Enjoy... > > -- patch starts > --------------------------------------------------------- --- [snip] > --- kdepim/kmail/kmcommands.cpp.tem 2005-05-23 13:11:54.000000000 > +0100 +++ kdepim/kmail/kmcommands.cpp 2005-08-20 12:20:15.000000000 > +0100 @@ -629,6 +629,35 @@ > } > > > +KMUseTemplateCommand::KMUseTemplateCommand( QWidget *parent, > KMMessage *msg ) + :KMCommand( parent, msg ) > +{ > +} > + > +KMCommand::Result KMUseTemplateCommand::execute() > +{ > + kdDebug(0) << k_funcinfo << endl; > + KMMessage *msg =3D retrievedMessage(); > + if (!msg || !msg->parent() || > + !kmkernel->folderIsTemplates( msg->parent() )) > + return Failed; > + > + // Take a copy of the original message, which remains unchanged. > + KMMessage *newMsg =3D new KMMessage; > + newMsg->setComplete(msg->isComplete()); > + newMsg->fromString(msg->asString()); > + newMsg->setStatus(msg->status()); Why do you copy the status of the template? > + KMComposeWin *win =3D new KMComposeWin(); > + msg->setTransferInProgress(false); // From here on on, the > composer owns the message.=20 The above line should be unnecessary. > + newMsg->setTransferInProgress(false);=20 > + win->setMsg(newMsg, FALSE, TRUE); > + win->show(); > + > + return OK; > +} [snip] > --- kdepim/kmail/kmcomposewin.cpp.tem 2005-05-23 13:11:54.000000000 > +0100 +++ kdepim/kmail/kmcomposewin.cpp 2005-08-18 16:44:03.000000000 [snip] > @@ -3531,12 +3539,13 @@ > > >=20 > //------------------------------------------------------------------- >--------- -void KMComposeWin::doSend(int aSendNow, bool saveInDrafts) > +void KMComposeWin::doSend(int aSendNow, bool saveInDrafts, bool > saveInTemplates) { This code has changed quite a bit since KDE 3.4. It would really be=20 better if you'd develop against the development version. Also I don't=20 like the usage of another bool parameter. Using an enum would be much=20 better. > mSendNow =3D aSendNow; > mSaveInDrafts =3D saveInDrafts; > + mSaveInTemplates =3D saveInTemplates; > > - if (!saveInDrafts) > + if (!saveInDrafts && !saveInTemplates) > { > if ( KPIM::getFirstEmailAddress( from() ).isEmpty() ) { > if ( !( mShowHeaders & HDR_FROM ) ) { > @@ -3631,9 +3640,9 @@ > (!hf.isEmpty() && (hf !=3D mTransport->text(0)))) > mMsg->setHeaderField("X-KMail-Transport", > mTransport->currentText()); > > - mDisableBreaking =3D saveInDrafts; > + mDisableBreaking =3D (saveInDrafts || saveInTemplates); > > - const bool neverEncrypt =3D ( saveInDrafts && > GlobalSettings::neverEncryptDrafts() ) + const bool neverEncrypt =3D ( > (saveInDrafts || saveInTemplates) && > GlobalSettings::neverEncryptDrafts() ) > > || mSigningAndEncryptionExplicitlyDisable > ||d; > > connect( this, SIGNAL( applyChangesDone( bool ) ), > SLOT( slotContinueDoSend( bool ) ) ); > @@ -3739,6 +3748,52 @@ >=20 > (static_cast(imapDraftsFolder->storage()))->getFolder >(); } > The below duplication of the equivalent code for drafts is not nice.=20 Please try to come up with a way to avoid the code duplication. > + } else if (mSaveInTemplates) { > + KMFolder* templatesFolder =3D 0, *imapTemplatesFolder =3D 0; > + // get the templatesFolder > + if ( !(*it)->templates().isEmpty() ) { > + templatesFolder =3D kmkernel->folderMgr()->findIdString( > (*it)->templates() ); > + if ( templatesFolder =3D=3D 0 )=20 > + // This is *NOT* supposed to be "imapTemplatesFolder", > because a=20 > + // dIMAP folder works like a normal folder=20 > + templatesFolder =3D > kmkernel->dimapFolderMgr()->findIdString( (*it)->templates() ); > + if ( templatesFolder =3D=3D 0 ) > + imapTemplatesFolder =3D > kmkernel->imapFolderMgr()->findIdString( (*it)->templates() ); > + if ( !templatesFolder && !imapTemplatesFolder ) { > + const KPIM::Identity & id =3D kmkernel->identityManager() > + ->identityForUoidOrDefault( (*it)->headerField( > "X-KMail-Identity" ).stripWhiteSpace().toUInt() ); > + KMessageBox::information(0, i18n("The custom templates > folder for identity " > + "\"%1\" does not exist > (anymore); " > + "therefore, the default > templates folder " > + "will be used.") > + .arg( id.identityName() ) ); > + }=20 > + } > + if (imapTemplatesFolder && imapTemplatesFolder->noContent()) > + imapTemplatesFolder =3D 0; > + > + if ( templatesFolder =3D=3D 0 ) { > + templatesFolder =3D kmkernel->templatesFolder(); > + } else { > + templatesFolder->open(); > + } > + kdDebug(5006) << "saveintemplates: templates=3D" << > templatesFolder->name() << endl; > + if (imapTemplatesFolder)=20 > + kdDebug(5006) << "saveintemplates: imaptemplates=3D" > + << imapTemplatesFolder->name() << endl; > + > + sentOk =3D !(templatesFolder->addMsg((*it))); > + > + //Ensure the templates message is correctly and fully parsed > + templatesFolder->unGetMsg(templatesFolder->count() - 1); > + (*it) =3D templatesFolder->getMsg(templatesFolder->count() - 1); > + > + if (imapTemplatesFolder) { > + // move the message to the imap-folder and highlight it > + imapTemplatesFolder->moveMsg((*it)); > + (static_cast(imapTemplatesFolder->storage()))->getFo >lder(); > + }=20 > + > } else { > (*it)->setTo( KMMessage::expandAliases( to() )); > (*it)->setCc( KMMessage::expandAliases( cc() )); > @@ -3788,6 +3843,14 @@ > > >=20 > //------------------------------------------------------------------- >--------- +void KMComposeWin::slotSaveTemplate() { > + kdDebug(0) << k_funcinfo << endl; > + if ( mEditor->checkExternalEditorFinished() ) > + doSend( false, false, true ); I guess the above line makes pretty clear why using bool parameters is=20 evil. If an enum with descriptive values would be used the code would=20 be much better readable. FWIW, the first bool has already been replaced=20 by an enum in the development version. > +} > + > + > +//------------------------------------------------------------------ >---------- void KMComposeWin::slotSendNow() { > if ( !mEditor->checkExternalEditorFinished() ) > return; > @@ -4284,6 +4347,7 @@ > */ > void KMComposeWin::slotFolderRemoved(KMFolder* folder) > { > + // TODO: need to handle templates here? I don't think so. This is only necessary to deal with the case where=20 editting a draft is aborted and the draft has to be re-added to the=20 drafts folder. > if ( (mFolder) && (folder->idString() =3D=3D mFolder->idString()) ) > { > mFolder =3D kmkernel->draftsFolder(); > @@ -4417,6 +4481,35 @@ > alignRightAction->setChecked( ( a & AlignRight ) ); > } > > +void KMComposeWin::slotInsertTemplate() > +{ > + kdDebug(0) << k_funcinfo << endl; > + > + KMFolder *temFolder =3D kmkernel->templatesFolder(); Here obviously the identity specific template folder would have to be=20 used (if we allow this). But as I already wrote above I don't like this=20 solution that much. I'd prefer a separate solution for inserting,=20 saving and managing text blocks. > + if (!temFolder) return; > + > + if (temFolder->count()=3D=3D0) > + { > + KMessageBox::sorry(this,i18n("There are no templates > available.\nCopy or save messages into the 'templates' folder in > order to use them."));=20 > + return;=20 > + } > + > + SelectTemplateDialog d(temFolder,this); > + > + d.show(); > + if (d.exec()) > + { > + QString s =3D d.selectedTemplateText(); > + if (!s.isEmpty()) mEditor->insert(s); > + } > +} > + [snip] > --- kdepim/kmail/kmmainwidget.cpp.tem 2005-08-09 18:04:39.000000000 > +0100=20 > +++ kdepim/kmail/kmmainwidget.cpp 2005-08-20 12:20:44.000000000=20 > +0100 > @@ -2430,6 +2445,9 @@ > mEditAction =3D new KAction( i18n("&Edit Message"), "edit", Key_T, > this, SLOT(slotEditMsg()), actionCollection(), "edit" ); > > + mUseAction =3D new KAction( i18n("&Use Template"), "edit", Key_U, > this,=20 I think something like "New Message from Template" would be better. > + SLOT(slotUseTemplate()),=20 > actionCollection(), "use" );=20 > +=20 > //----- "Mark Message" submenu > mStatusMenu =3D new KActionMenu ( i18n( "Mar&k Message" ), > actionCollection(), "set_status" ); Since I don't think the Insert Template Text functionality is a good=20 solution I skipped the implementation of the template selection dialog.=20 If you take out this functionality and address the other issues I=20 raised then the patch will be included in the next version of KMail.=20 Please note, that you will most likely have to adapt your patch to Qt 4=20 since the next version of KMail will be based on Qt 4. Regards, Ingo --nextPart1692063.pyseZVHO3Q Content-Type: application/pgp-signature -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.2.5 (GNU/Linux) iD8DBQBDFKzWGnR+RTDgudgRAjk/AKCso0pDc9wdSMXqBdt+fpei9V0erACeJIsC FU7+00N/A2uF82Zr1egOcJQ= =FaCL -----END PGP SIGNATURE----- --nextPart1692063.pyseZVHO3Q-- --===============0747105636== Content-Type: text/plain; charset="iso-8859-1" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Disposition: inline _______________________________________________ KMail developers mailing list KMail-devel@kde.org https://mail.kde.org/mailman/listinfo/kmail-devel --===============0747105636==--