10 #define REALLY_WANT_KMCOMPOSEWIN_H
11 #include "kmcomposewin.h"
12 #undef REALLY_WANT_KMCOMPOSEWIN_H
15 #include "kmlineeditspell.h"
16 #include "kmatmlistview.h"
18 #include "kmmainwin.h"
19 #include "kmreadermainwin.h"
20 #include "messagesender.h"
21 #include "kmmsgpartdlg.h"
22 #include <kpgpblock.h>
23 #include <kaddrbook.h>
24 #include "kmaddrbook.h"
25 #include "kmmsgdict.h"
26 #include "kmfolderimap.h"
27 #include "kmfoldermgr.h"
28 #include "kmfoldercombobox.h"
29 #include "kmtransport.h"
30 #include "kmcommands.h"
31 #include "kcursorsaver.h"
33 #include "encodingdetector.h"
34 #include "attachmentlistview.h"
35 #include "transportmanager.h"
36 using KMail::AttachmentListView;
37 #include "dictionarycombobox.h"
39 #include "addressesdialog.h"
40 using KPIM::AddressesDialog;
41 #include "addresseeemailselection.h"
42 using KPIM::AddresseeEmailSelection;
43 using KPIM::AddresseeSelectorDialog;
44 #include <maillistdrag.h>
45 using KPIM::MailListDrag;
46 #include "recentaddresses.h"
47 using KRecentAddress::RecentAddresses;
48 #include "kleo_util.h"
50 #include "recipientseditor.h"
51 #include "editorwatcher.h"
53 #include "attachmentcollector.h"
54 #include "objecttreeparser.h"
56 #include "kmfoldermaildir.h"
58 #include <libkpimidentities/identitymanager.h>
59 #include <libkpimidentities/identitycombo.h>
60 #include <libkpimidentities/identity.h>
61 #include <libkdepim/kfileio.h>
62 #include <libemailfunctions/email.h>
63 #include <kleo/cryptobackendfactory.h>
64 #include <kleo/exportjob.h>
65 #include <kleo/specialjob.h>
66 #include <ui/progressdialog.h>
67 #include <ui/keyselectiondialog.h>
69 #include <gpgmepp/context.h>
70 #include <gpgmepp/key.h>
72 #include <kio/netaccess.h>
74 #include "klistboxdialog.h"
76 #include "messagecomposer.h"
77 #include "chiasmuskeyselector.h"
79 #include <kcharsets.h>
80 #include <kcompletionbox.h>
82 #include <kcombobox.h>
83 #include <kstdaccel.h>
84 #include <kpopupmenu.h>
85 #include <kedittoolbar.h>
86 #include <kkeydialog.h>
88 #include <kfiledialog.h>
90 #include <kinputdialog.h>
91 #include <kmessagebox.h>
93 #include <kio/scheduler.h>
94 #include <ktempfile.h>
96 #include <kapplication.h>
97 #include <kstatusbar.h>
99 #include <kstdaction.h>
100 #include <kdirwatch.h>
101 #include <kstdguiitem.h>
102 #include <kiconloader.h>
103 #include <kpushbutton.h>
104 #include <kuserprofile.h>
106 #include <ktempdir.h>
107 #include <kstandarddirs.h>
109 #include "globalsettings.h"
110 #include "replyphrases.h"
113 #include <kspelldlg.h>
114 #include <spellingfilter.h>
115 #include <ksyntaxhighlighter.h>
116 #include <kcolordialog.h>
118 #include <ksavefile.h>
120 #include <tqtabdialog.h>
121 #include <tqregexp.h>
122 #include <tqbuffer.h>
123 #include <tqtooltip.h>
124 #include <tqtextcodec.h>
125 #include <tqheader.h>
126 #include <tqwhatsthis.h>
127 #include <tqfontdatabase.h>
129 #include <mimelib/mimepp.h>
134 #include <sys/stat.h>
135 #include <sys/types.h>
142 #include "kmcomposewin.moc"
144 #include "snippetwidget.h"
146 KMail::Composer * KMail::makeComposer(
KMMessage * msg, uint identitiy ) {
147 return KMComposeWin::create( msg, identitiy );
150 KMail::Composer * KMComposeWin::create(
KMMessage * msg, uint identitiy ) {
151 return new KMComposeWin( msg, identitiy );
155 KMComposeWin::KMComposeWin(
KMMessage *aMsg, uint
id )
157 mSpellCheckInProgress( false ),
159 mAtmModified( false ),
163 mSigningAndEncryptionExplicitlyDisabled( false ),
165 mUseHTMLEditor( false ),
167 mAttachPK( 0 ), mAttachMPK( 0 ),
168 mAttachRemoveAction( 0 ), mAttachSaveAction( 0 ), mAttachPropertiesAction( 0 ),
169 mAppendSignatureAction( 0 ), mPrependSignatureAction( 0 ), mInsertSignatureAction( 0 ),
170 mSignAction( 0 ), mEncryptAction( 0 ), mRequestMDNAction( 0 ),
171 mUrgentAction( 0 ), mAllFieldsAction( 0 ), mFromAction( 0 ),
172 mReplyToAction( 0 ), mToAction( 0 ), mCcAction( 0 ), mBccAction( 0 ),
174 mIdentityAction( 0 ), mTransportAction( 0 ), mFccAction( 0 ),
175 mWordWrapAction( 0 ), mFixedFontAction( 0 ), mAutoSpellCheckingAction( 0 ),
176 mDictionaryAction( 0 ), mSnippetAction( 0 ),
177 mEncodingAction( 0 ),
178 mCryptoModuleAction( 0 ),
179 mEncryptChiasmusAction( 0 ),
180 mEncryptWithChiasmus( false ),
183 mAutoSaveTimer( 0 ), mLastAutoSaveErrno( 0 ),
184 mSignatureStateIndicator( 0 ), mEncryptionStateIndicator( 0 ),
185 mPreserveUserCursorPosition( false ),
186 mPreventFccOverwrite( false ),
187 mCheckForRecipients( true ),
188 mCheckForForgottenAttachments( true ),
189 mIgnoreStickyFields( false )
191 mClassicalRecipients = GlobalSettings::self()->recipientsEditorType() ==
192 GlobalSettings::EnumRecipientsEditorType::Classic;
194 mSubjectTextWasSpellChecked =
false;
195 if (kmkernel->xmlGuiInstance())
196 setInstance( kmkernel->xmlGuiInstance() );
197 mMainWidget =
new TQWidget(
this);
199 mHeadersToEditorSplitter =
new TQSplitter( Qt::Vertical, mMainWidget,
"mHeadersToEditorSplitter" );
200 mHeadersToEditorSplitter->setChildrenCollapsible(
false );
201 mHeadersArea =
new TQWidget( mHeadersToEditorSplitter );
202 mHeadersArea->setSizePolicy( mHeadersToEditorSplitter->sizePolicy().horData(), TQSizePolicy::Maximum );
203 TQVBoxLayout *v =
new TQVBoxLayout( mMainWidget );
204 v->addWidget( mHeadersToEditorSplitter );
205 mIdentity =
new KPIM::IdentityCombo(kmkernel->identityManager(), mHeadersArea);
206 TQToolTip::add( mIdentity,
207 i18n(
"Select an identity for this message" ) );
210 TQToolTip::add( mDictionaryCombo,
211 i18n(
"Select the dictionary to use when spell-checking this message" ) );
213 mFcc =
new KMFolderComboBox(mHeadersArea);
214 mFcc->showOutboxFolder(
false );
215 TQToolTip::add( mFcc,
216 i18n(
"Select the sent-mail folder where a copy of this message will be saved" ) );
218 mTransport =
new TQComboBox(
true, mHeadersArea);
219 TQToolTip::add( mTransport,
220 i18n(
"Select the outgoing account to use for sending this message" ) );
222 mEdtFrom =
new KMLineEdit(
false,mHeadersArea,
"fromLine");
223 TQToolTip::add( mEdtFrom,
224 i18n(
"Set the \"From:\" email address for this message" ) );
226 mEdtReplyTo =
new KMLineEdit(
true,mHeadersArea,
"replyToLine");
227 TQToolTip::add( mEdtReplyTo,
228 i18n(
"Set the \"Reply-To:\" email address for this message" ) );
229 connect(mEdtReplyTo,TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
230 TQT_SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
232 if ( mClassicalRecipients ) {
233 mRecipientsEditor = 0;
235 mEdtTo =
new KMLineEdit(
true,mHeadersArea,
"toLine");
236 mEdtCc =
new KMLineEdit(
true,mHeadersArea,
"ccLine");
237 mEdtBcc =
new KMLineEdit(
true,mHeadersArea,
"bccLine");
239 mLblTo =
new TQLabel(mHeadersArea);
240 mLblCc =
new TQLabel(mHeadersArea);
241 mLblBcc =
new TQLabel(mHeadersArea);
243 mBtnTo =
new TQPushButton(
"...",mHeadersArea);
244 mBtnCc =
new TQPushButton(
"...",mHeadersArea);
245 mBtnBcc =
new TQPushButton(
"...",mHeadersArea);
248 TQString tip = i18n(
"Select email address(es)");
249 TQToolTip::add( mBtnTo, tip );
250 TQToolTip::add( mBtnCc, tip );
251 TQToolTip::add( mBtnBcc, tip );
253 mBtnTo->setFocusPolicy(TQ_NoFocus);
254 mBtnCc->setFocusPolicy(TQ_NoFocus);
255 mBtnBcc->setFocusPolicy(TQ_NoFocus);
258 connect(mBtnTo,TQT_SIGNAL(clicked()),TQT_SLOT(slotAddrBookTo()));
259 connect(mBtnCc,TQT_SIGNAL(clicked()),TQT_SLOT(slotAddrBookTo()));
260 connect(mBtnBcc,TQT_SIGNAL(clicked()),TQT_SLOT(slotAddrBookTo()));
263 connect(mEdtTo,TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
264 TQT_SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
265 connect(mEdtCc,TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
266 TQT_SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
267 connect(mEdtBcc,TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
268 TQT_SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
285 mRecipientsEditor =
new RecipientsEditor( mHeadersArea );
286 connect( mRecipientsEditor,
287 TQT_SIGNAL( completionModeChanged( KGlobalSettings::Completion ) ),
288 TQT_SLOT( slotCompletionModeChanged( KGlobalSettings::Completion ) ) );
289 connect( mRecipientsEditor, TQT_SIGNAL(sizeHintChanged()), TQT_SLOT(recipientEditorSizeHintChanged()) );
291 mRecipientsEditor->setFocus();
293 mEdtSubject =
new KMLineEditSpell(
false,mHeadersArea,
"subjectLine");
294 TQToolTip::add( mEdtSubject,
295 i18n(
"Set a subject for this message" ) );
297 mLblIdentity =
new TQLabel( i18n(
"&Identity:"), mHeadersArea );
298 mDictionaryLabel =
new TQLabel( i18n(
"&Dictionary:"), mHeadersArea );
299 mLblFcc =
new TQLabel( i18n(
"&Sent-Mail folder:"), mHeadersArea );
300 mLblTransport =
new TQLabel( i18n(
"&Mail transport:"), mHeadersArea );
301 mLblFrom =
new TQLabel( i18n(
"sender address field",
"&From:"), mHeadersArea );
302 mLblReplyTo =
new TQLabel( i18n(
"&Reply to:"), mHeadersArea );
303 mLblSubject =
new TQLabel( i18n(
"S&ubject:"), mHeadersArea );
305 TQString sticky = i18n(
"Sticky");
306 mBtnIdentity =
new TQCheckBox(sticky,mHeadersArea);
307 TQToolTip::add( mBtnIdentity,
308 i18n(
"Use the selected value as your identity for future messages" ) );
309 mBtnFcc =
new TQCheckBox(sticky,mHeadersArea);
310 TQToolTip::add( mBtnFcc,
311 i18n(
"Use the selected value as your sent-mail folder for future messages" ) );
312 mBtnTransport =
new TQCheckBox(sticky,mHeadersArea);
313 TQToolTip::add( mBtnTransport,
314 i18n(
"Use the selected value as your outgoing account for future messages" ) );
315 mBtnDictionary =
new TQCheckBox( sticky, mHeadersArea );
316 TQToolTip::add( mBtnDictionary,
317 i18n(
"Use the selected value as your dictionary for future messages" ) );
320 mHtmlMarkup = GlobalSettings::self()->useHtmlMarkup();
321 mShowHeaders = GlobalSettings::self()->headers();
325 mAtmList.setAutoDelete(
true);
326 mAtmTempList.setAutoDelete(
true);
327 mAtmModified =
false;
328 mAutoDeleteMsg =
false;
331 mFixedFontAction = 0;
334 mSplitter =
new TQSplitter( Qt::Vertical, mHeadersToEditorSplitter,
"mSplitter" );
335 mSplitter->setChildrenCollapsible(
false );
336 mSnippetSplitter =
new TQSplitter( Qt::Horizontal, mSplitter,
"mSnippetSplitter");
337 mSnippetSplitter->setChildrenCollapsible(
false );
339 TQWidget *editorAndCryptoStateIndicators =
new TQWidget( mSnippetSplitter );
340 TQVBoxLayout *vbox =
new TQVBoxLayout( editorAndCryptoStateIndicators );
341 TQHBoxLayout *hbox =
new TQHBoxLayout( vbox );
343 mSignatureStateIndicator =
new TQLabel( editorAndCryptoStateIndicators );
344 mSignatureStateIndicator->setAlignment( TQt::AlignHCenter );
345 hbox->addWidget( mSignatureStateIndicator );
347 KConfigGroup reader( KMKernel::config(),
"Reader" );
348 TQPalette p( mSignatureStateIndicator->palette() );
350 TQColor defaultSignedColor( 0x40, 0xFF, 0x40 );
351 TQColor defaultEncryptedColor( 0x00, 0x80, 0xFF );
352 p.setColor( TQColorGroup::Background, reader.readColorEntry(
"PGPMessageOkKeyOk", &defaultSignedColor ) );
353 mSignatureStateIndicator->setPalette( p );
355 mEncryptionStateIndicator =
new TQLabel( editorAndCryptoStateIndicators );
356 mEncryptionStateIndicator->setAlignment( TQt::AlignHCenter );
357 hbox->addWidget( mEncryptionStateIndicator );
358 p.setColor( TQColorGroup::Background, reader.readColorEntry(
"PGPMessageEncr" , &defaultEncryptedColor ) );
359 mEncryptionStateIndicator->setPalette( p );
362 mEditor =
new KMEdit( editorAndCryptoStateIndicators,
this, mDictionaryCombo->spellConfig() );
363 vbox->addWidget( mEditor );
365 mSnippetWidget =
new SnippetWidget( mEditor, actionCollection(), mSnippetSplitter );
366 mSnippetWidget->setShown( GlobalSettings::self()->showSnippetManager() );
369 mSplitter->setOpaqueResize(
true );
371 mEditor->initializeAutoSpellChecking();
372 mEditor->setTextFormat(TQt::PlainText);
373 mEditor->setAcceptDrops(
true );
375 TQWhatsThis::add( mBtnIdentity,
376 GlobalSettings::self()->stickyIdentityItem()->whatsThis() );
377 TQWhatsThis::add( mBtnFcc,
378 GlobalSettings::self()->stickyFccItem()->whatsThis() );
379 TQWhatsThis::add( mBtnTransport,
380 GlobalSettings::self()->stickyTransportItem()->whatsThis() );
381 TQWhatsThis::add( mBtnTransport,
382 GlobalSettings::self()->stickyDictionaryItem()->whatsThis() );
384 mSpellCheckInProgress=
false;
386 setCaption( i18n(
"Composer") );
387 setMinimumSize(200,200);
389 mBtnIdentity->setFocusPolicy(TQ_NoFocus);
390 mBtnFcc->setFocusPolicy(TQ_NoFocus);
391 mBtnTransport->setFocusPolicy(TQ_NoFocus);
392 mBtnDictionary->setFocusPolicy( TQ_NoFocus );
394 mAtmListView =
new AttachmentListView(
this, mSplitter,
395 "attachment list view" );
396 mAtmListView->setSelectionMode( TQListView::Extended );
397 mAtmListView->addColumn( i18n(
"Name"), 200 );
398 mAtmListView->addColumn( i18n(
"Size"), 80 );
399 mAtmListView->addColumn( i18n(
"Encoding"), 120 );
400 int atmColType = mAtmListView->addColumn( i18n(
"Type"), 120 );
402 mAtmListView->header()->setStretchEnabled(
true, atmColType );
403 mAtmEncryptColWidth = 80;
404 mAtmSignColWidth = 80;
405 mAtmCompressColWidth = 100;
406 mAtmColCompress = mAtmListView->addColumn( i18n(
"Compress"),
407 mAtmCompressColWidth );
408 mAtmColEncrypt = mAtmListView->addColumn( i18n(
"Encrypt"),
409 mAtmEncryptColWidth );
410 mAtmColSign = mAtmListView->addColumn( i18n(
"Sign"),
412 mAtmListView->setColumnWidth( mAtmColEncrypt, 0 );
413 mAtmListView->setColumnWidth( mAtmColSign, 0 );
414 mAtmListView->setAllColumnsShowFocus(
true );
416 connect( mAtmListView,
417 TQT_SIGNAL( doubleClicked( TQListViewItem* ) ),
418 TQT_SLOT( slotAttachEdit() ) );
419 connect( mAtmListView,
420 TQT_SIGNAL( rightButtonPressed( TQListViewItem*,
const TQPoint&,
int ) ),
421 TQT_SLOT( slotAttachPopupMenu( TQListViewItem*,
const TQPoint&,
int ) ) );
422 connect( mAtmListView,
423 TQT_SIGNAL( selectionChanged() ),
424 TQT_SLOT( slotUpdateAttachActions() ) );
425 connect( mAtmListView,
426 TQT_SIGNAL( attachmentDeleted() ),
427 TQT_SLOT( slotAttachRemove() ) );
428 connect( mAtmListView,
429 TQT_SIGNAL( dragStarted() ),
430 TQT_SLOT( slotAttachmentDragStarted() ) );
437 slotUpdateSignatureAndEncrypionStateIndicators();
439 applyMainWindowSettings(KMKernel::config(),
"Composer");
441 connect( mEdtSubject, TQT_SIGNAL( subjectTextSpellChecked() ),
442 TQT_SLOT( slotSubjectTextSpellChecked() ) );
443 connect(mEdtSubject,TQT_SIGNAL(textChanged(
const TQString&)),
444 TQT_SLOT(slotUpdWinTitle(
const TQString&)));
445 connect(mIdentity,TQT_SIGNAL(identityChanged(uint)),
446 TQT_SLOT(slotIdentityChanged(uint)));
447 connect( kmkernel->identityManager(), TQT_SIGNAL(changed(uint)),
448 TQT_SLOT(slotIdentityChanged(uint)));
450 connect(mEdtFrom,TQT_SIGNAL(completionModeChanged(KGlobalSettings::Completion)),
451 TQT_SLOT(slotCompletionModeChanged(KGlobalSettings::Completion)));
452 connect(kmkernel->folderMgr(),TQT_SIGNAL(folderRemoved(
KMFolder*)),
453 TQT_SLOT(slotFolderRemoved(
KMFolder*)));
454 connect(kmkernel->imapFolderMgr(),TQT_SIGNAL(folderRemoved(
KMFolder*)),
455 TQT_SLOT(slotFolderRemoved(
KMFolder*)));
456 connect(kmkernel->dimapFolderMgr(),TQT_SIGNAL(folderRemoved(
KMFolder*)),
457 TQT_SLOT(slotFolderRemoved(
KMFolder*)));
458 connect( kmkernel, TQT_SIGNAL( configChanged() ),
459 TQT_TQOBJECT(
this), TQT_SLOT( slotConfigChanged() ) );
461 connect (mEditor, TQT_SIGNAL (spellcheck_done(
int)),
462 this, TQT_SLOT (slotSpellcheckDone (
int)));
463 connect (mEditor, TQT_SIGNAL( attachPNGImageData(
const TQByteArray &) ),
464 this, TQT_SLOT ( slotAttachPNGImageData(
const TQByteArray &) ) );
465 connect (mEditor, TQT_SIGNAL( focusChanged(
bool) ),
466 this, TQT_SLOT (editorFocusChanged(
bool)) );
468 mMainWidget->resize(480,510);
469 setCentralWidget(mMainWidget);
472 if ( !mClassicalRecipients ) {
478 if ( GlobalSettings::self()->useExternalEditor() ) {
479 mEditor->setUseExternalEditor(
true);
480 mEditor->setExternalEditorPath( GlobalSettings::self()->externalEditor() );
484 slotUpdateSignatureActions();
488 fontChanged( mEditor->currentFont() );
494 KMComposeWin::~KMComposeWin()
499 mAutoDeleteMsg =
false;
500 mFolder->addMsg(mMsg);
502 mFolder->unGetMsg( mFolder->count() - 1 );
504 if (mAutoDeleteMsg) {
508 TQMap<KIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.begin();
509 while ( it != mMapAtmLoadData.end() )
511 KIO::Job *job = it.key();
512 mMapAtmLoadData.remove( it );
514 it = mMapAtmLoadData.begin();
516 deleteAll( mComposedMessages );
518 for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
523 void KMComposeWin::setAutoDeleteWindow(
bool f )
526 setWFlags( getWFlags() | WDestructiveClose );
528 setWFlags( getWFlags() & ~WDestructiveClose );
532 void KMComposeWin::send(
int how)
548 void KMComposeWin::addAttachmentsAndSend(
const KURL::List &urls,
const TQString &,
int how)
555 mAttachFilesSend = how;
556 mAttachFilesPending = urls;
557 connect(
this, TQT_SIGNAL(attachmentAdded(
const KURL&,
bool)), TQT_SLOT(slotAttachedFile(
const KURL&)));
558 for( KURL::List::ConstIterator itr = urls.begin(); itr != urls.end(); ++itr ) {
559 if (!addAttach( *itr ))
560 mAttachFilesPending.remove(mAttachFilesPending.find(*itr));
563 if (mAttachFilesPending.isEmpty() && mAttachFilesSend == how)
565 send(mAttachFilesSend);
566 mAttachFilesSend = -1;
570 void KMComposeWin::slotAttachedFile(
const KURL &url)
572 if (mAttachFilesPending.isEmpty())
574 mAttachFilesPending.remove(mAttachFilesPending.find(url));
575 if (mAttachFilesPending.isEmpty())
577 send(mAttachFilesSend);
578 mAttachFilesSend = -1;
583 void KMComposeWin::addAttachment(KURL url,TQString )
589 void KMComposeWin::addAttachment(
const TQString &name,
591 const TQByteArray &data,
592 const TQCString &type,
593 const TQCString &subType,
594 const TQCString ¶mAttr,
595 const TQString ¶mValue,
596 const TQCString &contDisp)
598 if (!data.isEmpty()) {
599 KMMessagePart *msgPart =
new KMMessagePart;
600 msgPart->setName(name);
601 if( type ==
"message" && subType ==
"rfc822" ) {
602 msgPart->setMessageBody( data );
604 TQValueList<int> dummy;
605 msgPart->setBodyAndGuessCte(data, dummy,
606 kmkernel->msgSender()->sendQuotedPrintable());
608 msgPart->setTypeStr(type);
609 msgPart->setSubtypeStr(subType);
610 msgPart->setParameter(paramAttr,paramValue);
611 msgPart->setContentDisposition(contDisp);
617 void KMComposeWin::slotAttachPNGImageData(
const TQByteArray &image)
621 TQString attName = KInputDialog::getText(
"KMail", i18n(
"Name of the attachment:"), TQString(), &ok,
this );
625 if ( !attName.lower().endsWith(
".png") ) attName +=
".png";
627 addAttachment( attName,
"base64", image,
"image",
"png", TQCString(), TQString(), TQCString() );
631 void KMComposeWin::setBody(TQString body)
633 mEditor->setText(body);
637 bool KMComposeWin::event(TQEvent *e)
639 if (e->type() == TQEvent::ApplicationPaletteChange)
643 return KMail::Composer::event(e);
648 void KMComposeWin::readColorConfig(
void)
650 if ( GlobalSettings::self()->useDefaultColors() ) {
651 mForeColor = TQColor(kapp->palette().active().text());
652 mBackColor = TQColor(kapp->palette().active().base());
654 mForeColor = GlobalSettings::self()->foregroundColor();
655 mBackColor = GlobalSettings::self()->backgroundColor();
659 mPalette = kapp->palette();
660 TQColorGroup cgrp = mPalette.active();
661 cgrp.setColor( TQColorGroup::Base, mBackColor);
662 cgrp.setColor( TQColorGroup::Text, mForeColor);
663 mPalette.setDisabled(cgrp);
664 mPalette.setActive(cgrp);
665 mPalette.setInactive(cgrp);
667 mEdtFrom->setPalette(mPalette);
668 mEdtReplyTo->setPalette(mPalette);
669 if ( mClassicalRecipients ) {
670 mEdtTo->setPalette(mPalette);
671 mEdtCc->setPalette(mPalette);
672 mEdtBcc->setPalette(mPalette);
674 mEdtSubject->setPalette(mPalette);
675 mTransport->setPalette(mPalette);
676 mEditor->setPalette(mPalette);
677 mFcc->setPalette(mPalette);
681 void KMComposeWin::readConfig(
bool reload )
684 mBtnIdentity->setChecked( GlobalSettings::self()->stickyIdentity() );
685 if (mBtnIdentity->isChecked()) {
686 mId = (GlobalSettings::self()->previousIdentity()!=0) ?
687 GlobalSettings::self()->previousIdentity() : mId;
689 mBtnFcc->setChecked( GlobalSettings::self()->stickyFcc() );
690 mBtnTransport->setChecked( GlobalSettings::self()->stickyTransport() );
691 mBtnDictionary->setChecked( GlobalSettings::self()->stickyDictionary() );
692 TQStringList transportHistory = GlobalSettings::self()->transportHistory();
693 TQString currentTransport = GlobalSettings::self()->currentTransport();
695 mEdtFrom->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
696 mEdtReplyTo->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
697 if ( mClassicalRecipients ) {
698 mEdtTo->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
699 mEdtCc->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
700 mEdtBcc->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
703 mRecipientsEditor->setCompletionMode( (KGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
707 if ( GlobalSettings::self()->useDefaultFonts() ) {
708 mBodyFont = KGlobalSettings::generalFont();
709 mFixedFont = KGlobalSettings::fixedFont();
711 mBodyFont = GlobalSettings::self()->composerFont();
712 mFixedFont = GlobalSettings::self()->fixedFont();
716 mEdtFrom->setFont(mBodyFont);
717 mEdtReplyTo->setFont(mBodyFont);
718 if ( mClassicalRecipients ) {
719 mEdtTo->setFont(mBodyFont);
720 mEdtCc->setFont(mBodyFont);
721 mEdtBcc->setFont(mBodyFont);
723 mEdtSubject->setFont(mBodyFont);
726 TQSize siz = GlobalSettings::self()->composerSize();
727 if (siz.width() < 200) siz.setWidth(200);
728 if (siz.height() < 200) siz.setHeight(200);
731 if ( !GlobalSettings::self()->snippetSplitterPosition().isEmpty() ) {
732 mSnippetSplitter->setSizes( GlobalSettings::self()->snippetSplitterPosition() );
734 TQValueList<int> defaults;
735 defaults << (int)(width() * 0.8) << (int)(width() * 0.2);
736 mSnippetSplitter->setSizes( defaults );
740 mIdentity->setCurrentIdentity( mId );
742 kdDebug(5006) <<
"KMComposeWin::readConfig. " << mIdentity->currentIdentityName() << endl;
743 const KPIM::Identity & ident =
744 kmkernel->identityManager()->identityForUoid( mIdentity->currentIdentity() );
747 mTransport->insertStringList( KMTransportInfo::availableTransports() );
748 while ( transportHistory.count() > (uint)GlobalSettings::self()->maxTransportEntries() )
749 transportHistory.remove( transportHistory.last() );
750 mTransport->insertStringList( transportHistory );
751 mTransport->setCurrentText( GlobalSettings::self()->defaultTransport() );
752 if ( mBtnTransport->isChecked() ) {
753 setTransport( currentTransport );
756 if ( mBtnDictionary->isChecked() ) {
757 mDictionaryCombo->setCurrentByDictionaryName( GlobalSettings::self()->previousDictionary() );
759 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
762 TQString fccName =
"";
763 if ( mBtnFcc->isChecked() ) {
764 fccName = GlobalSettings::self()->previousFcc();
765 }
else if ( !ident.fcc().isEmpty() ) {
766 fccName = ident.fcc();
773 void KMComposeWin::writeConfig(
void)
775 GlobalSettings::self()->setHeaders( mShowHeaders );
776 GlobalSettings::self()->setStickyFcc( mBtnFcc->isChecked() );
777 if ( !mIgnoreStickyFields ) {
778 GlobalSettings::self()->setCurrentTransport( mTransport->currentText() );
779 GlobalSettings::self()->setStickyTransport( mBtnTransport->isChecked() );
780 GlobalSettings::self()->setStickyDictionary( mBtnDictionary->isChecked() );
781 GlobalSettings::self()->setStickyIdentity( mBtnIdentity->isChecked() );
782 GlobalSettings::self()->setPreviousIdentity( mIdentity->currentIdentity() );
784 GlobalSettings::self()->setPreviousFcc( mFcc->getFolder()->idString() );
785 GlobalSettings::self()->setPreviousDictionary( mDictionaryCombo->currentDictionaryName() );
786 GlobalSettings::self()->setAutoSpellChecking(
787 mAutoSpellCheckingAction->isChecked() );
788 TQStringList transportHistory = GlobalSettings::self()->transportHistory();
789 transportHistory.remove(mTransport->currentText());
790 if (KMTransportInfo::availableTransports().findIndex(mTransport
791 ->currentText()) == -1) {
792 transportHistory.prepend(mTransport->currentText());
794 GlobalSettings::self()->setTransportHistory( transportHistory );
795 GlobalSettings::self()->setUseFixedFont( mFixedFontAction->isChecked() );
796 GlobalSettings::self()->setUseHtmlMarkup( mHtmlMarkup );
797 GlobalSettings::self()->setComposerSize( size() );
798 GlobalSettings::self()->setShowSnippetManager( mSnippetAction->isChecked() );
800 KConfigGroupSaver saver( KMKernel::config(),
"Geometry" );
801 saveMainWindowSettings( KMKernel::config(),
"Composer" );
802 GlobalSettings::setSnippetSplitterPosition( mSnippetSplitter->sizes() );
805 GlobalSettings::self()->writeConfig();
809 void KMComposeWin::autoSaveMessage()
811 kdDebug(5006) << k_funcinfo << endl;
812 if ( !mMsg || mComposer || mAutoSaveFilename.isEmpty() )
814 kdDebug(5006) << k_funcinfo <<
"autosaving message" << endl;
816 if ( mAutoSaveTimer )
817 mAutoSaveTimer->stop();
819 connect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
820 TQT_TQOBJECT(
this), TQT_SLOT( slotContinueAutoSave() ) );
824 applyChanges(
true,
true );
829 void KMComposeWin::slotContinueAutoSave()
831 disconnect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
832 TQT_TQOBJECT(
this), TQT_SLOT( slotContinueAutoSave() ) );
835 if ( mComposedMessages.isEmpty() ) {
836 kdDebug(5006) <<
"Composing the message failed." << endl;
839 KMMessage *msg = mComposedMessages.first();
843 kdDebug(5006) << k_funcinfo <<
"opening autoSaveFile " << mAutoSaveFilename
845 const TQString filename =
847 KSaveFile autoSaveFile( filename, 0600 );
848 int status = autoSaveFile.status();
849 kdDebug(5006) << k_funcinfo <<
"autoSaveFile.status() = " << status << endl;
851 kdDebug(5006) <<
"autosaving message in " << filename << endl;
852 int fd = autoSaveFile.handle();
854 if ( ::write( fd, msgStr.data(), msgStr.length() ) == -1 )
858 kdDebug(5006) << k_funcinfo <<
"closing autoSaveFile" << endl;
859 autoSaveFile.close();
860 mLastAutoSaveErrno = 0;
863 kdDebug(5006) << k_funcinfo <<
"autosaving failed" << endl;
864 autoSaveFile.abort();
865 if ( status != mLastAutoSaveErrno ) {
867 KMessageBox::queuedMessageBox( 0, KMessageBox::Sorry,
868 i18n(
"Autosaving the message as %1 "
871 .arg( filename, strerror( status ) ),
872 i18n(
"Autosaving Failed") );
873 mLastAutoSaveErrno = status;
877 if ( autoSaveInterval() > 0 )
882 void KMComposeWin::slotView(
void)
891 if (!TQT_TQOBJECT_CONST(sender())->isA(
"KToggleAction"))
893 KToggleAction *act = (KToggleAction *) sender();
895 if (act == mAllFieldsAction)
897 else if (act == mIdentityAction)
899 else if (act == mTransportAction)
901 else if (act == mFromAction)
903 else if (act == mReplyToAction)
905 else if (act == mToAction)
907 else if (act == mCcAction)
909 else if (act == mBccAction)
911 else if (act == mSubjectAction)
913 else if (act == mFccAction)
915 else if ( act == mDictionaryAction )
920 kdDebug(5006) <<
"Something is wrong (Oh, yeah?)" << endl;
927 if (!act->isChecked())
930 if (
id > 0) mShowHeaders = mShowHeaders & ~id;
931 else mShowHeaders = abs(mShowHeaders);
936 if (
id > 0) mShowHeaders |= id;
937 else mShowHeaders = -abs(mShowHeaders);
942 int KMComposeWin::calcColumnWidth(
int which,
long allShowing,
int width)
944 if ( (allShowing & which) == 0 )
948 if ( which == HDR_IDENTITY )
950 else if ( which == HDR_DICTIONARY )
951 w = mDictionaryLabel;
952 else if ( which == HDR_FCC )
954 else if ( which == HDR_TRANSPORT )
956 else if ( which == HDR_FROM )
958 else if ( which == HDR_REPLY_TO )
960 else if ( which == HDR_SUBJECT )
965 w->setBuddy( mEditor );
968 return TQMAX( width, w->sizeHint().width() );
971 void KMComposeWin::rethinkFields(
bool fromSlot)
974 int mask, row, numRows;
977 if (mShowHeaders < 0)
978 showHeaders = HDR_ALL;
980 showHeaders = mShowHeaders;
982 for (mask=1,mNumHeaders=0; mask<=showHeaders; mask<<=1)
983 if ((showHeaders&mask) != 0) mNumHeaders++;
985 numRows = mNumHeaders + 1;
989 mGrid =
new TQGridLayout( mHeadersArea, numRows, 3, KDialogBase::marginHint()/2, KDialogBase::spacingHint());
990 mGrid->setColStretch(0, 1);
991 mGrid->setColStretch(1, 100);
992 mGrid->setColStretch(2, 1);
993 mGrid->setRowStretch( mNumHeaders + 1, 100 );
996 kdDebug(5006) <<
"KMComposeWin::rethinkFields" << endl;
997 if (mRecipientsEditor)
998 mLabelWidth = mRecipientsEditor->setFirstColumnWidth( 0 );
999 mLabelWidth = calcColumnWidth( HDR_IDENTITY, showHeaders, mLabelWidth );
1000 mLabelWidth = calcColumnWidth( HDR_DICTIONARY, showHeaders, mLabelWidth );
1001 mLabelWidth = calcColumnWidth( HDR_FCC, showHeaders, mLabelWidth );
1002 mLabelWidth = calcColumnWidth( HDR_TRANSPORT, showHeaders, mLabelWidth );
1003 mLabelWidth = calcColumnWidth( HDR_FROM, showHeaders, mLabelWidth );
1004 mLabelWidth = calcColumnWidth( HDR_REPLY_TO, showHeaders, mLabelWidth );
1005 mLabelWidth = calcColumnWidth( HDR_SUBJECT, showHeaders, mLabelWidth );
1007 if (!fromSlot) mAllFieldsAction->setChecked(showHeaders==HDR_ALL);
1009 if (!fromSlot) mIdentityAction->setChecked(abs(mShowHeaders)&HDR_IDENTITY);
1010 rethinkHeaderLine(showHeaders,HDR_IDENTITY, row,
1011 mLblIdentity, mIdentity, mBtnIdentity);
1013 if (!fromSlot) mDictionaryAction->setChecked(abs(mShowHeaders)&HDR_DICTIONARY);
1014 rethinkHeaderLine(showHeaders,HDR_DICTIONARY, row,
1015 mDictionaryLabel, mDictionaryCombo, mBtnDictionary );
1017 if (!fromSlot) mFccAction->setChecked(abs(mShowHeaders)&HDR_FCC);
1018 rethinkHeaderLine(showHeaders,HDR_FCC, row,
1019 mLblFcc, mFcc, mBtnFcc);
1021 if (!fromSlot) mTransportAction->setChecked(abs(mShowHeaders)&HDR_TRANSPORT);
1022 rethinkHeaderLine(showHeaders,HDR_TRANSPORT, row,
1023 mLblTransport, mTransport, mBtnTransport);
1025 if (!fromSlot) mFromAction->setChecked(abs(mShowHeaders)&HDR_FROM);
1026 rethinkHeaderLine(showHeaders,HDR_FROM, row,
1027 mLblFrom, mEdtFrom );
1029 TQWidget *prevFocus = mEdtFrom;
1031 if (!fromSlot) mReplyToAction->setChecked(abs(mShowHeaders)&HDR_REPLY_TO);
1032 rethinkHeaderLine(showHeaders,HDR_REPLY_TO,row,
1033 mLblReplyTo, mEdtReplyTo, 0);
1034 if ( showHeaders & HDR_REPLY_TO ) {
1035 prevFocus = connectFocusMoving( prevFocus, mEdtReplyTo );
1038 if ( mClassicalRecipients ) {
1039 if (!fromSlot) mToAction->setChecked(abs(mShowHeaders)&HDR_TO);
1040 rethinkHeaderLine(showHeaders, HDR_TO, row,
1041 mLblTo, mEdtTo, mBtnTo,
1042 i18n(
"Primary Recipients"),
1043 i18n(
"<qt>The email addresses you put "
1044 "in this field receive a copy of the email.</qt>"));
1045 if ( showHeaders & HDR_TO ) {
1046 prevFocus = connectFocusMoving( prevFocus, mEdtTo );
1049 if (!fromSlot) mCcAction->setChecked(abs(mShowHeaders)&HDR_CC);
1050 rethinkHeaderLine(showHeaders, HDR_CC, row,
1051 mLblCc, mEdtCc, mBtnCc,
1052 i18n(
"Additional Recipients"),
1053 i18n(
"<qt>The email addresses you put "
1054 "in this field receive a copy of the email. "
1055 "Technically it is the same thing as putting all the "
1056 "addresses in the <b>To:</b> field but differs in "
1057 "that it usually symbolises the receiver of the "
1058 "Carbon Copy (CC) is a listener, not the main "
1059 "recipient.</qt>"));
1060 if ( showHeaders & HDR_CC ) {
1061 prevFocus = connectFocusMoving( prevFocus, mEdtCc );
1064 if (!fromSlot) mBccAction->setChecked(abs(mShowHeaders)&HDR_BCC);
1065 rethinkHeaderLine(showHeaders,HDR_BCC, row,
1066 mLblBcc, mEdtBcc, mBtnBcc,
1067 i18n(
"Hidden Recipients"),
1068 i18n(
"<qt>Essentially the same thing "
1069 "as the <b>Copy To:</b> field but differs in that "
1070 "all other recipients do not see who receives a "
1071 "blind copy.</qt>"));
1072 if ( showHeaders & HDR_BCC ) {
1073 prevFocus = connectFocusMoving( prevFocus, mEdtBcc );
1076 mGrid->addMultiCellWidget( mRecipientsEditor, row, row, 0, 2 );
1079 if ( showHeaders & HDR_REPLY_TO ) {
1080 connect( mEdtReplyTo, TQT_SIGNAL( focusDown() ), mRecipientsEditor,
1081 TQT_SLOT( setFocusTop() ) );
1083 connect( mEdtFrom, TQT_SIGNAL( focusDown() ), mRecipientsEditor,
1084 TQT_SLOT( setFocusTop() ) );
1086 if ( showHeaders & HDR_REPLY_TO ) {
1087 connect( mRecipientsEditor, TQT_SIGNAL( focusUp() ), mEdtReplyTo, TQT_SLOT( setFocus() ) );
1089 connect( mRecipientsEditor, TQT_SIGNAL( focusUp() ), mEdtFrom, TQT_SLOT( setFocus() ) );
1092 connect( mRecipientsEditor, TQT_SIGNAL( focusDown() ), mEdtSubject,
1093 TQT_SLOT( setFocus() ) );
1094 connect( mEdtSubject, TQT_SIGNAL( focusUp() ), mRecipientsEditor,
1095 TQT_SLOT( setFocusBottom() ) );
1097 prevFocus = mRecipientsEditor;
1099 if (!fromSlot) mSubjectAction->setChecked(abs(mShowHeaders)&HDR_SUBJECT);
1100 rethinkHeaderLine(showHeaders,HDR_SUBJECT, row,
1101 mLblSubject, mEdtSubject);
1102 connectFocusMoving( mEdtSubject, mEditor );
1104 assert(row<=mNumHeaders);
1107 if( !mAtmList.isEmpty() )
1108 mAtmListView->show();
1110 mAtmListView->hide();
1111 resize(this->size());
1114 mHeadersArea->setMaximumHeight( mHeadersArea->sizeHint().height() );
1116 mHeadersArea->show();
1118 slotUpdateAttachActions();
1119 mIdentityAction->setEnabled(!mAllFieldsAction->isChecked());
1120 mDictionaryAction->setEnabled( !mAllFieldsAction->isChecked() );
1121 mTransportAction->setEnabled(!mAllFieldsAction->isChecked());
1122 mFromAction->setEnabled(!mAllFieldsAction->isChecked());
1123 if ( mReplyToAction ) mReplyToAction->setEnabled(!mAllFieldsAction->isChecked());
1124 if ( mToAction ) mToAction->setEnabled(!mAllFieldsAction->isChecked());
1125 if ( mCcAction ) mCcAction->setEnabled(!mAllFieldsAction->isChecked());
1126 if ( mBccAction ) mBccAction->setEnabled(!mAllFieldsAction->isChecked());
1127 mFccAction->setEnabled(!mAllFieldsAction->isChecked());
1128 mSubjectAction->setEnabled(!mAllFieldsAction->isChecked());
1129 if (mRecipientsEditor)
1130 mRecipientsEditor->setFirstColumnWidth( mLabelWidth );
1133 TQWidget *KMComposeWin::connectFocusMoving( TQWidget *prev, TQWidget *next )
1135 connect( prev, TQT_SIGNAL( focusDown() ), next, TQT_SLOT( setFocus() ) );
1136 connect( next, TQT_SIGNAL( focusUp() ), prev, TQT_SLOT( setFocus() ) );
1142 void KMComposeWin::rethinkHeaderLine(
int aValue,
int aMask,
int& aRow,
1144 TQLineEdit* aEdt, TQPushButton* aBtn,
1145 const TQString &toolTip,
const TQString &whatsThis )
1149 if ( !toolTip.isEmpty() )
1150 TQToolTip::add( aLbl, toolTip );
1151 if ( !whatsThis.isEmpty() )
1152 TQWhatsThis::add( aLbl, whatsThis );
1153 aLbl->setFixedWidth( mLabelWidth );
1154 aLbl->setBuddy(aEdt);
1155 mGrid->addWidget(aLbl, aRow, 0);
1156 aEdt->setBackgroundColor( mBackColor );
1160 mGrid->addWidget(aEdt, aRow, 1);
1162 mGrid->addWidget(aBtn, aRow, 2);
1165 mGrid->addMultiCellWidget(aEdt, aRow, aRow, 1, 2 );
1173 if (aBtn) aBtn->hide();
1178 void KMComposeWin::rethinkHeaderLine(
int aValue,
int aMask,
int& aRow,
1180 TQComboBox* aCbx, TQCheckBox* aChk)
1185 aLbl->resize((
int)aLbl->sizeHint().width(),aLbl->sizeHint().height() + 6);
1186 aLbl->setMinimumSize(aLbl->size());
1188 aLbl->setBuddy(aCbx);
1189 mGrid->addWidget(aLbl, aRow, 0);
1191 aCbx->setMinimumSize(100, aLbl->height()+2);
1193 mGrid->addWidget(aCbx, aRow, 1);
1195 mGrid->addWidget(aChk, aRow, 2);
1196 aChk->setFixedSize(aChk->sizeHint().width(), aLbl->height());
1211 void KMComposeWin::getTransportMenu()
1213 TQStringList availTransports;
1215 mActNowMenu->clear();
1216 mActLaterMenu->clear();
1218 TQStringList::Iterator it;
1220 for(it = availTransports.begin(); it != availTransports.end() ; ++it,
id++)
1222 mActNowMenu->insertItem((*it).replace(
"&",
"&&"), id);
1223 mActLaterMenu->insertItem((*it).replace(
"&",
"&&"), id);
1229 void KMComposeWin::setupActions(
void)
1231 KActionMenu *actActionNowMenu, *actActionLaterMenu;
1233 if (kmkernel->msgSender()->sendImmediate())
1236 ( void )
new KAction( i18n(
"&Send Mail"),
"mail_send", CTRL+Key_Return,
1237 TQT_TQOBJECT(
this), TQT_SLOT(slotSendNow()), actionCollection(),
"send_default");
1240 actActionNowMenu =
new KActionMenu (i18n(
"&Send Mail Via"),
"mail_send",
1241 actionCollection(),
"send_default_via" );
1243 (void)
new KAction (i18n(
"Send &Later"),
"queue", 0, TQT_TQOBJECT(
this),
1244 TQT_SLOT(slotSendLater()), actionCollection(),
"send_alternative");
1245 actActionLaterMenu =
new KActionMenu (i18n(
"Send &Later Via"),
"queue",
1246 actionCollection(),
"send_alternative_via" );
1252 (void)
new KAction (i18n(
"Send &Later"),
"queue",
1254 TQT_TQOBJECT(
this), TQT_SLOT(slotSendLater()), actionCollection(),
"send_default");
1255 actActionLaterMenu =
new KActionMenu (i18n(
"Send &Later Via"),
"queue",
1256 actionCollection(),
"send_default_via" );
1258 ( void )
new KAction( i18n(
"&Send Mail"),
"mail_send", 0,
1259 TQT_TQOBJECT(
this), TQT_SLOT(slotSendNow()), actionCollection(),
"send_alternative");
1262 actActionNowMenu =
new KActionMenu (i18n(
"&Send Mail Via"),
"mail_send",
1263 actionCollection(),
"send_alternative_via" );
1268 actActionNowMenu->setDelayed(
true);
1269 actActionLaterMenu->setDelayed(
true);
1271 connect( actActionNowMenu, TQT_SIGNAL( activated() ),
this,
1272 TQT_SLOT( slotSendNow() ) );
1273 connect( actActionLaterMenu, TQT_SIGNAL( activated() ),
this,
1274 TQT_SLOT( slotSendLater() ) );
1277 mActNowMenu = actActionNowMenu->popupMenu();
1278 mActLaterMenu = actActionLaterMenu->popupMenu();
1280 connect( mActNowMenu, TQT_SIGNAL( activated(
int ) ),
this,
1281 TQT_SLOT( slotSendNowVia(
int ) ) );
1282 connect( mActNowMenu, TQT_SIGNAL( aboutToShow() ),
this,
1283 TQT_SLOT( getTransportMenu() ) );
1285 connect( mActLaterMenu, TQT_SIGNAL( activated(
int ) ),
this,
1286 TQT_SLOT( slotSendLaterVia(
int ) ) );
1287 connect( mActLaterMenu, TQT_SIGNAL( aboutToShow() ),
this,
1288 TQT_SLOT( getTransportMenu() ) );
1293 (void)
new KAction (i18n(
"Save as &Draft"),
"filesave", 0,
1294 TQT_TQOBJECT(
this), TQT_SLOT(slotSaveDraft()),
1295 actionCollection(),
"save_in_drafts");
1296 (void)
new KAction (i18n(
"Save as &Template"),
"filesave", 0,
1297 TQT_TQOBJECT(
this), TQT_SLOT(slotSaveTemplate()),
1298 actionCollection(),
"save_in_templates");
1299 (void)
new KAction (i18n(
"&Insert File..."),
"fileopen", 0,
1300 TQT_TQOBJECT(
this), TQT_SLOT(slotInsertFile()),
1301 actionCollection(),
"insert_file");
1302 mRecentAction =
new KRecentFilesAction (i18n(
"&Insert File Recent"),
1304 TQT_TQOBJECT(
this), TQT_SLOT(slotInsertRecentFile(
const KURL&)),
1305 actionCollection(),
"insert_file_recent");
1307 mRecentAction->loadEntries( KMKernel::config() );
1309 (void)
new KAction (i18n(
"&Address Book"),
"contents",0,
1310 TQT_TQOBJECT(
this), TQT_SLOT(slotAddrBook()),
1311 actionCollection(),
"addressbook");
1312 (void)
new KAction (i18n(
"&New Composer"),
"mail_new",
1313 KStdAccel::shortcut(KStdAccel::New),
1314 TQT_TQOBJECT(
this), TQT_SLOT(slotNewComposer()),
1315 actionCollection(),
"new_composer");
1316 (void)
new KAction (i18n(
"New Main &Window"),
"window_new", 0,
1317 TQT_TQOBJECT(
this), TQT_SLOT(slotNewMailReader()),
1318 actionCollection(),
"open_mailreader");
1320 if ( !mClassicalRecipients ) {
1321 new KAction( i18n(
"Select &Recipients..."), CTRL + Key_L, TQT_TQOBJECT(mRecipientsEditor),
1322 TQT_SLOT( selectRecipients() ), actionCollection(),
"select_recipients" );
1323 new KAction( i18n(
"Save &Distribution List..."), 0, TQT_TQOBJECT(mRecipientsEditor),
1324 TQT_SLOT( saveDistributionList() ), actionCollection(),
1325 "save_distribution_list" );
1329 KStdAction::print (TQT_TQOBJECT(
this), TQT_SLOT(slotPrint()), actionCollection());
1330 KStdAction::close (TQT_TQOBJECT(
this), TQT_SLOT(slotClose()), actionCollection());
1332 KStdAction::undo (TQT_TQOBJECT(
this), TQT_SLOT(slotUndo()), actionCollection());
1333 KStdAction::redo (TQT_TQOBJECT(
this), TQT_SLOT(slotRedo()), actionCollection());
1334 KStdAction::cut (TQT_TQOBJECT(
this), TQT_SLOT(slotCut()), actionCollection());
1335 KStdAction::copy (TQT_TQOBJECT(
this), TQT_SLOT(slotCopy()), actionCollection());
1336 KStdAction::pasteText (TQT_TQOBJECT(
this), TQT_SLOT(slotPasteClipboard()), actionCollection());
1337 KStdAction::selectAll (TQT_TQOBJECT(
this), TQT_SLOT(slotMarkAll()), actionCollection());
1339 KStdAction::find (TQT_TQOBJECT(
this), TQT_SLOT(slotFind()), actionCollection());
1340 KStdAction::findNext(TQT_TQOBJECT(
this), TQT_SLOT(slotSearchAgain()), actionCollection());
1342 KStdAction::replace (TQT_TQOBJECT(
this), TQT_SLOT(slotReplace()), actionCollection());
1343 KStdAction::spelling (TQT_TQOBJECT(
this), TQT_SLOT(slotSpellcheck()), actionCollection(),
"spellcheck");
1345 mPasteQuotation =
new KAction (i18n(
"Pa&ste as Quotation"),0,TQT_TQOBJECT(
this),TQT_SLOT( slotPasteClipboardAsQuotation()),
1346 actionCollection(),
"paste_quoted");
1348 (void)
new KAction (i18n(
"Paste as Attac&hment"),0,TQT_TQOBJECT(
this),TQT_SLOT( slotPasteClipboardAsAttachment()),
1349 actionCollection(),
"paste_att");
1351 KAction * addq =
new KAction(i18n(
"Add &Quote Characters"), 0, TQT_TQOBJECT(
this),
1352 TQT_SLOT(slotAddQuotes()), actionCollection(),
"tools_quote");
1353 connect( mEditor, TQT_SIGNAL(selectionAvailable(
bool)),
1354 addq, TQT_SLOT(setEnabled(
bool)) );
1356 KAction * remq =
new KAction(i18n(
"Re&move Quote Characters"), 0, TQT_TQOBJECT(
this),
1357 TQT_SLOT(slotRemoveQuotes()), actionCollection(),
"tools_unquote");
1358 connect( mEditor, TQT_SIGNAL(selectionAvailable(
bool)),
1359 remq, TQT_SLOT(setEnabled(
bool)) );
1362 (void)
new KAction (i18n(
"Cl&ean Spaces"), 0, TQT_TQOBJECT(
this), TQT_SLOT(slotCleanSpace()),
1363 actionCollection(),
"clean_spaces");
1365 mFixedFontAction =
new KToggleAction( i18n(
"Use Fi&xed Font"), 0, TQT_TQOBJECT(
this),
1366 TQT_SLOT(slotUpdateFont()), actionCollection(),
"toggle_fixedfont" );
1367 mFixedFontAction->setChecked( GlobalSettings::self()->useFixedFont() );
1370 mUrgentAction =
new KToggleAction (i18n(
"&Urgent"), 0,
1373 mRequestMDNAction =
new KToggleAction ( i18n(
"&Request Disposition Notification"), 0,
1375 "options_request_mdn");
1376 mRequestMDNAction->setChecked(GlobalSettings::self()->requestMDN());
1378 mEncodingAction =
new KSelectAction( i18n(
"Se&t Encoding" ),
"charset",
1379 0, TQT_TQOBJECT(
this), TQT_SLOT(slotSetCharset() ),
1380 actionCollection(),
"charsets" );
1381 mWordWrapAction =
new KToggleAction (i18n(
"&Wordwrap"), 0,
1382 actionCollection(),
"wordwrap");
1383 mWordWrapAction->setChecked(GlobalSettings::self()->wordWrap());
1384 connect(mWordWrapAction, TQT_SIGNAL(toggled(
bool)), TQT_SLOT(slotWordWrapToggled(
bool)));
1386 mSnippetAction =
new KToggleAction ( i18n(
"&Snippets"), 0,
1387 actionCollection(),
"snippets");
1388 connect(mSnippetAction, TQT_SIGNAL(toggled(
bool)), mSnippetWidget, TQT_SLOT(setShown(
bool)) );
1389 mSnippetAction->setChecked( GlobalSettings::self()->showSnippetManager() );
1391 mAutoSpellCheckingAction =
1392 new KToggleAction( i18n(
"&Automatic Spellchecking" ),
"spellcheck", 0,
1393 actionCollection(),
"options_auto_spellchecking" );
1394 const bool spellChecking = GlobalSettings::self()->autoSpellChecking();
1395 mAutoSpellCheckingAction->setEnabled( !GlobalSettings::self()->useExternalEditor() );
1396 mAutoSpellCheckingAction->setChecked( !GlobalSettings::self()->useExternalEditor() && spellChecking );
1397 slotAutoSpellCheckingToggled( !GlobalSettings::self()->useExternalEditor() && spellChecking );
1398 connect( mAutoSpellCheckingAction, TQT_SIGNAL( toggled(
bool ) ),
1399 TQT_TQOBJECT(
this), TQT_SLOT( slotAutoSpellCheckingToggled(
bool ) ) );
1401 TQStringList encodings = KMMsgBase::supportedEncodings(
true);
1402 encodings.prepend( i18n(
"Auto-Detect"));
1403 mEncodingAction->setItems( encodings );
1404 mEncodingAction->setCurrentItem( -1 );
1407 markupAction =
new KToggleAction (i18n(
"Formatting (HTML)"), 0, TQT_TQOBJECT(
this),
1408 TQT_SLOT(slotToggleMarkup()),
1409 actionCollection(),
"html");
1411 mAllFieldsAction =
new KToggleAction (i18n(
"&All Fields"), 0, TQT_TQOBJECT(
this),
1412 TQT_SLOT(slotView()),
1413 actionCollection(),
"show_all_fields");
1414 mIdentityAction =
new KToggleAction (i18n(
"&Identity"), 0, TQT_TQOBJECT(
this),
1415 TQT_SLOT(slotView()),
1416 actionCollection(),
"show_identity");
1417 mDictionaryAction =
new KToggleAction (i18n(
"&Dictionary"), 0, TQT_TQOBJECT(
this),
1418 TQT_SLOT(slotView()),
1419 actionCollection(),
"show_dictionary");
1420 mFccAction =
new KToggleAction (i18n(
"&Sent-Mail Folder"), 0, TQT_TQOBJECT(
this),
1421 TQT_SLOT(slotView()),
1422 actionCollection(),
"show_fcc");
1423 mTransportAction =
new KToggleAction (i18n(
"&Mail Transport"), 0, TQT_TQOBJECT(
this),
1424 TQT_SLOT(slotView()),
1425 actionCollection(),
"show_transport");
1426 mFromAction =
new KToggleAction (i18n(
"&From"), 0, TQT_TQOBJECT(
this),
1427 TQT_SLOT(slotView()),
1428 actionCollection(),
"show_from");
1429 mReplyToAction =
new KToggleAction (i18n(
"&Reply To"), 0, TQT_TQOBJECT(
this),
1430 TQT_SLOT(slotView()),
1431 actionCollection(),
"show_reply_to");
1432 if ( mClassicalRecipients ) {
1433 mToAction =
new KToggleAction (i18n(
"&To"), 0, TQT_TQOBJECT(
this),
1434 TQT_SLOT(slotView()),
1435 actionCollection(),
"show_to");
1436 mCcAction =
new KToggleAction (i18n(
"&CC"), 0, TQT_TQOBJECT(
this),
1437 TQT_SLOT(slotView()),
1438 actionCollection(),
"show_cc");
1439 mBccAction =
new KToggleAction (i18n(
"&BCC"), 0, TQT_TQOBJECT(
this),
1440 TQT_SLOT(slotView()),
1441 actionCollection(),
"show_bcc");
1443 mSubjectAction =
new KToggleAction (i18n(
"S&ubject"), 0, TQT_TQOBJECT(
this),
1444 TQT_SLOT(slotView()),
1445 actionCollection(),
"show_subject");
1448 mAppendSignatureAction =
new KAction (i18n(
"Append S&ignature"), 0, TQT_TQOBJECT(
this),
1449 TQT_SLOT(slotAppendSignature()),
1450 actionCollection(),
"append_signature");
1451 mPrependSignatureAction =
new KAction (i18n(
"Prepend S&ignature"), 0, TQT_TQOBJECT(
this),
1452 TQT_SLOT(slotPrependSignature()),
1453 actionCollection(),
"prepend_signature");
1455 mInsertSignatureAction =
new KAction (i18n(
"Insert Signature At C&ursor Position"),
"edit", 0, TQT_TQOBJECT(
this),
1456 TQT_SLOT(slotInsertSignatureAtCursor()),
1457 actionCollection(),
"insert_signature_at_cursor_position");
1459 mAttachPK =
new KAction (i18n(
"Attach &Public Key..."), 0, TQT_TQOBJECT(
this),
1460 TQT_SLOT(slotInsertPublicKey()),
1461 actionCollection(),
"attach_public_key");
1462 mAttachMPK =
new KAction (i18n(
"Attach &My Public Key"), 0, TQT_TQOBJECT(
this),
1463 TQT_SLOT(slotInsertMyPublicKey()),
1464 actionCollection(),
"attach_my_public_key");
1465 (void)
new KAction (i18n(
"&Attach File..."),
"attach",
1466 0, TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFile()),
1467 actionCollection(),
"attach");
1468 mAttachRemoveAction =
new KAction (i18n(
"&Remove Attachment"), 0, TQT_TQOBJECT(
this),
1469 TQT_SLOT(slotAttachRemove()),
1470 actionCollection(),
"remove");
1471 mAttachSaveAction =
new KAction (i18n(
"&Save Attachment As..."),
"filesave",0,
1472 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachSave()),
1473 actionCollection(),
"attach_save");
1474 mAttachPropertiesAction =
new KAction (i18n(
"Attachment Pr&operties"), 0, TQT_TQOBJECT(
this),
1475 TQT_SLOT(slotAttachProperties()),
1476 actionCollection(),
"attach_properties");
1478 setStandardToolBarMenuEnabled(
true);
1480 KStdAction::keyBindings(TQT_TQOBJECT(
this), TQT_SLOT(slotEditKeys()), actionCollection());
1481 KStdAction::configureToolbars(TQT_TQOBJECT(
this), TQT_SLOT(slotEditToolbars()), actionCollection());
1482 KStdAction::preferences(kmkernel, TQT_SLOT(slotShowConfigurationDialog()), actionCollection());
1484 (void)
new KAction (i18n(
"&Spellchecker..."), 0, TQT_TQOBJECT(
this), TQT_SLOT(slotSpellcheckConfig()),
1485 actionCollection(),
"setup_spellchecker");
1487 if ( Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" ) ) {
1488 KToggleAction * a =
new KToggleAction( i18n(
"Encrypt Message with Chiasmus..." ),
1489 "chidecrypted", 0, actionCollection(),
1490 "encrypt_message_chiasmus" );
1491 a->setCheckedState( KGuiItem( i18n(
"Encrypt Message with Chiasmus..." ),
"chiencrypted" ) );
1492 mEncryptChiasmusAction = a;
1493 connect( mEncryptChiasmusAction, TQT_SIGNAL(toggled(
bool)),
1494 TQT_TQOBJECT(
this), TQT_SLOT(slotEncryptChiasmusToggled(
bool)) );
1496 mEncryptChiasmusAction = 0;
1499 mEncryptAction =
new KToggleAction (i18n(
"&Encrypt Message"),
1501 actionCollection(),
"encrypt_message");
1502 mSignAction =
new KToggleAction (i18n(
"&Sign Message"),
1504 actionCollection(),
"sign_message");
1506 const KPIM::Identity & ident =
1507 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
1510 mLastIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
1511 mLastIdentityHasEncryptionKey = !ident.pgpEncryptionKey().isEmpty() || !ident.smimeEncryptionKey().isEmpty();
1513 mLastEncryptActionState =
false;
1514 mLastSignActionState = GlobalSettings::self()->pgpAutoSign();
1517 mAttachPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() );
1521 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
1522 !ident.pgpEncryptionKey().isEmpty() );
1524 if ( !Kleo::CryptoBackendFactory::instance()->openpgp() && !Kleo::CryptoBackendFactory::instance()->smime() ) {
1526 mEncryptAction->setEnabled(
false );
1527 setEncryption(
false );
1528 mSignAction->setEnabled(
false );
1529 setSigning(
false );
1531 const bool canOpenPGPSign = Kleo::CryptoBackendFactory::instance()->openpgp()
1532 && !ident.pgpSigningKey().isEmpty();
1533 const bool canSMIMESign = Kleo::CryptoBackendFactory::instance()->smime()
1534 && !ident.smimeSigningKey().isEmpty();
1536 setEncryption(
false );
1537 setSigning( ( canOpenPGPSign || canSMIMESign ) && GlobalSettings::self()->pgpAutoSign() );
1540 connect(mEncryptAction, TQT_SIGNAL(toggled(
bool)),
1541 TQT_SLOT(slotEncryptToggled(
bool )));
1542 connect(mSignAction, TQT_SIGNAL(toggled(
bool)),
1543 TQT_SLOT(slotSignToggled(
bool )));
1546 for (
int i = 0 ; i < numCryptoMessageFormats ; ++i )
1547 l.push_back( Kleo::cryptoMessageFormatToLabel( cryptoMessageFormats[i] ) );
1549 mCryptoModuleAction =
new KSelectAction( i18n(
"&Cryptographic Message Format" ), 0,
1550 TQT_TQOBJECT(
this), TQT_SLOT(slotSelectCryptoModule()),
1551 actionCollection(),
"options_select_crypto" );
1552 mCryptoModuleAction->setItems( l );
1553 mCryptoModuleAction->setCurrentItem( format2cb( ident.preferredCryptoMessageFormat() ) );
1554 mCryptoModuleAction->setToolTip( i18n(
"Select a cryptographic format for this message" ) );
1555 slotSelectCryptoModule(
true );
1557 TQStringList styleItems;
1558 styleItems << i18n(
"Standard" );
1559 styleItems << i18n(
"Bulleted List (Disc)" );
1560 styleItems << i18n(
"Bulleted List (Circle)" );
1561 styleItems << i18n(
"Bulleted List (Square)" );
1562 styleItems << i18n(
"Ordered List (Decimal)" );
1563 styleItems << i18n(
"Ordered List (Alpha lower)" );
1564 styleItems << i18n(
"Ordered List (Alpha upper)" );
1566 listAction =
new KSelectAction( i18n(
"Select Style" ), 0, actionCollection(),
1568 listAction->setItems( styleItems );
1569 listAction->setToolTip( i18n(
"Select a list style" ) );
1570 connect( listAction, TQT_SIGNAL( activated(
const TQString& ) ),
1571 TQT_SLOT( slotListAction(
const TQString& ) ) );
1572 fontAction =
new KFontAction(
"Select Font", 0, actionCollection(),
1574 fontAction->setToolTip( i18n(
"Select a font" ) );
1575 connect( fontAction, TQT_SIGNAL( activated(
const TQString& ) ),
1576 TQT_SLOT( slotFontAction(
const TQString& ) ) );
1577 fontSizeAction =
new KFontSizeAction(
"Select Size", 0, actionCollection(),
1579 fontSizeAction->setToolTip( i18n(
"Select a font size" ) );
1580 connect( fontSizeAction, TQT_SIGNAL( fontSizeChanged(
int ) ),
1581 TQT_SLOT( slotSizeAction(
int ) ) );
1583 alignLeftAction =
new KToggleAction (i18n(
"Align Left"),
"text_left", 0,
1584 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignLeft()), actionCollection(),
1586 alignLeftAction->setChecked(
true );
1587 alignRightAction =
new KToggleAction (i18n(
"Align Right"),
"text_right", 0,
1588 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignRight()), actionCollection(),
1590 alignCenterAction =
new KToggleAction (i18n(
"Align Center"),
"text_center", 0,
1591 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignCenter()), actionCollection(),
1593 textBoldAction =
new KToggleAction( i18n(
"&Bold"),
"text_bold", CTRL+Key_B,
1594 TQT_TQOBJECT(
this), TQT_SLOT(slotTextBold()),
1595 actionCollection(),
"text_bold");
1596 textItalicAction =
new KToggleAction( i18n(
"&Italic"),
"text_italic", CTRL+Key_I,
1597 TQT_TQOBJECT(
this), TQT_SLOT(slotTextItalic()),
1598 actionCollection(),
"text_italic");
1599 textUnderAction =
new KToggleAction( i18n(
"&Underline"),
"text_under", CTRL+Key_U,
1600 TQT_TQOBJECT(
this), TQT_SLOT(slotTextUnder()),
1601 actionCollection(),
"text_under");
1602 actionFormatReset =
new KAction( i18n(
"Reset Font Settings" ),
"eraser", 0,
1603 TQT_TQOBJECT(
this), TQT_SLOT( slotFormatReset() ),
1604 actionCollection(),
"format_reset");
1605 actionFormatColor =
new KAction( i18n(
"Text Color..." ),
"colorize", 0,
1606 TQT_TQOBJECT(
this), TQT_SLOT( slotTextColor() ),
1607 actionCollection(),
"format_color");
1610 createGUI(
"kmcomposerui.rc");
1612 connect( toolBar(
"htmlToolBar"), TQT_SIGNAL( visibilityChanged(
bool) ),
1613 TQT_TQOBJECT(
this), TQT_SLOT( htmlToolBarVisibilityChanged(
bool) ) );
1617 KAction* configureAction = actionCollection()->action(
"options_configure" );
1618 if ( configureAction )
1619 configureAction->setText( i18n(
"Configure KMail..." ) );
1623 void KMComposeWin::setupStatusBar(
void)
1625 statusBar()->insertItem(
"", 0, 1);
1626 statusBar()->setItemAlignment(0, AlignLeft | AlignVCenter);
1628 statusBar()->insertItem(i18n(
" Spellcheck: %1 ").arg(
" " ), 3, 0,
true );
1629 statusBar()->insertItem(i18n(
" Column: %1 ").arg(
" "), 2, 0,
true);
1630 statusBar()->insertItem(i18n(
" Line: %1 ").arg(
" "), 1, 0,
true);
1635 void KMComposeWin::updateCursorPosition()
1639 line = mEditor->currentLine();
1640 col = mEditor->currentColumn();
1641 temp = i18n(
" Line: %1 ").arg(line+1);
1642 statusBar()->changeItem(temp,1);
1643 temp = i18n(
" Column: %1 ").arg(col+1);
1644 statusBar()->changeItem(temp,2);
1649 void KMComposeWin::setupEditor(
void)
1652 mEditor->setModified(
false);
1653 TQFontMetrics fm(mBodyFont);
1654 mEditor->setTabStopWidth(fm.width(TQChar(
' ')) * 8);
1657 slotWordWrapToggled( GlobalSettings::self()->wordWrap() );
1683 updateCursorPosition();
1684 connect(mEditor,TQT_SIGNAL(CursorPositionChanged()),TQT_SLOT(updateCursorPosition()));
1685 connect( mEditor, TQT_SIGNAL( currentFontChanged(
const TQFont & ) ),
1686 TQT_TQOBJECT(
this), TQT_SLOT( fontChanged(
const TQFont & ) ) );
1687 connect( mEditor, TQT_SIGNAL( currentAlignmentChanged(
int ) ),
1688 TQT_TQOBJECT(
this), TQT_SLOT( alignmentChanged(
int ) ) );
1694 static TQString cleanedUpHeaderString(
const TQString & s )
1698 res.replace(
'\r',
"" );
1699 res.replace(
'\n',
" " );
1700 return res.stripWhiteSpace();
1704 TQString KMComposeWin::subject()
const
1706 return cleanedUpHeaderString( mEdtSubject->text() );
1710 TQString KMComposeWin::to()
const
1713 return cleanedUpHeaderString( mEdtTo->text() );
1714 }
else if ( mRecipientsEditor ) {
1715 return mRecipientsEditor->recipientString( Recipient::To );
1722 TQString KMComposeWin::cc()
const
1724 if ( mEdtCc && !mEdtCc->isHidden() ) {
1725 return cleanedUpHeaderString( mEdtCc->text() );
1726 }
else if ( mRecipientsEditor ) {
1727 return mRecipientsEditor->recipientString( Recipient::Cc );
1734 TQString KMComposeWin::bcc()
const
1736 if ( mEdtBcc && !mEdtBcc->isHidden() ) {
1737 return cleanedUpHeaderString( mEdtBcc->text() );
1738 }
else if ( mRecipientsEditor ) {
1739 return mRecipientsEditor->recipientString( Recipient::Bcc );
1746 TQString KMComposeWin::from()
const
1748 return cleanedUpHeaderString( mEdtFrom->text() );
1752 TQString KMComposeWin::replyTo()
const
1754 if ( mEdtReplyTo ) {
1755 return cleanedUpHeaderString( mEdtReplyTo->text() );
1762 void KMComposeWin::verifyWordWrapLengthIsAdequate(
const TQString &body)
1764 int maxLineLength = 0;
1767 if (mEditor->TQTextEdit::wordWrap() == TQTextEdit::FixedColumnWidth) {
1768 for (curPos = 0; curPos < (int)body.length(); ++curPos)
1769 if (body[curPos] ==
'\n') {
1770 if ((curPos - oldPos) > maxLineLength)
1771 maxLineLength = curPos - oldPos;
1774 if ((curPos - oldPos) > maxLineLength)
1775 maxLineLength = curPos - oldPos;
1776 if (mEditor->wrapColumnOrWidth() < maxLineLength)
1777 mEditor->setWrapColumnOrWidth(maxLineLength);
1782 void KMComposeWin::decryptOrStripOffCleartextSignature( TQCString& body )
1784 TQPtrList<Kpgp::Block> pgpBlocks;
1785 TQStrList nonPgpBlocks;
1786 if( Kpgp::Module::prepareMessageForDecryption( body,
1787 pgpBlocks, nonPgpBlocks ) )
1791 if( pgpBlocks.count() == 1 )
1793 Kpgp::Block* block = pgpBlocks.first();
1794 if( ( block->type() == Kpgp::PgpMessageBlock ) ||
1795 ( block->type() == Kpgp::ClearsignedBlock ) )
1797 if( block->type() == Kpgp::PgpMessageBlock )
1804 body = nonPgpBlocks.first()
1806 + nonPgpBlocks.last();
1813 void KMComposeWin::setTransport(
const TQString & transport )
1815 kdDebug(5006) <<
"KMComposeWin::setTransport( \"" << transport <<
"\" )" << endl;
1817 if ( transport.isEmpty() )
1820 bool transportFound =
false;
1821 for (
int i = 0; i < mTransport->count(); ++i ) {
1822 if ( mTransport->text(i) == transport ) {
1823 transportFound =
true;
1824 mTransport->setCurrentItem(i);
1825 kdDebug(5006) <<
"transport found, it's no. " << i <<
" in the list" << endl;
1829 if ( !transportFound ) {
1830 kdDebug(5006) <<
"unknown transport \"" << transport <<
"\"" << endl;
1831 if ( transport.startsWith(
"smtp://") || transport.startsWith(
"smtps://") ||
1832 transport.startsWith(
"file://") ) {
1834 mTransport->setEditText( transport );
1838 mTransport->setCurrentText( GlobalSettings::self()->defaultTransport() );
1844 void KMComposeWin::setMsg(
KMMessage* newMsg,
bool mayAutoSign,
1845 bool allowDecryption,
bool isModified)
1850 kdDebug(5006) <<
"KMComposeWin::setMsg() : newMsg == 0!" << endl;
1854 KPIM::IdentityManager * im = kmkernel->identityManager();
1856 mEdtFrom->setText(mMsg->from());
1857 mEdtReplyTo->setText(mMsg->replyTo());
1858 if ( mClassicalRecipients ) {
1859 mEdtTo->setText(mMsg->to());
1860 mEdtCc->setText(mMsg->cc());
1861 mEdtBcc->setText(mMsg->bcc());
1863 mRecipientsEditor->setRecipientString( mMsg->to(), Recipient::To );
1864 mRecipientsEditor->setRecipientString( mMsg->cc(), Recipient::Cc );
1865 mRecipientsEditor->setRecipientString( mMsg->bcc(), Recipient::Bcc );
1866 mRecipientsEditor->setFocusBottom();
1868 mEdtSubject->setText(mMsg->subject());
1870 const bool stickyIdentity = mBtnIdentity->isChecked() && !mIgnoreStickyFields;
1871 const bool messageHasIdentity = !newMsg->
headerField(
"X-KMail-Identity").isEmpty();
1872 if (!stickyIdentity && messageHasIdentity)
1873 mId = newMsg->
headerField(
"X-KMail-Identity").stripWhiteSpace().toUInt();
1877 if ( !stickyIdentity ) {
1878 disconnect(mIdentity,TQT_SIGNAL(identityChanged(uint)),
1879 TQT_TQOBJECT(
this), TQT_SLOT(slotIdentityChanged(uint)));
1882 mIdentity->setCurrentIdentity( mId );
1883 const uint idToApply = mId;
1884 if ( !stickyIdentity ) {
1885 connect(mIdentity,TQT_SIGNAL(identityChanged(uint)),
1886 TQT_TQOBJECT(
this), TQT_SLOT(slotIdentityChanged(uint)));
1891 if ( messageHasIdentity )
1892 mId = newMsg->
headerField(
"X-KMail-Identity").stripWhiteSpace().toUInt();
1894 mId = im->defaultIdentity().uoid();
1899 slotIdentityChanged( idToApply );
1901 const KPIM::Identity & ident = im->identityForUoid( mIdentity->currentIdentity() );
1905 TQString mdnAddr = newMsg->
headerField(
"Disposition-Notification-To");
1906 mRequestMDNAction->setChecked( ( !mdnAddr.isEmpty() &&
1907 im->thatIsMe( mdnAddr ) ) ||
1908 GlobalSettings::self()->requestMDN() );
1911 mUrgentAction->setChecked( newMsg->
isUrgent() );
1913 if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
1914 mMsg->removeHeaderField(
"X-Face");
1917 TQString xface = ident.xface();
1918 if (!xface.isEmpty())
1920 int numNL = ( xface.length() - 1 ) / 70;
1921 for (
int i = numNL; i > 0; --i )
1922 xface.insert( i*70,
"\n\t" );
1923 mMsg->setHeaderField(
"X-Face", xface);
1928 switch ( mMsg->encryptionState() ) {
1929 case KMMsgFullyEncrypted:
1930 case KMMsgPartiallyEncrypted:
1931 mLastEncryptActionState =
true;
1933 case KMMsgNotEncrypted:
1934 mLastEncryptActionState =
false;
1941 switch ( mMsg->signatureState() ) {
1942 case KMMsgFullySigned:
1943 case KMMsgPartiallySigned:
1944 mLastSignActionState =
true;
1946 case KMMsgNotSigned:
1947 mLastSignActionState =
false;
1954 if ( mMsg->headers().FindField(
"X-KMail-SignatureActionEnabled" ) )
1955 mLastSignActionState = (mMsg->headerField(
"X-KMail-SignatureActionEnabled" ) ==
"true");
1956 if ( mMsg->headers().FindField(
"X-KMail-EncryptActionEnabled" ) )
1957 mLastEncryptActionState = (mMsg->headerField(
"X-KMail-EncryptActionEnabled" ) ==
"true");
1958 if ( mMsg->headers().FindField(
"X-KMail-CryptoMessageFormat" ) )
1959 mCryptoModuleAction->setCurrentItem( format2cb( static_cast<Kleo::CryptoMessageFormat>(
1960 mMsg->headerField(
"X-KMail-CryptoMessageFormat" ).toInt() ) ) );
1962 mLastIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
1963 mLastIdentityHasEncryptionKey = !ident.pgpEncryptionKey().isEmpty() || !ident.smimeEncryptionKey().isEmpty();
1965 if ( Kleo::CryptoBackendFactory::instance()->openpgp() || Kleo::CryptoBackendFactory::instance()->smime() ) {
1966 const bool canOpenPGPSign = Kleo::CryptoBackendFactory::instance()->openpgp()
1967 && !ident.pgpSigningKey().isEmpty();
1968 const bool canSMIMESign = Kleo::CryptoBackendFactory::instance()->smime()
1969 && !ident.smimeSigningKey().isEmpty();
1971 setEncryption( mLastEncryptActionState );
1972 setSigning( ( canOpenPGPSign || canSMIMESign ) && mLastSignActionState );
1974 slotUpdateSignatureAndEncrypionStateIndicators();
1978 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
1979 !ident.pgpEncryptionKey().isEmpty() );
1981 TQString transport = newMsg->
headerField(
"X-KMail-Transport");
1982 const bool stickyTransport = mBtnTransport->isChecked() && !mIgnoreStickyFields;
1983 if (!stickyTransport && !transport.isEmpty())
1984 setTransport( transport );
1986 if (!mBtnFcc->isChecked())
1988 if (!mMsg->fcc().isEmpty())
1989 setFcc(mMsg->fcc());
1991 setFcc(ident.fcc());
1994 const bool stickyDictionary = mBtnDictionary->isChecked() && !mIgnoreStickyFields;
1995 if ( !stickyDictionary ) {
1996 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
1999 partNode * root = partNode::fromMessage( mMsg );
2001 KMail::ObjectTreeParser otp;
2002 otp.parseObjectTree( root );
2004 KMail::AttachmentCollector ac;
2005 ac.collectAttachmentsFrom( root );
2007 for ( std::vector<partNode*>::const_iterator it = ac.attachments().begin() ; it != ac.attachments().end() ; ++it )
2008 addAttach(
new KMMessagePart( (*it)->msgPart() ) );
2010 mEditor->setText( otp.textualContent() );
2011 mCharset = otp.textualContentCharset();
2012 if ( partNode * n = root->findType( DwMime::kTypeText, DwMime::kSubtypeHtml ) )
2013 if ( partNode * p = n->parentNode() )
2014 if ( p->hasType( DwMime::kTypeMultipart ) &&
2015 p->hasSubType( DwMime::kSubtypeAlternative ) )
2016 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" ) {
2017 toggleMarkup(
true );
2020 mCharset = n->msgPart().charset();
2021 TQCString bodyDecoded = n->msgPart().bodyDecoded();
2024 const TQTextCodec *codec = KMMsgBase::codecForName( mCharset );
2026 mEditor->setText( codec->toUnicode( bodyDecoded ) );
2028 mEditor->setText( TQString::fromLocal8Bit( bodyDecoded ) );
2032 if ( mCharset.isEmpty() )
2033 mCharset = mMsg->charset();
2034 if ( mCharset.isEmpty() )
2035 mCharset = mDefCharset;
2036 setCharset( mCharset );
2039 if ( mMsg->numBodyParts() == 0 && otp.textualContent().isEmpty() ) {
2040 mCharset=mMsg->charset();
2041 if ( mCharset.isEmpty() || mCharset ==
"default" )
2042 mCharset = mDefCharset;
2044 TQCString bodyDecoded = mMsg->bodyDecoded();
2046 if( allowDecryption )
2047 decryptOrStripOffCleartextSignature( bodyDecoded );
2049 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2051 mEditor->setText(codec->toUnicode(bodyDecoded));
2053 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2055 #ifdef BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
2056 const int num = mMsg->numBodyParts();
2057 kdDebug(5006) <<
"KMComposeWin::setMsg() mMsg->numBodyParts="
2058 << mMsg->numBodyParts() << endl;
2061 KMMessagePart bodyPart;
2062 int firstAttachment = 0;
2064 mMsg->bodyPart(1, &bodyPart);
2065 if ( bodyPart.typeStr().lower() ==
"text" &&
2066 bodyPart.subtypeStr().lower() ==
"html" ) {
2068 partNode *root = partNode::fromMessage( mMsg );
2069 partNode *node = root->findType( DwMime::kTypeText,
2070 DwMime::kSubtypeHtml );
2071 if ( node && node->parentNode() &&
2072 node->parentNode()->hasType( DwMime::kTypeMultipart ) &&
2073 node->parentNode()->hasSubType( DwMime::kSubtypeAlternative ) ) {
2075 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/html found" << endl;
2076 firstAttachment = 2;
2077 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" )
2078 toggleMarkup(
true );
2080 delete root; root = 0;
2082 if ( firstAttachment == 0 ) {
2083 mMsg->bodyPart(0, &bodyPart);
2084 if ( bodyPart.typeStr().lower() ==
"text" ) {
2086 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/* found" << endl;
2087 firstAttachment = 1;
2091 if ( firstAttachment != 0 )
2093 mCharset = bodyPart.charset();
2094 if ( mCharset.isEmpty() || mCharset ==
"default" )
2095 mCharset = mDefCharset;
2097 TQCString bodyDecoded = bodyPart.bodyDecoded();
2099 if( allowDecryption )
2100 decryptOrStripOffCleartextSignature( bodyDecoded );
2108 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2110 mEditor->setText(codec->toUnicode(bodyDecoded));
2112 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2114 }
else mEditor->setText(
"");
2115 for(
int i = firstAttachment; i < num; ++i )
2117 KMMessagePart *msgPart =
new KMMessagePart;
2118 mMsg->bodyPart(i, msgPart);
2119 TQCString mimeType = msgPart->typeStr().lower() +
'/'
2120 + msgPart->subtypeStr().lower();
2123 if( mimeType !=
"application/pgp-signature" ) {
2128 mCharset=mMsg->charset();
2129 if ( mCharset.isEmpty() || mCharset ==
"default" )
2130 mCharset = mDefCharset;
2132 TQCString bodyDecoded = mMsg->bodyDecoded();
2134 if( allowDecryption )
2135 decryptOrStripOffCleartextSignature( bodyDecoded );
2137 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2139 mEditor->setText(codec->toUnicode(bodyDecoded));
2141 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2144 setCharset(mCharset);
2145 #endif // BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
2147 if( (GlobalSettings::self()->autoTextSignature()==
"auto") && mayAutoSign ) {
2155 if ( GlobalSettings::self()->prependSignature() ) {
2156 TQTimer::singleShot( 0,
this, TQT_SLOT(slotPrependSignature()) );
2158 TQTimer::singleShot( 0,
this, TQT_SLOT(slotAppendSignature()) );
2162 if ( mMsg->getCursorPos() > 0 ) {
2165 mPreserveUserCursorPosition =
true;
2167 setModified( isModified );
2170 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
2173 mPreventFccOverwrite = ( !newMsg->
fcc().isEmpty() && ident.fcc() != newMsg->
fcc() );
2178 void KMComposeWin::setFcc(
const TQString &idString )
2181 if ( ! idString.isEmpty() && kmkernel->findFolderById( idString ) ) {
2182 mFcc->setFolder( idString );
2184 mFcc->setFolder( kmkernel->sentFolder() );
2190 bool KMComposeWin::isModified()
const
2192 return ( mEditor->isModified() ||
2193 mEdtFrom->edited() ||
2194 ( mEdtReplyTo && mEdtReplyTo->edited() ) ||
2195 ( mEdtTo && mEdtTo->edited() ) ||
2196 ( mEdtCc && mEdtCc->edited() ) ||
2197 ( mEdtBcc && mEdtBcc->edited() ) ||
2198 ( mRecipientsEditor && mRecipientsEditor->isModified() ) ||
2199 mEdtSubject->edited() ||
2201 ( mTransport->lineEdit() && mTransport->lineEdit()->edited() ) );
2206 void KMComposeWin::setModified(
bool modified )
2208 mEditor->setModified( modified );
2210 mEdtFrom->setEdited(
false );
2211 if ( mEdtReplyTo ) mEdtReplyTo->setEdited(
false );
2212 if ( mEdtTo ) mEdtTo->setEdited(
false );
2213 if ( mEdtCc ) mEdtCc->setEdited(
false );
2214 if ( mEdtBcc ) mEdtBcc->setEdited(
false );
2215 if ( mRecipientsEditor ) mRecipientsEditor->clearModified();
2216 mEdtSubject->setEdited(
false );
2217 mAtmModified = false ;
2218 if ( mTransport->lineEdit() )
2219 mTransport->lineEdit()->setEdited(
false );
2225 bool KMComposeWin::queryClose ()
2227 if ( !mEditor->checkExternalEditorFinished() )
2229 if ( kmkernel->shuttingDown() || kapp->sessionSaving() )
2231 if ( mComposer && mComposer->isPerformingSignOperation() )
2234 if ( isModified() ) {
2235 bool istemplate = ( mFolder!=0 && mFolder->isTemplates() );
2236 const TQString savebut = ( istemplate ?
2237 i18n(
"Re&save as Template") :
2238 i18n(
"&Save as Draft") );
2239 const TQString savetext = ( istemplate ?
2240 i18n(
"Resave this message in the Templates folder. "
2241 "It can then be used at a later time.") :
2242 i18n(
"Save this message in the Drafts folder. "
2243 "It can then be edited and sent at a later time.") );
2245 const int rc = KMessageBox::warningYesNoCancel(
this,
2246 i18n(
"Do you want to save the message for later or discard it?"),
2247 i18n(
"Close Composer"),
2248 KGuiItem(savebut,
"filesave", TQString(), savetext),
2249 KStdGuiItem::discard() );
2250 if ( rc == KMessageBox::Cancel )
2252 else if ( rc == KMessageBox::Yes ) {
2267 bool KMComposeWin::userForgotAttachment()
2269 bool checkForForgottenAttachments =
2270 mCheckForForgottenAttachments && GlobalSettings::self()->showForgottenAttachmentWarning();
2272 if ( !checkForForgottenAttachments || ( mAtmList.count() > 0 ) )
2276 TQStringList attachWordsList = GlobalSettings::self()->attachmentKeywords();
2278 if ( attachWordsList.isEmpty() ) {
2280 attachWordsList << TQString::fromLatin1(
"attachment")
2281 << TQString::fromLatin1(
"attached");
2282 if ( TQString::fromLatin1(
"attachment") != i18n(
"attachment") )
2283 attachWordsList << i18n(
"attachment");
2284 if ( TQString::fromLatin1(
"attached") != i18n(
"attached") )
2285 attachWordsList << i18n(
"attached");
2288 TQRegExp rx ( TQString::fromLatin1(
"\\b") +
2289 attachWordsList.join(
"\\b|\\b") +
2290 TQString::fromLatin1(
"\\b") );
2291 rx.setCaseSensitive(
false );
2293 bool gotMatch =
false;
2297 TQString subj = subject();
2298 gotMatch = ( KMMessage::stripOffPrefixes( subj ) == subj )
2299 && ( rx.search( subj ) >= 0 );
2304 TQRegExp quotationRx (
"^([ \\t]*([|>:}#]|[A-Za-z]+>))+");
2305 for (
int i = 0; i < mEditor->numLines(); ++i ) {
2306 TQString line = mEditor->textLine( i );
2307 gotMatch = ( quotationRx.search( line ) < 0 )
2308 && ( rx.search( line ) >= 0 );
2317 int rc = KMessageBox::warningYesNoCancel(
this,
2318 i18n(
"The message you have composed seems to refer to an "
2319 "attached file but you have not attached anything.\n"
2320 "Do you want to attach a file to your message?"),
2321 i18n(
"File Attachment Reminder"),
2322 i18n(
"&Attach File..."),
2323 i18n(
"&Send as Is") );
2324 if ( rc == KMessageBox::Cancel )
2326 if ( rc == KMessageBox::Yes ) {
2335 void KMComposeWin::applyChanges(
bool dontSignNorEncrypt,
bool dontDisable )
2337 kdDebug(5006) <<
"entering KMComposeWin::applyChanges" << endl;
2339 if(!mMsg || mComposer) {
2340 kdDebug(5006) <<
"KMComposeWin::applyChanges() : mMsg == 0!\n" << endl;
2341 emit applyChangesDone(
false );
2346 mComposer =
new MessageComposer(
this );
2347 connect( mComposer, TQT_SIGNAL( done(
bool ) ),
2348 TQT_TQOBJECT(
this), TQT_SLOT( slotComposerDone(
bool ) ) );
2353 if ( !dontDisable ) setEnabled(
false );
2355 mComposer->setDisableBreaking( mDisableBreaking );
2356 mComposer->applyChanges( dontSignNorEncrypt );
2359 void KMComposeWin::slotComposerDone(
bool rc )
2361 deleteAll( mComposedMessages );
2362 mComposedMessages = mComposer->composedMessageList();
2363 emit applyChangesDone( rc );
2371 const KPIM::Identity & KMComposeWin::identity()
const {
2372 return kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
2375 uint KMComposeWin::identityUid()
const {
2376 return mIdentity->currentIdentity();
2379 Kleo::CryptoMessageFormat KMComposeWin::cryptoMessageFormat()
const {
2380 if ( !mCryptoModuleAction )
2381 return Kleo::AutoFormat;
2382 return cb2format( mCryptoModuleAction->currentItem() );
2385 bool KMComposeWin::encryptToSelf()
const {
2387 KConfigGroup group( KMKernel::config(),
"Composer" );
2388 return group.readBoolEntry(
"crypto-encrypt-to-self",
true );
2391 bool KMComposeWin::queryExit ()
2397 bool KMComposeWin::addAttach(
const KURL aUrl)
2399 if ( !aUrl.isValid() ) {
2400 KMessageBox::sorry(
this, i18n(
"<qt><p>KMail could not recognize the location of the attachment (%1);</p>"
2401 "<p>you have to specify the full path if you wish to attach a file.</p></qt>" )
2402 .arg( aUrl.prettyURL() ) );
2406 const int maxAttachmentSize = GlobalSettings::maximumAttachmentSize();
2407 const uint maximumAttachmentSizeInByte = maxAttachmentSize*1024*1024;
2408 if ( aUrl.isLocalFile() && TQFileInfo( aUrl.pathOrURL() ).size() > maximumAttachmentSizeInByte ) {
2409 KMessageBox::sorry(
this, i18n(
"<qt><p>Your administrator has disallowed attaching files bigger than %1 MB.</p>" ).arg( maxAttachmentSize ) );
2413 KIO::TransferJob *job = KIO::get(aUrl);
2414 KIO::Scheduler::scheduleJob( job );
2417 ld.data = TQByteArray();
2419 if( !aUrl.fileEncoding().isEmpty() )
2420 ld.encoding = aUrl.fileEncoding().latin1();
2422 mMapAtmLoadData.insert(job, ld);
2423 mAttachJobs[job] = aUrl;
2424 connect(job, TQT_SIGNAL(result(KIO::Job *)),
2425 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileResult(KIO::Job *)));
2426 connect(job, TQT_SIGNAL(data(KIO::Job *,
const TQByteArray &)),
2427 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileData(KIO::Job *,
const TQByteArray &)));
2433 void KMComposeWin::addAttach(
const KMMessagePart* msgPart)
2435 mAtmList.append(msgPart);
2438 if (mAtmList.count()==1)
2440 mAtmListView->resize(mAtmListView->width(), 50);
2441 mAtmListView->show();
2446 KMAtmListViewItem *lvi =
new KMAtmListViewItem( mAtmListView );
2447 msgPartToItem(msgPart, lvi);
2448 mAtmItemList.append(lvi);
2451 if ( mTempDir != 0 ) {
2456 connect( lvi, TQT_SIGNAL( compress(
int ) ),
2457 TQT_TQOBJECT(
this), TQT_SLOT( compressAttach(
int ) ) );
2458 connect( lvi, TQT_SIGNAL( uncompress(
int ) ),
2459 TQT_TQOBJECT(
this), TQT_SLOT( uncompressAttach(
int ) ) );
2461 slotUpdateAttachActions();
2466 void KMComposeWin::slotUpdateAttachActions()
2468 int selectedCount = 0;
2469 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
2470 if ( (*it)->isSelected() ) {
2475 mAttachRemoveAction->setEnabled( selectedCount >= 1 );
2476 mAttachSaveAction->setEnabled( selectedCount == 1 );
2477 mAttachPropertiesAction->setEnabled( selectedCount == 1 );
2483 TQString KMComposeWin::prettyMimeType(
const TQString& type )
2485 TQString t = type.lower();
2486 KServiceType::Ptr st = KServiceType::serviceType( t );
2487 return st ? st->comment() : t;
2490 void KMComposeWin::msgPartToItem(
const KMMessagePart* msgPart,
2491 KMAtmListViewItem *lvi,
bool loadDefaults)
2493 assert(msgPart != 0);
2495 if (!msgPart->fileName().isEmpty())
2496 lvi->setText(0, msgPart->fileName());
2498 lvi->setText(0, msgPart->name());
2499 lvi->setText(1, KIO::convertSize( msgPart->decodedSize()));
2500 lvi->setText(2, msgPart->contentTransferEncodingStr());
2501 lvi->setText(3, prettyMimeType(msgPart->typeStr() +
"/" + msgPart->subtypeStr()));
2502 lvi->setAttachmentSize(msgPart->decodedSize());
2504 if ( loadDefaults ) {
2505 if( canSignEncryptAttachments() ) {
2506 lvi->enableCryptoCBs(
true );
2507 lvi->setEncrypt( mEncryptAction->isChecked() );
2508 lvi->setSign( mSignAction->isChecked() );
2510 lvi->enableCryptoCBs(
false );
2517 void KMComposeWin::removeAttach(
const TQString &aUrl)
2520 KMMessagePart* msgPart;
2521 for(idx=0,msgPart=mAtmList.first(); msgPart;
2522 msgPart=mAtmList.next(),idx++) {
2523 if (msgPart->name() == aUrl) {
2532 void KMComposeWin::removeAttach(
int idx)
2534 mAtmModified =
true;
2536 KMAtmListViewItem *item =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( idx ) );
2537 if ( item->itemBelow() )
2538 mAtmSelectNew = item->itemBelow();
2539 else if ( item->itemAbove() )
2540 mAtmSelectNew = item->itemAbove();
2542 mAtmList.remove(idx);
2543 delete mAtmItemList.take(idx);
2545 if( mAtmList.isEmpty() )
2547 mAtmListView->hide();
2548 mAtmListView->setMinimumSize(0, 0);
2555 bool KMComposeWin::encryptFlagOfAttachment(
int idx)
2557 return (
int)(mAtmItemList.count()) > idx
2558 ? static_cast<KMAtmListViewItem*>( mAtmItemList.at( idx ) )->isEncrypt()
2564 bool KMComposeWin::signFlagOfAttachment(
int idx)
2566 return (
int)(mAtmItemList.count()) > idx
2567 ? ((KMAtmListViewItem*)(mAtmItemList.at( idx )))->isSign()
2573 void KMComposeWin::addrBookSelInto()
2575 if ( mClassicalRecipients ) {
2576 if ( GlobalSettings::self()->addresseeSelectorType() ==
2577 GlobalSettings::EnumAddresseeSelectorType::New ) {
2578 addrBookSelIntoNew();
2580 addrBookSelIntoOld();
2583 kdWarning() <<
"To be implemented: call recipients picker." << endl;
2587 void KMComposeWin::addrBookSelIntoOld()
2589 AddressesDialog dlg(
this );
2594 if ( !txt.isEmpty() ) {
2595 lst = KPIM::splitEmailAddrList( txt );
2596 dlg.setSelectedTo( lst );
2599 txt = mEdtCc->text();
2600 if ( !txt.isEmpty() ) {
2601 lst = KPIM::splitEmailAddrList( txt );
2602 dlg.setSelectedCC( lst );
2605 txt = mEdtBcc->text();
2606 if ( !txt.isEmpty() ) {
2607 lst = KPIM::splitEmailAddrList( txt );
2608 dlg.setSelectedBCC( lst );
2611 dlg.setRecentAddresses( RecentAddresses::self( KMKernel::config() )->kabcAddresses() );
2613 if (dlg.exec()==TQDialog::Rejected)
return;
2615 mEdtTo->setText( dlg.to().join(
", ") );
2616 mEdtTo->setEdited(
true );
2618 mEdtCc->setText( dlg.cc().join(
", ") );
2619 mEdtCc->setEdited(
true );
2621 mEdtBcc->setText( dlg.bcc().join(
", ") );
2622 mEdtBcc->setEdited(
true );
2625 if ( !mEdtBcc->text().isEmpty() ) {
2626 mShowHeaders |= HDR_BCC;
2627 rethinkFields(
false );
2631 void KMComposeWin::addrBookSelIntoNew()
2633 AddresseeEmailSelection selection;
2635 AddresseeSelectorDialog dlg( &selection );
2641 if ( !txt.isEmpty() ) {
2642 lst = KPIM::splitEmailAddrList( txt );
2643 selection.setSelectedTo( lst );
2646 txt = mEdtCc->text();
2647 if ( !txt.isEmpty() ) {
2648 lst = KPIM::splitEmailAddrList( txt );
2649 selection.setSelectedCC( lst );
2652 txt = mEdtBcc->text();
2653 if ( !txt.isEmpty() ) {
2654 lst = KPIM::splitEmailAddrList( txt );
2655 selection.setSelectedBCC( lst );
2658 if (dlg.exec()==TQDialog::Rejected)
return;
2660 TQStringList list = selection.to() + selection.toDistributionLists();
2661 mEdtTo->setText( list.join(
", ") );
2662 mEdtTo->setEdited(
true );
2664 list = selection.cc() + selection.ccDistributionLists();
2665 mEdtCc->setText( list.join(
", ") );
2666 mEdtCc->setEdited(
true );
2668 list = selection.bcc() + selection.bccDistributionLists();
2669 mEdtBcc->setText( list.join(
", ") );
2670 mEdtBcc->setEdited(
true );
2673 if ( !mEdtBcc->text().isEmpty() ) {
2674 mShowHeaders |= HDR_BCC;
2675 rethinkFields(
false );
2681 void KMComposeWin::setCharset(
const TQCString& aCharset,
bool forceDefault)
2683 if ((forceDefault && GlobalSettings::self()->forceReplyCharset()) || aCharset.isEmpty())
2684 mCharset = mDefCharset;
2686 mCharset = aCharset.lower();
2688 if ( mCharset.isEmpty() || mCharset ==
"default" )
2689 mCharset = mDefCharset;
2693 mEncodingAction->setCurrentItem( 0 );
2697 TQStringList encodings = mEncodingAction->items();
2699 bool charsetFound =
false;
2700 for ( TQStringList::Iterator it = encodings.begin(); it != encodings.end();
2703 if (i > 0 && ((mCharset ==
"us-ascii" && i == 1) ||
2704 (i != 1 && KGlobal::charsets()->codecForName(
2705 KGlobal::charsets()->encodingForName(*it))
2706 == KGlobal::charsets()->codecForName(mCharset))))
2708 mEncodingAction->setCurrentItem( i );
2710 charsetFound =
true;
2714 if (!aCharset.isEmpty() && !charsetFound) setCharset(
"",
true);
2719 void KMComposeWin::slotAddrBook()
2721 KAddrBookExternal::openAddressBook(
this);
2726 void KMComposeWin::slotAddrBookFrom()
2733 void KMComposeWin::slotAddrBookReplyTo()
2740 void KMComposeWin::slotAddrBookTo()
2746 void KMComposeWin::slotAttachFile()
2754 KURL recentURL = KFileDialog::getStartURL( TQString(), recent );
2755 if ( !recentURL.url().isEmpty() &&
2756 !KIO::NetAccess::exists( recentURL,
true,
this ) ) {
2757 recentURL = KURL( TQDir::homeDirPath() );
2760 KFileDialog fdlg( recentURL.url(), TQString(),
this, 0, true );
2761 fdlg.setOperationMode( KFileDialog::Other );
2762 fdlg.setCaption( i18n(
"Attach File" ) );
2763 fdlg.okButton()->setGuiItem( KGuiItem( i18n(
"&Attach" ),
"fileopen" ) );
2764 fdlg.setMode( KFile::Files );
2766 KURL::List files = fdlg.selectedURLs();
2768 for (KURL::List::Iterator it = files.begin(); it != files.end(); ++it)
2774 void KMComposeWin::slotAttachFileData(KIO::Job *job,
const TQByteArray &data)
2776 TQMap<KIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2777 assert(it != mMapAtmLoadData.end());
2778 TQBuffer buff((*it).data);
2779 buff.open(IO_WriteOnly | IO_Append);
2780 buff.writeBlock(data.data(), data.size());
2786 void KMComposeWin::slotAttachFileResult(KIO::Job *job)
2788 TQMap<KIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2789 assert(it != mMapAtmLoadData.end());
2791 TQMap<KIO::Job*, KURL>::iterator jit = mAttachJobs.find(job);
2792 bool attachURLfound = (jit != mAttachJobs.end());
2795 attachURL = jit.data();
2796 mAttachJobs.remove(jit);
2800 mMapAtmLoadData.remove(it);
2801 job->showErrorDialog();
2803 emit attachmentAdded(attachURL,
false);
2808 (*it).data.resize((*it).data.size() + 1);
2809 (*it).data[(*it).data.size() - 1] =
'\0';
2810 if (
const TQTextCodec * codec = KGlobal::charsets()->codecForName((*it).encoding) )
2811 mEditor->insert( codec->toUnicode( (*it).data ) );
2813 mEditor->insert( TQString::fromLocal8Bit( (*it).data ) );
2814 mMapAtmLoadData.remove(it);
2816 emit attachmentAdded(attachURL,
true);
2819 TQCString partCharset;
2820 if ( !( *it ).url.fileEncoding().isEmpty() ) {
2821 partCharset = TQCString( ( *it ).url.fileEncoding().latin1() );
2824 KLocale *loc = KGlobal::locale();
2825 ed.setAutoDetectLanguage( EncodingDetector::scriptForLanguageCode ( loc->language() ) );
2828 if ( partCharset.isEmpty() )
2829 partCharset = mCharset;
2832 KMMessagePart* msgPart;
2835 TQString name( (*it).url.fileName() );
2837 TQString mimeType =
static_cast<KIO::MimetypeJob*
>(job)->mimetype();
2839 if ( name.isEmpty() ) {
2842 if( mimeType ==
"text/html" )
2843 name =
"index.html";
2846 TQStringList patterns( KMimeType::mimeType( mimeType )->patterns() );
2848 if( !patterns.isEmpty() ) {
2850 int i = ext.findRev(
'.' );
2856 name = TQString(
"unknown") += ext;
2860 name.truncate( 256 );
2862 TQCString encoding = KMMsgBase::autoDetectCharset(partCharset,
2864 if ( encoding.isEmpty() )
2868 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
2869 encName = KMMsgBase::encodeRFC2047String( name, encoding );
2871 encName = KMMsgBase::encodeRFC2231String( name, encoding );
2872 bool RFC2231encoded =
false;
2873 if ( !GlobalSettings::self()->outlookCompatibleAttachments() )
2874 RFC2231encoded = name != TQString( encName );
2877 msgPart =
new KMMessagePart;
2878 msgPart->setName(name);
2879 TQValueList<int> allowedCTEs;
2880 if ( mimeType ==
"message/rfc822" ) {
2881 msgPart->setMessageBody( (*it).data );
2882 allowedCTEs << DwMime::kCte7bit;
2883 allowedCTEs << DwMime::kCte8bit;
2885 msgPart->setBodyAndGuessCte((*it).data, allowedCTEs,
2886 !kmkernel->msgSender()->sendQuotedPrintable());
2887 kdDebug(5006) <<
"autodetected cte: " << msgPart->cteStr() << endl;
2889 int slash = mimeType.find(
'/' );
2891 slash = mimeType.length();
2892 msgPart->setTypeStr( mimeType.left( slash ).latin1() );
2893 msgPart->setSubtypeStr( mimeType.mid( slash + 1 ).latin1() );
2894 msgPart->setContentDisposition(TQCString(
"attachment;\n\tfilename")
2895 + ( RFC2231encoded ?
"*=" + encName :
"=\"" + encName +
'"' ) );
2897 mMapAtmLoadData.remove(it);
2899 if ( msgPart->typeStr().lower() ==
"text" ) {
2900 msgPart->setCharset(partCharset);
2904 KConfigGroup composer(KMKernel::config(),
"Composer");
2905 if ( GlobalSettings::self()->showMessagePartDialogOnAttach() ) {
2909 for ( TQValueListConstIterator<int> it = allowedCTEs.begin() ;
2910 it != allowedCTEs.end() ; ++it )
2912 case DwMime::kCteBase64: encodings |= KMMsgPartDialog::Base64;
break;
2913 case DwMime::kCteQp: encodings |= KMMsgPartDialog::QuotedPrintable;
break;
2914 case DwMime::kCte7bit: encodings |= KMMsgPartDialog::SevenBit;
break;
2915 case DwMime::kCte8bit: encodings |= KMMsgPartDialog::EightBit;
break;
2918 dlg.setShownEncodings( encodings );
2919 dlg.setMsgPart(msgPart);
2924 emit attachmentAdded(attachURL,
false);
2928 mAtmModified =
true;
2934 emit attachmentAdded(attachURL,
true);
2939 void KMComposeWin::slotInsertFile()
2941 KFileDialog fdlg(TQString(), TQString(),
this, 0,
true);
2942 fdlg.setOperationMode( KFileDialog::Opening );
2943 fdlg.okButton()->setText(i18n(
"&Insert"));
2944 fdlg.setCaption(i18n(
"Insert File"));
2945 fdlg.toolBar()->insertCombo(KMMsgBase::supportedEncodings(
false), 4711,
2947 KComboBox *combo = fdlg.toolBar()->getCombo(4711);
2948 for (
int i = 0; i < combo->count(); i++)
2949 if (KGlobal::charsets()->codecForName(KGlobal::charsets()->
2950 encodingForName(combo->text(i)))
2951 == TQTextCodec::codecForLocale()) combo->setCurrentItem(i);
2952 if (!fdlg.exec())
return;
2954 KURL u = fdlg.selectedURL();
2955 mRecentAction->addURL(u);
2958 KConfig *config = KMKernel::config();
2959 KConfigGroupSaver saver( config,
"Composer" );
2960 TQString encoding = KGlobal::charsets()->encodingForName(combo->currentText()).latin1();
2961 TQStringList urls = config->readListEntry(
"recent-urls" );
2962 TQStringList encodings = config->readListEntry(
"recent-encodings" );
2965 uint mMaxRecentFiles = 30;
2966 while (urls.count() > mMaxRecentFiles)
2967 urls.erase( urls.fromLast() );
2968 while (encodings.count() > mMaxRecentFiles)
2969 encodings.erase( encodings.fromLast() );
2971 if (urls.count() != encodings.count()) {
2975 urls.prepend( u.prettyURL() );
2976 encodings.prepend( encoding );
2977 config->writeEntry(
"recent-urls", urls );
2978 config->writeEntry(
"recent-encodings", encodings );
2979 mRecentAction->saveEntries( config );
2981 slotInsertRecentFile(u);
2986 void KMComposeWin::slotInsertRecentFile(
const KURL& u)
2988 if (u.fileName().isEmpty())
return;
2990 KIO::Job *job = KIO::get(u);
2993 ld.data = TQByteArray();
2997 KConfig *config = KMKernel::config();
2998 KConfigGroupSaver saver( config,
"Composer" );
2999 TQStringList urls = config->readListEntry(
"recent-urls" );
3000 TQStringList encodings = config->readListEntry(
"recent-encodings" );
3001 int index = urls.findIndex( u.prettyURL() );
3003 TQString encoding = encodings[ index ];
3004 ld.encoding = encoding.latin1();
3007 mMapAtmLoadData.insert(job, ld);
3008 connect(job, TQT_SIGNAL(result(KIO::Job *)),
3009 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileResult(KIO::Job *)));
3010 connect(job, TQT_SIGNAL(data(KIO::Job *,
const TQByteArray &)),
3011 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileData(KIO::Job *,
const TQByteArray &)));
3016 void KMComposeWin::slotSetCharset()
3018 if (mEncodingAction->currentItem() == 0)
3020 mAutoCharset =
true;
3023 mAutoCharset =
false;
3025 mCharset = KGlobal::charsets()->encodingForName( mEncodingAction->
3026 currentText() ).latin1();
3031 void KMComposeWin::slotSelectCryptoModule(
bool init )
3034 setModified(
true );
3036 if( canSignEncryptAttachments() ) {
3038 if( 0 == mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3041 if( !mAtmList.isEmpty() ) {
3042 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3044 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3045 lvi->setSign( mSignAction->isChecked() );
3046 lvi->setEncrypt( mEncryptAction->isChecked() );
3051 for(
int col=0; col < mAtmColEncrypt; col++ )
3052 totalWidth += mAtmListView->columnWidth( col );
3053 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3058 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3059 int newWidth = mAtmListView->columnWidth( col ) * reducedTotalWidth
3061 mAtmListView->setColumnWidth( col, newWidth );
3062 usedWidth += newWidth;
3067 mAtmListView->setColumnWidth( mAtmColEncrypt-1,
3068 reducedTotalWidth - usedWidth );
3069 mAtmListView->setColumnWidth( mAtmColEncrypt, mAtmEncryptColWidth );
3070 mAtmListView->setColumnWidth( mAtmColSign, mAtmSignColWidth );
3071 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3073 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3074 lvi->enableCryptoCBs(
true );
3079 if( 0 != mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3080 mAtmEncryptColWidth = mAtmListView->columnWidth( mAtmColEncrypt );
3081 mAtmSignColWidth = mAtmListView->columnWidth( mAtmColSign );
3084 for(
int col=0; col < mAtmListView->columns(); col++ )
3085 totalWidth += mAtmListView->columnWidth( col );
3086 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3091 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3092 int newWidth = mAtmListView->columnWidth( col ) * totalWidth
3093 / reducedTotalWidth;
3094 mAtmListView->setColumnWidth( col, newWidth );
3095 usedWidth += newWidth;
3100 mAtmListView->setColumnWidth( mAtmColEncrypt-1, totalWidth - usedWidth );
3101 mAtmListView->setColumnWidth( mAtmColEncrypt, 0 );
3102 mAtmListView->setColumnWidth( mAtmColSign, 0 );
3103 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3105 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3106 lvi->enableCryptoCBs(
false );
3112 static void showExportError( TQWidget * w,
const GpgME::Error & err ) {
3114 const TQString msg = i18n(
"<qt><p>An error occurred while trying to export "
3115 "the key from the backend:</p>"
3116 "<p><b>%1</b></p></qt>")
3117 .arg( TQString::fromLocal8Bit( err.asString() ) );
3118 KMessageBox::error( w, msg, i18n(
"Key Export Failed") );
3123 void KMComposeWin::slotInsertMyPublicKey()
3127 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() ).pgpEncryptionKey();
3128 if ( !mFingerprint.isEmpty() )
3129 startPublicKeyExport();
3132 void KMComposeWin::startPublicKeyExport() {
3133 if ( mFingerprint.isEmpty() || !Kleo::CryptoBackendFactory::instance()->openpgp() )
3135 Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->openpgp()->publicKeyExportJob(
true );
3138 connect( job, TQT_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
3139 this, TQT_SLOT(slotPublicKeyExportResult(
const GpgME::Error&,
const TQByteArray&)) );
3141 const GpgME::Error err = job->start( mFingerprint );
3143 showExportError(
this, err );
3145 (
void)
new Kleo::ProgressDialog( job, i18n(
"Exporting key..."),
this );
3148 void KMComposeWin::slotPublicKeyExportResult(
const GpgME::Error & err,
const TQByteArray & keydata ) {
3150 showExportError(
this, err );
3155 KMMessagePart * msgPart =
new KMMessagePart();
3156 msgPart->setName( i18n(
"OpenPGP key 0x%1").arg( mFingerprint ) );
3157 msgPart->setTypeStr(
"application");
3158 msgPart->setSubtypeStr(
"pgp-keys");
3159 TQValueList<int> dummy;
3160 msgPart->setBodyAndGuessCte(keydata, dummy,
false);
3161 msgPart->setContentDisposition(
"attachment;\n\tfilename=0x" + TQCString( mFingerprint.latin1() ) +
".asc" );
3169 void KMComposeWin::slotInsertPublicKey()
3171 Kleo::KeySelectionDialog dlg( i18n(
"Attach Public OpenPGP Key"),
3172 i18n(
"Select the public key which should "
3174 std::vector<GpgME::Key>(),
3175 Kleo::KeySelectionDialog::PublicKeys|Kleo::KeySelectionDialog::OpenPGPKeys,
3178 this,
"attach public key selection dialog" );
3179 if ( dlg.exec() != TQDialog::Accepted )
3182 mFingerprint = dlg.fingerprint();
3183 startPublicKeyExport();
3188 void KMComposeWin::slotAttachPopupMenu(TQListViewItem *,
const TQPoint &,
int)
3192 mAttachMenu =
new TQPopupMenu(
this);
3194 mOpenId = mAttachMenu->insertItem(i18n(
"to open",
"Open"),
this,
3195 TQT_SLOT(slotAttachOpen()));
3196 mOpenWithId = mAttachMenu->insertItem(i18n(
"Open With..."),
this,
3197 TQT_SLOT(slotAttachOpenWith()));
3198 mViewId = mAttachMenu->insertItem(i18n(
"to view",
"View"),
this,
3199 TQT_SLOT(slotAttachView()));
3200 mEditId = mAttachMenu->insertItem( i18n(
"Edit"),
this, TQT_SLOT(slotAttachEdit()) );
3201 mEditWithId = mAttachMenu->insertItem( i18n(
"Edit With..."),
this,
3202 TQT_SLOT(slotAttachEditWith()) );
3203 mRemoveId = mAttachMenu->insertItem(i18n(
"Remove"),
this, TQT_SLOT(slotAttachRemove()));
3204 mSaveAsId = mAttachMenu->insertItem( SmallIconSet(
"filesaveas"), i18n(
"Save As..."),
this,
3205 TQT_SLOT( slotAttachSave() ) );
3206 mPropertiesId = mAttachMenu->insertItem( i18n(
"Properties"),
this,
3207 TQT_SLOT( slotAttachProperties() ) );
3208 mAttachMenu->insertSeparator();
3209 mAttachMenu->insertItem(i18n(
"Add Attachment..."),
this, TQT_SLOT(slotAttachFile()));
3212 int selectedCount = 0;
3213 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
3214 if ( (*it)->isSelected() ) {
3219 mAttachMenu->setItemEnabled( mOpenId, selectedCount > 0 );
3220 mAttachMenu->setItemEnabled( mOpenWithId, selectedCount > 0 );
3221 mAttachMenu->setItemEnabled( mViewId, selectedCount > 0 );
3222 mAttachMenu->setItemEnabled( mEditId, selectedCount == 1 );
3223 mAttachMenu->setItemEnabled( mEditWithId, selectedCount == 1 );
3224 mAttachMenu->setItemEnabled( mRemoveId, selectedCount > 0 );
3225 mAttachMenu->setItemEnabled( mSaveAsId, selectedCount == 1 );
3226 mAttachMenu->setItemEnabled( mPropertiesId, selectedCount == 1 );
3228 mAttachMenu->popup(TQCursor::pos());
3232 int KMComposeWin::currentAttachmentNum()
3235 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i )
3236 if ( *it == mAtmListView->currentItem() )
3242 void KMComposeWin::slotAttachProperties()
3244 int idx = currentAttachmentNum();
3246 if (idx < 0)
return;
3248 KMMessagePart* msgPart = mAtmList.at(idx);
3251 dlg.setMsgPart(msgPart);
3252 KMAtmListViewItem* listItem = (KMAtmListViewItem*)(mAtmItemList.at(idx));
3253 if( canSignEncryptAttachments() && listItem ) {
3254 dlg.setCanSign(
true );
3255 dlg.setCanEncrypt(
true );
3256 dlg.setSigned( listItem->isSign() );
3257 dlg.setEncrypted( listItem->isEncrypt() );
3259 dlg.setCanSign(
false );
3260 dlg.setCanEncrypt(
false );
3264 mAtmModified =
true;
3267 msgPartToItem(msgPart, listItem);
3268 if( canSignEncryptAttachments() ) {
3269 listItem->setSign( dlg.isSigned() );
3270 listItem->setEncrypt( dlg.isEncrypted() );
3274 if (msgPart->typeStr().lower() !=
"text") msgPart->setCharset(TQCString());
3278 void KMComposeWin::compressAttach(
int idx )
3280 if (idx < 0)
return;
3283 for ( i = 0; i < mAtmItemList.count(); ++i )
3284 if ( mAtmItemList.at( i )->itemPos() == idx )
3287 if ( i > mAtmItemList.count() )
3290 KMMessagePart* msgPart;
3291 msgPart = mAtmList.at( i );
3293 TQBuffer dev( array );
3294 KZip zip( &TQT_TQIODEVICE_OBJECT(dev) );
3295 TQByteArray decoded = msgPart->bodyDecodedBinary();
3296 if ( ! zip.open( IO_WriteOnly ) ) {
3297 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3298 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3302 zip.setCompression( KZip::DeflateCompression );
3303 if ( ! zip.writeFile( msgPart->name(),
"",
"", decoded.size(),
3304 decoded.data() ) ) {
3305 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3306 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3310 if ( array.size() >= decoded.size() ) {
3311 if ( KMessageBox::questionYesNo(
this, i18n(
"The compressed file is larger "
3312 "than the original. Do you want to keep the original one?" ), TQString(), i18n(
"Keep"), i18n(
"Compress") )
3313 == KMessageBox::Yes ) {
3314 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3318 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedCodec(
3319 msgPart->cteStr() );
3321 msgPart->setCteStr(
"base64" );
3322 msgPart->setBodyEncodedBinary( array );
3323 TQString name = msgPart->name() +
".zip";
3325 msgPart->setName( name );
3327 TQCString cDisp =
"attachment;";
3328 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3330 kdDebug(5006) <<
"encoding: " << encoding << endl;
3331 if ( encoding.isEmpty() ) encoding =
"utf-8";
3332 kdDebug(5006) <<
"encoding after: " << encoding << endl;
3334 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3335 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3337 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3339 cDisp +=
"\n\tfilename";
3340 if ( name != TQString( encName ) )
3341 cDisp +=
"*=" + encName;
3343 cDisp +=
"=\"" + encName +
'"';
3344 msgPart->setContentDisposition( cDisp );
3346 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedMimeType(
3347 msgPart->typeStr(), msgPart->subtypeStr() );
3348 msgPart->setTypeStr(
"application" );
3349 msgPart->setSubtypeStr(
"x-zip" );
3351 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) );
3352 msgPartToItem( msgPart, listItem,
false );
3357 void KMComposeWin::uncompressAttach(
int idx )
3359 if (idx < 0)
return;
3362 for ( i = 0; i < mAtmItemList.count(); ++i )
3363 if ( mAtmItemList.at( i )->itemPos() == idx )
3366 if ( i > mAtmItemList.count() )
3369 KMMessagePart* msgPart;
3370 msgPart = mAtmList.at( i );
3372 TQBuffer dev( msgPart->bodyDecodedBinary() );
3373 KZip zip( &TQT_TQIODEVICE_OBJECT(dev) );
3374 TQByteArray decoded;
3376 decoded = msgPart->bodyDecodedBinary();
3377 if ( ! zip.open( IO_ReadOnly ) ) {
3378 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3379 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3382 const KArchiveDirectory *dir = zip.directory();
3384 KZipFileEntry *entry;
3385 if ( dir->entries().count() != 1 ) {
3386 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3387 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3390 entry = (KZipFileEntry*)dir->entry( dir->entries()[0] );
3393 static_cast<KMAtmListViewItem*>( mAtmItemList.at(i) )->uncompressedCodec() );
3395 msgPart->setBodyEncodedBinary( entry->data() );
3396 TQString name = entry->name();
3397 msgPart->setName( name );
3401 TQCString cDisp =
"attachment;";
3402 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3404 if ( encoding.isEmpty() ) encoding =
"utf-8";
3407 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3408 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3410 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3412 cDisp +=
"\n\tfilename";
3413 if ( name != TQString( encName ) )
3414 cDisp +=
"*=" + encName;
3416 cDisp +=
"=\"" + encName +
'"';
3417 msgPart->setContentDisposition( cDisp );
3419 TQCString type, subtype;
3420 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->uncompressedMimeType( type,
3423 msgPart->setTypeStr( type );
3424 msgPart->setSubtypeStr( subtype );
3426 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>(mAtmItemList.at( i ));
3427 msgPartToItem( msgPart, listItem,
false );
3432 void KMComposeWin::slotAttachView()
3435 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3436 if ( (*it)->isSelected() ) {
3442 void KMComposeWin::slotAttachOpen()
3445 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3446 if ( (*it)->isSelected() ) {
3447 openAttach( i,
false );
3453 void KMComposeWin::slotAttachOpenWith()
3456 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3457 if ( (*it)->isSelected() ) {
3458 openAttach( i,
true );
3463 void KMComposeWin::slotAttachEdit()
3466 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3467 if ( (*it)->isSelected() ) {
3468 editAttach( i,
false );
3473 void KMComposeWin::slotAttachEditWith()
3476 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3477 if ( (*it)->isSelected() ) {
3478 editAttach( i,
true );
3484 bool KMComposeWin::inlineSigningEncryptionSelected() {
3485 if ( !mSignAction->isChecked() && !mEncryptAction->isChecked() )
3487 return cryptoMessageFormat() == Kleo::InlineOpenPGPFormat;
3491 void KMComposeWin::viewAttach(
int index )
3494 KMMessagePart* msgPart;
3495 msgPart = mAtmList.at(index);
3496 pname = msgPart->name().stripWhiteSpace();
3497 if (pname.isEmpty()) pname=msgPart->contentDescription();
3498 if (pname.isEmpty()) pname=
"unnamed";
3500 KTempFile* atmTempFile =
new KTempFile();
3501 mAtmTempList.append( atmTempFile );
3502 atmTempFile->setAutoDelete(
true );
3503 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3505 KMReaderMainWin *win =
new KMReaderMainWin(msgPart,
false,
3506 atmTempFile->name(), pname, mCharset );
3511 void KMComposeWin::openAttach(
int index,
bool with )
3513 KMMessagePart* msgPart = mAtmList.at(index);
3514 const TQString contentTypeStr =
3515 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3517 KMimeType::Ptr mimetype;
3518 mimetype = KMimeType::mimeType( contentTypeStr );
3520 KTempFile* atmTempFile =
new KTempFile();
3521 mAtmTempList.append( atmTempFile );
3522 const bool autoDelete =
true;
3523 atmTempFile->setAutoDelete( autoDelete );
3526 url.setPath( atmTempFile->name() );
3528 KPIM::kByteArrayToFile( msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3530 if ( ::chmod( TQFile::encodeName( atmTempFile->name() ), S_IRUSR ) != 0) {
3531 TQFile::remove(url.path());
3535 KService::Ptr offer =
3536 KServiceTypeProfile::preferredService( mimetype->name(),
"Application" );
3538 if ( with || !offer || mimetype->name() ==
"application/octet-stream" ) {
3539 if ( ( !KRun::displayOpenWithDialog( url, autoDelete ) ) && autoDelete ) {
3540 TQFile::remove(url.path());
3544 if ( ( !KRun::run( *offer, url, autoDelete ) ) && autoDelete ) {
3545 TQFile::remove( url.path() );
3550 void KMComposeWin::editAttach(
int index,
bool openWith)
3552 KMMessagePart* msgPart = mAtmList.at(index);
3553 const TQString contentTypeStr =
3554 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3556 KTempFile* atmTempFile =
new KTempFile();
3557 mAtmTempList.append( atmTempFile );
3558 atmTempFile->setAutoDelete(
true );
3559 atmTempFile->file()->writeBlock( msgPart->bodyDecodedBinary() );
3560 atmTempFile->file()->flush();
3565 TQT_TQOBJECT(
this), this );
3567 if ( watcher->start() ) {
3568 mEditorMap.insert( watcher, msgPart );
3569 mEditorTempFiles.insert( watcher, atmTempFile );
3574 void KMComposeWin::slotAttachSave()
3576 KMMessagePart* msgPart;
3577 TQString fileName, pname;
3578 int idx = currentAttachmentNum();
3580 if (idx < 0)
return;
3582 msgPart = mAtmList.at(idx);
3583 pname = msgPart->name();
3584 if (pname.isEmpty()) pname=
"unnamed";
3586 KURL url = KFileDialog::getSaveURL(pname, TQString(), 0, i18n(
"Save Attachment As"));
3591 kmkernel->byteArrayToRemoteFile(msgPart->bodyDecodedBinary(), url);
3596 void KMComposeWin::slotAttachRemove()
3599 bool attachmentRemoved =
false;
3601 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ) {
3602 if ( (*it)->isSelected() ) {
3604 attachmentRemoved =
true;
3612 if ( attachmentRemoved ) {
3613 setModified(
true );
3614 slotUpdateAttachActions();
3615 if ( mAtmSelectNew ) {
3616 mAtmListView->setSelected( mAtmSelectNew,
true );
3617 mAtmListView->setCurrentItem( mAtmSelectNew );
3623 void KMComposeWin::slotFind()
3628 void KMComposeWin::slotSearchAgain()
3630 mEditor->repeatSearch();
3634 void KMComposeWin::slotReplace()
3640 void KMComposeWin::slotUpdateFont()
3642 kdDebug() <<
"KMComposeWin::slotUpdateFont " << endl;
3643 if ( ! mFixedFontAction ) {
3646 mEditor->setFont( mFixedFontAction->isChecked() ? mFixedFont : mBodyFont );
3649 TQString KMComposeWin::quotePrefixName()
const
3654 int languageNr = GlobalSettings::self()->replyCurrentLanguage();
3655 ReplyPhrases replyPhrases( TQString::number(languageNr) );
3656 replyPhrases.readConfig();
3657 TQString quotePrefix = msg()->formatString(
3658 replyPhrases.indentPrefix() );
3660 quotePrefix = msg()->formatString(quotePrefix);
3664 void KMComposeWin::slotPasteClipboardAsQuotation()
3666 if( mEditor->hasFocus() && msg() )
3668 TQString s = TQApplication::clipboard()->text();
3670 mEditor->insert(addQuotesToText(s));
3674 void KMComposeWin::slotPasteClipboardAsAttachment()
3676 KURL url( TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3677 if ( url.isValid() ) {
3678 addAttach(TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3682 TQMimeSource *mimeSource = TQApplication::clipboard()->data();
3683 if ( TQImageDrag::canDecode(mimeSource) ) {
3684 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3688 TQString attName = KInputDialog::getText(
"KMail", i18n(
"Name of the attachment:"), TQString(), &ok,
this );
3691 KMMessagePart *msgPart =
new KMMessagePart;
3692 msgPart->setName(attName);
3693 TQValueList<int> dummy;
3694 msgPart->setBodyAndGuessCte(TQCString(TQApplication::clipboard()->text().latin1()), dummy,
3695 kmkernel->msgSender()->sendQuotedPrintable());
3700 void KMComposeWin::slotAddQuotes()
3702 if( mEditor->hasFocus() && msg() )
3708 if ( mEditor->hasMarkedText() ) {
3709 TQString s = mEditor->markedText();
3711 mEditor->insert(addQuotesToText(s));
3713 int l = mEditor->currentLine();
3714 int c = mEditor->currentColumn();
3715 TQString s = mEditor->textLine(l);
3716 s.prepend(quotePrefixName());
3717 mEditor->insertLine(s,l);
3718 mEditor->removeLine(l+1);
3719 mEditor->setCursorPosition(l,c+2);
3724 TQString KMComposeWin::addQuotesToText(
const TQString &inputText)
3726 TQString answer = TQString( inputText );
3727 TQString indentStr = quotePrefixName();
3728 answer.replace(
'\n',
'\n' + indentStr);
3729 answer.prepend( indentStr );
3734 TQString KMComposeWin::removeQuotesFromText(
const TQString &inputText)
3736 TQString s = inputText;
3739 TQString quotePrefix =
'^' + quotePrefixName();
3740 TQRegExp rx(quotePrefix);
3744 quotePrefix =
'\n' + quotePrefixName();
3746 s.replace(rx,
"\n");
3751 void KMComposeWin::slotRemoveQuotes()
3753 if( mEditor->hasFocus() && msg() )
3759 if ( mEditor->hasMarkedText() ) {
3760 TQString s = mEditor->markedText();
3761 mEditor->insert(removeQuotesFromText(s));
3763 int l = mEditor->currentLine();
3764 int c = mEditor->currentColumn();
3765 TQString s = mEditor->textLine(l);
3766 mEditor->insertLine(removeQuotesFromText(s),l);
3767 mEditor->removeLine(l+1);
3768 mEditor->setCursorPosition(l,c-2);
3774 void KMComposeWin::slotUndo()
3776 TQWidget* fw = focusWidget();
3779 if ( ::tqqt_cast<KEdit*>(fw) )
3780 static_cast<TQTextEdit*
>(fw)->undo();
3781 else if (::tqqt_cast<TQLineEdit*>(fw))
3782 static_cast<TQLineEdit*>(fw)->undo();
3785 void KMComposeWin::slotRedo()
3787 TQWidget* fw = focusWidget();
3790 if (::tqqt_cast<KEdit*>(fw))
3791 static_cast<KEdit*
>(fw)->redo();
3792 else if (::tqqt_cast<TQLineEdit*>(fw))
3793 static_cast<TQLineEdit*>(fw)->redo();
3797 void KMComposeWin::slotCut()
3799 TQWidget* fw = focusWidget();
3802 if (::tqqt_cast<KEdit*>(fw))
3803 static_cast<KEdit*
>(fw)->cut();
3804 else if (::tqqt_cast<TQLineEdit*>(fw))
3805 static_cast<TQLineEdit*>(fw)->cut();
3810 void KMComposeWin::slotCopy()
3812 TQWidget* fw = focusWidget();
3819 TQKeyEvent k(TQEvent::KeyPress, Key_C, 0, ControlButton);
3820 kapp->notify(TQT_TQOBJECT(fw), TQT_TQEVENT(&k));
3825 void KMComposeWin::slotPasteClipboard()
3827 paste( TQClipboard::Clipboard );
3830 void KMComposeWin::paste( TQClipboard::Mode mode )
3832 TQWidget* fw = focusWidget();
3835 TQMimeSource *mimeSource = TQApplication::clipboard()->data( mode );
3836 if ( mimeSource->provides(
"image/png") ) {
3837 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3838 }
else if ( KURLDrag::canDecode( mimeSource ) ) {
3840 if( KURLDrag::decode( mimeSource, urlList ) ) {
3841 const TQString asText = i18n(
"Add as Text");
3842 const TQString asAttachment = i18n(
"Add as Attachment");
3843 const TQString text = i18n(
"Please select whether you want to insert the content as text into the editor, "
3844 "or append the referenced file as an attachment.");
3845 const TQString caption = i18n(
"Paste as text or attachment?");
3847 int id = KMessageBox::questionYesNoCancel(
this, text, caption,
3848 KGuiItem( asText ), KGuiItem( asAttachment) );
3850 case KMessageBox::Yes:
3851 for ( KURL::List::Iterator it = urlList.begin();
3852 it != urlList.end(); ++it ) {
3853 mEditor->insert( (*it).url() );
3856 case KMessageBox::No:
3857 for ( KURL::List::Iterator it = urlList.begin();
3858 it != urlList.end(); ++it ) {
3864 }
else if ( TQTextDrag::canDecode( mimeSource ) ) {
3866 if ( TQTextDrag::decode( mimeSource, s ) )
3867 mEditor->insert( s );
3873 void KMComposeWin::slotMarkAll()
3875 TQWidget* fw = focusWidget();
3878 if (::tqqt_cast<TQLineEdit*>(fw))
3879 static_cast<TQLineEdit*
>(fw)->selectAll();
3880 else if (::tqqt_cast<KEdit*>(fw))
3881 static_cast<KEdit*>(fw)->selectAll();
3886 void KMComposeWin::slotClose()
3893 void KMComposeWin::slotNewComposer()
3899 win =
new KMComposeWin(msg);
3905 void KMComposeWin::slotNewMailReader()
3907 KMMainWin *kmmwin =
new KMMainWin(0);
3914 void KMComposeWin::slotUpdWinTitle(
const TQString& text)
3920 setCaption(
"("+i18n(
"unnamed")+
")");
3921 else setCaption( s.replace( TQChar(
'\n'),
' ' ) );
3926 void KMComposeWin::slotEncryptToggled(
bool on)
3928 setEncryption( on,
true );
3929 slotUpdateSignatureAndEncrypionStateIndicators();
3934 void KMComposeWin::setEncryption(
bool encrypt,
bool setByUser )
3936 bool wasModified = isModified();
3938 setModified(
true );
3939 if ( !mEncryptAction->isEnabled() )
3943 else if ( encrypt && encryptToSelf() && !mLastIdentityHasEncryptionKey ) {
3945 KMessageBox::sorry(
this,
3946 i18n(
"<qt><p>You have requested that messages be "
3947 "encrypted to yourself, but the currently selected "
3948 "identity does not define an (OpenPGP or S/MIME) "
3949 "encryption key to use for this.</p>"
3950 "<p>Please select the key(s) to use "
3951 "in the identity configuration.</p>"
3953 i18n(
"Undefined Encryption Key") );
3954 setModified( wasModified );
3960 mEncryptAction->setChecked( encrypt );
3964 mEncryptAction->setIcon(
"encrypted");
3966 mEncryptAction->setIcon(
"decrypted");
3969 if ( canSignEncryptAttachments() ) {
3970 for ( KMAtmListViewItem* entry =
3971 static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3973 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
3974 entry->setEncrypt( encrypt );
3980 void KMComposeWin::slotSignToggled(
bool on)
3982 setSigning( on,
true );
3983 slotUpdateSignatureAndEncrypionStateIndicators();
3988 void KMComposeWin::setSigning(
bool sign,
bool setByUser )
3990 bool wasModified = isModified();
3992 setModified(
true );
3993 if ( !mSignAction->isEnabled() )
3997 if ( sign && !mLastIdentityHasSigningKey ) {
3999 KMessageBox::sorry(
this,
4000 i18n(
"<qt><p>In order to be able to sign "
4001 "this message you first have to "
4002 "define the (OpenPGP or S/MIME) signing key "
4004 "<p>Please select the key to use "
4005 "in the identity configuration.</p>"
4007 i18n(
"Undefined Signing Key") );
4008 setModified( wasModified );
4014 mSignAction->setChecked( sign );
4017 if ( canSignEncryptAttachments() ) {
4018 for ( KMAtmListViewItem* entry =
4019 static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
4021 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
4022 entry->setSign( sign );
4028 void KMComposeWin::slotWordWrapToggled(
bool on)
4032 mEditor->setWordWrap( TQTextEdit::FixedColumnWidth );
4033 mEditor->setWrapColumnOrWidth( GlobalSettings::self()->lineWrapWidth() );
4037 mEditor->setWordWrap( TQTextEdit::WidgetWidth );
4042 void KMComposeWin::disableWordWrap()
4044 mEditor->setWordWrap( TQTextEdit::NoWrap );
4047 void KMComposeWin::disableRecipientNumberCheck()
4049 mCheckForRecipients =
false;
4052 void KMComposeWin::disableForgottenAttachmentsCheck()
4054 mCheckForForgottenAttachments =
false;
4057 void KMComposeWin::ignoreStickyFields()
4059 mIgnoreStickyFields =
true;
4060 mBtnTransport->setChecked(
false );
4061 mBtnDictionary->setChecked(
false );
4062 mBtnIdentity->setChecked(
false );
4063 mBtnTransport->setEnabled(
false );
4064 mBtnDictionary->setEnabled(
false );
4065 mBtnIdentity->setEnabled(
false );
4069 void KMComposeWin::slotPrint()
4071 mMessageWasModified = isModified();
4072 connect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4073 TQT_TQOBJECT(
this), TQT_SLOT( slotContinuePrint(
bool ) ) );
4074 applyChanges(
true );
4077 void KMComposeWin::slotContinuePrint(
bool rc )
4079 disconnect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4080 TQT_TQOBJECT(
this), TQT_SLOT( slotContinuePrint(
bool ) ) );
4083 if ( mComposedMessages.isEmpty() ) {
4084 kdDebug(5006) <<
"Composing the message failed." << endl;
4087 KMCommand *command =
new KMPrintCommand(
this, mComposedMessages.first() );
4089 setModified( mMessageWasModified );
4094 bool KMComposeWin::validateAddresses( TQWidget * parent,
const TQString & addresses )
4096 TQString brokenAddress;
4098 if ( !( errorCode == KPIM::AddressOk || errorCode == KPIM::AddressEmpty ) ) {
4099 TQString errorMsg(
"<qt><p><b>" + brokenAddress +
4100 "</b></p><p>" + KPIM::emailParseResultToString( errorCode ) +
4102 KMessageBox::sorry( parent, errorMsg, i18n(
"Invalid Email Address") );
4109 void KMComposeWin::doSend( KMail::MessageSender::SendMethod method,
4110 KMComposeWin::SaveIn saveIn )
4112 if ( method != KMail::MessageSender::SendLater && kmkernel->isOffline() ) {
4113 KMessageBox::information(
this,
4114 i18n(
"KMail is currently in offline mode,"
4115 "your messages will be kept in the outbox until you go online."),
4116 i18n(
"Online/Offline"),
"kmailIsOffline" );
4117 mSendMethod = KMail::MessageSender::SendLater;
4119 mSendMethod = method;
4123 if ( saveIn == KMComposeWin::None ) {
4124 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() ) {
4125 if ( !( mShowHeaders & HDR_FROM ) ) {
4126 mShowHeaders |= HDR_FROM;
4127 rethinkFields(
false );
4129 mEdtFrom->setFocus();
4130 KMessageBox::sorry(
this,
4131 i18n(
"You must enter your email address in the "
4132 "From: field. You should also set your email "
4133 "address for all identities, so that you do "
4134 "not have to enter it for each message.") );
4137 if ( to().isEmpty() )
4139 if ( cc().isEmpty() && bcc().isEmpty()) {
4140 if ( mEdtTo ) mEdtTo->setFocus();
4141 KMessageBox::information(
this,
4142 i18n(
"You must specify at least one receiver,"
4143 "either in the To: field or as CC or as BCC.") );
4147 if ( mEdtTo ) mEdtTo->setFocus();
4149 KMessageBox::questionYesNo(
this,
4150 i18n(
"To field is missing."
4151 "Send message anyway?"),
4152 i18n(
"No To: specified") );
4153 if ( rc == KMessageBox::No ){
4160 if ( !validateAddresses(
this, to().stripWhiteSpace() ) ) {
4164 if ( !validateAddresses(
this, cc().stripWhiteSpace() ) ) {
4168 if ( !validateAddresses(
this, bcc().stripWhiteSpace() ) ) {
4172 if (subject().isEmpty())
4174 mEdtSubject->setFocus();
4176 KMessageBox::questionYesNo(
this,
4177 i18n(
"You did not specify a subject. "
4178 "Send message anyway?"),
4179 i18n(
"No Subject Specified"),
4180 i18n(
"S&end as Is"),
4181 i18n(
"&Specify the Subject"),
4182 "no_subject_specified" );
4183 if( rc == KMessageBox::No )
4189 if ( userForgotAttachment() )
4194 mMsg->setDateToday();
4201 TQString hf = mMsg->headerField(
"X-KMail-Transport");
4202 if ((mTransport->currentText() != mTransport->text(0)) ||
4203 (!hf.isEmpty() && (hf != mTransport->text(0))))
4204 mMsg->setHeaderField(
"X-KMail-Transport", mTransport->currentText());
4206 mDisableBreaking = ( saveIn != KMComposeWin::None );
4208 const bool neverEncrypt = ( mDisableBreaking && GlobalSettings::self()->neverEncryptDrafts() )
4209 || mSigningAndEncryptionExplicitlyDisabled;
4210 connect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4211 TQT_SLOT( slotContinueDoSend(
bool ) ) );
4213 if ( mEditor->textFormat() == TQt::RichText )
4214 mMsg->setHeaderField(
"X-KMail-Markup",
"true" );
4216 mMsg->removeHeaderField(
"X-KMail-Markup" );
4217 if ( mEditor->textFormat() == TQt::RichText && inlineSigningEncryptionSelected() ) {
4218 TQString keepBtnText = mEncryptAction->isChecked() ?
4219 mSignAction->isChecked() ? i18n(
"&Keep markup, do not sign/encrypt" )
4220 : i18n(
"&Keep markup, do not encrypt" )
4221 : i18n(
"&Keep markup, do not sign" );
4222 TQString yesBtnText = mEncryptAction->isChecked() ?
4223 mSignAction->isChecked() ? i18n(
"Sign/Encrypt (delete markup)")
4224 : i18n(
"Encrypt (delete markup)" )
4225 : i18n(
"Sign (delete markup)" );
4226 int ret = KMessageBox::warningYesNoCancel(
this,
4227 i18n(
"<qt><p>Inline signing/encrypting of HTML messages is not possible;</p>"
4228 "<p>do you want to delete your markup?</p></qt>"),
4229 i18n(
"Sign/Encrypt Message?"),
4230 KGuiItem( yesBtnText ),
4231 KGuiItem( keepBtnText ) );
4232 if ( KMessageBox::Cancel == ret )
4234 if ( KMessageBox::No == ret ) {
4235 mEncryptAction->setChecked(
false);
4236 mSignAction->setChecked(
false);
4239 toggleMarkup(
false);
4243 if (neverEncrypt && saveIn != KMComposeWin::None ) {
4246 mMsg->setHeaderField(
"X-KMail-SignatureActionEnabled", mSignAction->isChecked()?
"true":
"false" );
4247 mMsg->setHeaderField(
"X-KMail-EncryptActionEnabled", mEncryptAction->isChecked()?
"true":
"false" );
4248 mMsg->setHeaderField(
"X-KMail-CryptoMessageFormat", TQString::number( cryptoMessageFormat() ) );
4250 mMsg->removeHeaderField(
"X-KMail-SignatureActionEnabled" );
4251 mMsg->removeHeaderField(
"X-KMail-EncryptActionEnabled" );
4252 mMsg->removeHeaderField(
"X-KMail-CryptoMessageFormat" );
4256 kdDebug(5006) <<
"KMComposeWin::doSend() - calling applyChanges()"
4258 applyChanges( neverEncrypt );
4261 bool KMComposeWin::saveDraftOrTemplate(
const TQString &folderName,
4264 KMFolder *theFolder = 0, *imapTheFolder = 0;
4266 if ( !folderName.isEmpty() ) {
4267 theFolder = kmkernel->folderMgr()->findIdString( folderName );
4268 if ( theFolder == 0 )
4271 theFolder = kmkernel->dimapFolderMgr()->findIdString( folderName );
4272 if ( theFolder == 0 )
4273 imapTheFolder = kmkernel->imapFolderMgr()->findIdString( folderName );
4274 if ( !theFolder && !imapTheFolder ) {
4275 const KPIM::Identity &
id = kmkernel->identityManager()
4276 ->identityForUoidOrDefault( msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt() );
4277 KMessageBox::information( 0,
4278 i18n(
"The custom drafts or templates folder for "
4279 "identify \"%1\" does not exist (anymore); "
4280 "therefore, the default drafts or templates "
4281 "folder will be used.")
4282 .arg(
id.identityName() ) );
4285 if ( imapTheFolder && imapTheFolder->noContent() )
4288 bool didOpen =
false;
4289 if ( theFolder == 0 ) {
4290 theFolder = ( mSaveIn==KMComposeWin::Drafts ?
4291 kmkernel->draftsFolder() : kmkernel->templatesFolder() );
4294 theFolder->
open(
"composer" );
4297 kdDebug(5006) << k_funcinfo <<
"theFolder=" << theFolder->name() << endl;
4298 if ( imapTheFolder )
4299 kdDebug(5006) << k_funcinfo <<
"imapTheFolder=" << imapTheFolder->name() << endl;
4301 bool sentOk = !( theFolder->
addMsg( msg ) );
4305 msg = theFolder->
getMsg( theFolder->
count() - 1 );
4308 if ( imapTheFolder ) {
4310 imapTheFolder->moveMsg( msg );
4311 (
static_cast<KMFolderImap*
>( imapTheFolder->storage() ))->getFolder();
4315 theFolder->
close(
"composer" );
4319 void KMComposeWin::slotContinueDoSend(
bool sentOk )
4321 kdDebug(5006) <<
"KMComposeWin::slotContinueDoSend( " << sentOk <<
" )"
4323 disconnect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4324 TQT_TQOBJECT(
this), TQT_SLOT( slotContinueDoSend(
bool ) ) );
4327 mDisableBreaking =
false;
4331 for ( TQValueVector<KMMessage*>::iterator it = mComposedMessages.begin() ; it != mComposedMessages.end() ; ++it ) {
4334 (*it)->cleanupHeader();
4337 (*it)->setComplete(
true );
4339 if ( mSaveIn==KMComposeWin::Drafts ) {
4340 sentOk = saveDraftOrTemplate( (*it)->drafts(), (*it) );
4341 }
else if ( mSaveIn==KMComposeWin::Templates ) {
4342 sentOk = saveDraftOrTemplate( (*it)->templates(), (*it) );
4346 if( !mComposer->originalBCC().isEmpty() )
4348 TQString recips = (*it)->headerField(
"X-KMail-Recipients" );
4349 if( !recips.isEmpty() ) {
4352 (*it)->cleanupHeader();
4353 sentOk = kmkernel->msgSender()->send((*it), mSendMethod);
4362 RecentAddresses::self( KMKernel::config() )->add( bcc() );
4363 RecentAddresses::self( KMKernel::config() )->add( cc() );
4364 RecentAddresses::self( KMKernel::config() )->add( to() );
4366 setModified(
false );
4367 mAutoDeleteMsg =
false;
4374 bool KMComposeWin::checkTransport()
const
4377 KMessageBox::information( mMainWidget,
4378 i18n(
"Please create an account for sending and try again.") );
4386 void KMComposeWin::slotSendLater()
4388 if ( !checkTransport() )
4390 if ( !checkRecipientNumber() )
4392 if ( mEditor->checkExternalEditorFinished() )
4393 doSend( KMail::MessageSender::SendLater );
4398 void KMComposeWin::slotSaveDraft() {
4399 if ( mEditor->checkExternalEditorFinished() )
4400 doSend( KMail::MessageSender::SendLater, KMComposeWin::Drafts );
4404 void KMComposeWin::slotSaveTemplate() {
4405 if ( mEditor->checkExternalEditorFinished() )
4406 doSend( KMail::MessageSender::SendLater, KMComposeWin::Templates );
4410 void KMComposeWin::slotSendNowVia(
int item )
4413 TQString customTransport = availTransports[ item ];
4415 mTransport->setCurrentText( customTransport );
4420 void KMComposeWin::slotSendLaterVia(
int item )
4423 TQString customTransport = availTransports[ item ];
4425 mTransport->setCurrentText( customTransport );
4431 void KMComposeWin::slotSendNow() {
4432 if ( !mEditor->checkExternalEditorFinished() )
4434 if ( !checkTransport() )
4436 if ( !checkRecipientNumber() )
4438 if ( GlobalSettings::self()->confirmBeforeSend() )
4440 int rc = KMessageBox::warningYesNoCancel( mMainWidget,
4441 i18n(
"About to send email..."),
4442 i18n(
"Send Confirmation"),
4444 i18n(
"Send &Later") );
4446 if ( rc == KMessageBox::Yes )
4447 doSend( KMail::MessageSender::SendImmediate );
4448 else if ( rc == KMessageBox::No )
4449 doSend( KMail::MessageSender::SendLater );
4452 doSend( KMail::MessageSender::SendImmediate );
4457 bool KMComposeWin::checkRecipientNumber()
const
4459 uint thresHold = GlobalSettings::self()->recipientThreshold();
4460 if ( mCheckForRecipients &&
4461 GlobalSettings::self()->tooManyRecipients() &&
4462 mRecipientsEditor->recipients().count() > thresHold ) {
4463 if ( KMessageBox::questionYesNo( mMainWidget,
4464 i18n(
"You are trying to send the mail to more than %1 recipients. Send message anyway?").arg(thresHold),
4465 i18n(
"Too many receipients"),
4466 i18n(
"&Send as Is"),
4467 i18n(
"&Edit Recipients")) == KMessageBox::No ) {
4476 void KMComposeWin::slotAppendSignature()
4482 void KMComposeWin::slotPrependSignature()
4484 insertSignature( Prepend );
4488 void KMComposeWin::slotInsertSignatureAtCursor()
4490 insertSignature( AtCursor );
4494 void KMComposeWin::insertSignature( SignaturePlacement placement )
4496 bool mod = mEditor->isModified();
4498 const KPIM::Identity &ident =
4499 kmkernel->identityManager()->
4500 identityForUoidOrDefault( mIdentity->currentIdentity() );
4502 mOldSigText = GlobalSettings::self()->prependSignature()? ident.signature().rawText() : ident.signatureText();
4504 if( !mOldSigText.isEmpty() )
4507 int paragraph, index;
4508 mEditor->getCursorPosition( ¶graph, &index );
4509 index = mEditor->indexOfCurrentLineStart( paragraph, index );
4511 switch( placement ) {
4513 mEditor->setText( mEditor->text() + mOldSigText );
4516 mOldSigText =
"\n\n" + mOldSigText +
"\n";
4517 mEditor->insertAt( mOldSigText, paragraph, index );
4524 if ( mEditor->paragraphLength( paragraph ) > 0 )
4525 mOldSigText = mOldSigText +
"\n";
4526 if ( mOldSigText.startsWith(
"\n" ) )
4527 mOldSigText = mOldSigText.remove( 0, 1 );
4532 mOldSigText =
"\n" + mOldSigText;
4534 mEditor->insertAt( mOldSigText, paragraph, index );
4538 mEditor->setModified(mod);
4540 if ( mPreserveUserCursorPosition ) {
4541 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
4546 mPreserveUserCursorPosition =
false;
4551 mEditor->setCursorPosition( paragraph, 0 );
4554 mEditor->setCursorPosition( paragraph + 1, 0 );
4556 if ( placement == Prepend || placement == Append )
4557 mEditor->setContentsPos( 0, 0 );
4564 void KMComposeWin::slotHelp()
4570 void KMComposeWin::slotCleanSpace()
4581 if ( mEditor->hasMarkedText() ) {
4582 s = mEditor->markedText();
4586 s = mEditor->text();
4591 bool restore =
false;
4592 const KPIM::Identity & ident =
4593 kmkernel->identityManager()->identityForUoid( mId );
4594 if ( !ident.isNull() ) {
4595 sig = ident.signatureText();
4596 if( !sig.isEmpty() ) {
4597 if( s.endsWith( sig ) ) {
4598 s.truncate( s.length() - sig.length() );
4605 TQRegExp squeeze(
"[\t ]+" );
4606 s.replace( squeeze, TQChar(
' ' ) );
4609 TQRegExp trailing(
"\\s+$" );
4610 s.replace( trailing, TQChar(
'\n' ) );
4613 TQRegExp singleSpace(
"[\n]{2,}" );
4614 s.replace( singleSpace, TQChar(
'\n' ) );
4627 if ( !mEditor->hasMarkedText() )
4629 mEditor->insert( s );
4633 void KMComposeWin::slotToggleMarkup()
4635 if ( markupAction->isChecked() ) {
4637 toolBar(
"htmlToolBar")->show();
4639 fontChanged( mEditor->currentFont() );
4640 mSaveFont = mEditor->currentFont();
4643 toggleMarkup(
false);
4647 void KMComposeWin::toggleMarkup(
bool markup)
4650 if ( !mUseHTMLEditor ) {
4651 kdDebug(5006) <<
"setting RichText editor" << endl;
4652 mUseHTMLEditor =
true;
4656 int paraFrom, indexFrom, paraTo, indexTo;
4657 mEditor->getSelection ( ¶From, &indexFrom, ¶To, &indexTo);
4658 mEditor->selectAll();
4660 bool _bold = textBoldAction->isChecked();
4661 bool _italic = textItalicAction->isChecked();
4662 mEditor->setColor(TQColor(0,0,0));
4663 textBoldAction->setChecked(_bold);
4664 textItalicAction->setChecked(_italic);
4665 mEditor->setSelection ( paraFrom, indexFrom, paraTo, indexTo);
4667 mEditor->setTextFormat(TQt::RichText);
4668 mEditor->setModified(
true);
4669 markupAction->setChecked(
true);
4670 toolBar(
"htmlToolBar" )->show();
4671 mEditor->deleteAutoSpellChecking();
4672 mAutoSpellCheckingAction->setChecked(
false);
4673 slotAutoSpellCheckingToggled(
false);
4676 kdDebug(5006) <<
"setting PlainText editor" << endl;
4677 mHtmlMarkup =
false;
4678 toolBar(
"htmlToolBar")->hide();
4679 if ( mUseHTMLEditor ) {
4680 mUseHTMLEditor =
false;
4681 mEditor->setTextFormat(TQt::PlainText);
4682 TQString text = mEditor->text();
4683 mEditor->setText(text);
4684 mEditor->setModified(
true);
4685 slotAutoSpellCheckingToggled(
true);
4690 void KMComposeWin::htmlToolBarVisibilityChanged(
bool visible )
4694 markupAction->setChecked(
false );
4695 toggleMarkup(
false );
4699 void KMComposeWin::slotSubjectTextSpellChecked()
4701 mSubjectTextWasSpellChecked =
true;
4705 void KMComposeWin::slotAutoSpellCheckingToggled(
bool on )
4707 if ( mEditor->autoSpellChecking(on) == -1 ) {
4708 mAutoSpellCheckingAction->setChecked(
false);
4713 temp = i18n(
"Spellcheck: on" );
4715 temp = i18n(
"Spellcheck: off" );
4716 statusBar()->changeItem( temp, 3 );
4719 void KMComposeWin::slotSpellcheck()
4721 if (mSpellCheckInProgress)
return;
4722 mSubjectTextWasSpellChecked =
false;
4723 mSpellCheckInProgress=
true;
4729 mEditor->spellcheck();
4732 void KMComposeWin::slotUpdateSignatureActions()
4736 const KPIM::Identity & ident =
4737 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
4738 TQString sig = ident.signatureText();
4740 if ( sig.isEmpty() ) {
4741 mAppendSignatureAction->setEnabled(
false );
4742 mPrependSignatureAction->setEnabled(
false );
4743 mInsertSignatureAction->setEnabled(
false );
4746 mAppendSignatureAction->setEnabled(
true );
4747 mPrependSignatureAction->setEnabled(
true );
4748 mInsertSignatureAction->setEnabled(
true );
4752 void KMComposeWin::polish()
4755 markupAction->setChecked(mHtmlMarkup);
4757 toolBar(
"htmlToolBar")->show();
4759 toolBar(
"htmlToolBar")->hide();
4760 KMail::Composer::polish();
4764 void KMComposeWin::slotSpellcheckDone(
int result)
4766 kdDebug(5006) <<
"spell check complete: result = " << result << endl;
4767 mSpellCheckInProgress=
false;
4772 statusBar()->changeItem(i18n(
" Spell check canceled."),0);
4775 statusBar()->changeItem(i18n(
" Spell check stopped."),0);
4778 statusBar()->changeItem(i18n(
" Spell check complete."),0);
4781 TQTimer::singleShot( 2000,
this, TQT_SLOT(slotSpellcheckDoneClearStatus()) );
4784 void KMComposeWin::slotSpellcheckDoneClearStatus()
4786 statusBar()->changeItem(
"", 0);
4791 void KMComposeWin::slotIdentityChanged( uint uoid )
4793 const KPIM::Identity & ident =
4794 kmkernel->identityManager()->identityForUoid( uoid );
4795 if( ident.isNull() )
return;
4798 slotUpdateSignatureActions();
4800 if( !ident.fullEmailAddr().isNull() )
4801 mEdtFrom->setText(ident.fullEmailAddr());
4803 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() )
4804 mShowHeaders |= HDR_FROM;
4805 if ( mEdtReplyTo ) mEdtReplyTo->setText(ident.replyToAddr());
4807 if ( mRecipientsEditor ) {
4809 const KPIM::Identity & oldIdentity =
4810 kmkernel->identityManager()->identityForUoidOrDefault( mId );
4811 if ( oldIdentity.bcc() != ident.bcc() ) {
4812 mRecipientsEditor->removeRecipient( oldIdentity.bcc(), Recipient::Bcc );
4813 mRecipientsEditor->addRecipient( ident.bcc(), Recipient::Bcc );
4814 mRecipientsEditor->setFocusBottom();
4820 if( mEdtBcc && !mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4823 if( !mEdtBcc->text().isEmpty() && mEdtBcc->text() != ident.bcc() && !mEdtBcc->edited() ) {
4824 mEdtBcc->setText( ident.bcc() );
4829 if ( mEdtBcc->text() != ident.bcc() && !mEdtBcc->text().isEmpty() ) {
4830 TQString temp_string( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4831 mEdtBcc->setText( temp_string );
4835 mEdtBcc->setText( ident.bcc() );
4842 if( mEdtBcc && mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4843 if( !mEdtBcc->text().isEmpty() ) {
4844 TQString temp_string ( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4845 mEdtBcc->setText( temp_string );
4847 mEdtBcc->setText( ident.bcc() );
4853 if( mEdtBcc && !mEdtBcc->edited() && ident.bcc().isEmpty() ) {
4854 mEdtBcc->setText( ident.bcc() );
4857 if ( !ident.bcc().isEmpty() ) {
4858 mShowHeaders |= HDR_BCC;
4861 if ( ident.organization().isEmpty() )
4862 mMsg->removeHeaderField(
"Organization");
4864 mMsg->setHeaderField(
"Organization", ident.organization());
4866 if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
4867 mMsg->removeHeaderField(
"X-Face");
4870 TQString xface = ident.xface();
4871 if (!xface.isEmpty())
4873 int numNL = ( xface.length() - 1 ) / 70;
4874 for (
int i = numNL; i > 0; --i )
4875 xface.insert( i*70,
"\n\t" );
4876 mMsg->setHeaderField(
"X-Face", xface);
4880 if ( !mBtnTransport->isChecked() && !mIgnoreStickyFields ) {
4881 TQString transp = ident.transport();
4882 if ( transp.isEmpty() )
4884 mMsg->removeHeaderField(
"X-KMail-Transport");
4885 transp = GlobalSettings::self()->defaultTransport();
4888 mMsg->setHeaderField(
"X-KMail-Transport", transp);
4889 setTransport( transp );
4892 if ( !mBtnDictionary->isChecked() && !mIgnoreStickyFields ) {
4893 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
4896 if ( !mBtnFcc->isChecked() && !mPreventFccOverwrite ) {
4897 setFcc( ident.fcc() );
4900 TQString edtText = mEditor->text();
4902 if ( mOldSigText.isEmpty() ) {
4903 const KPIM::Identity &
id =
4906 identityForUoidOrDefault( mMsg->headerField(
"X-KMail-Identity" ).
4907 stripWhiteSpace().toUInt() );
4908 mOldSigText = GlobalSettings::self()->prependSignature() ?
id.signature().rawText() :
id.signatureText();
4912 if ( !GlobalSettings::prependSignature() ) {
4915 while ( !edtText.isEmpty() && edtText[edtText.length()-1].isSpace() )
4916 edtText.truncate( edtText.length() - 1 );
4918 while ( !mOldSigText.isEmpty() && mOldSigText[mOldSigText.length()-1].isSpace() )
4919 mOldSigText.truncate( mOldSigText.length() - 1 );
4921 if ( edtText.endsWith( mOldSigText ) )
4922 edtText.truncate( edtText.length() - mOldSigText.length() );
4925 mOldSigText = ident.signatureText();
4926 if( ( !mOldSigText.isEmpty() ) &&
4927 ( GlobalSettings::self()->autoTextSignature() ==
"auto" ) ) {
4928 edtText.append( mOldSigText );
4930 mEditor->setText( edtText );
4932 const int pos = edtText.find( mOldSigText );
4933 if ( pos >= 0 && !mOldSigText.isEmpty() ) {
4934 const int oldLength = mOldSigText.length();
4935 mOldSigText =
"\n\n"+ ident.signature().rawText() +
"\n";
4936 edtText = edtText.replace( pos, oldLength, mOldSigText );
4937 mEditor->setText( edtText );
4939 insertSignature( Append );
4945 bool bNewIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4946 bool bNewIdentityHasEncryptionKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4947 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
4948 !ident.pgpEncryptionKey().isEmpty() );
4950 if ( !bNewIdentityHasEncryptionKey && mLastIdentityHasEncryptionKey ) {
4951 mLastEncryptActionState = mEncryptAction->isChecked();
4952 setEncryption(
false );
4954 if ( !bNewIdentityHasSigningKey && mLastIdentityHasSigningKey ) {
4955 mLastSignActionState = mSignAction->isChecked();
4956 setSigning(
false );
4959 if ( bNewIdentityHasEncryptionKey && !mLastIdentityHasEncryptionKey )
4960 setEncryption( mLastEncryptActionState );
4961 if ( bNewIdentityHasSigningKey && !mLastIdentityHasSigningKey )
4962 setSigning( mLastSignActionState );
4964 mLastIdentityHasSigningKey = bNewIdentityHasSigningKey;
4965 mLastIdentityHasEncryptionKey = bNewIdentityHasEncryptionKey;
4967 setModified(
true );
4971 rethinkFields(
false );
4975 void KMComposeWin::slotSpellcheckConfig()
4977 KDialogBase dlg(KDialogBase::Plain, i18n(
"Spellchecker"),
4978 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok,
4979 TQT_TQWIDGET(
this), 0,
true,
true );
4981 TQTabDialog qtd (
this,
"tabdialog",
true);
4982 KSpellConfig mKSpellConfig (&qtd);
4983 mKSpellConfig.layout()->setMargin( KDialog::marginHint() );
4985 qtd.addTab (&mKSpellConfig, i18n(
"Spellchecker"));
4986 qtd.setCancelButton ();
4988 kwin.setIcons (qtd.winId(), kapp->icon(), kapp->miniIcon());
4989 qtd.setCancelButton(KStdGuiItem::cancel().text());
4990 qtd.setOkButton(KStdGuiItem::ok().text());
4993 mKSpellConfig.writeGlobalSettings();
4997 void KMComposeWin::slotStatusMessage(
const TQString &message)
4999 statusBar()->changeItem( message, 0 );
5002 void KMComposeWin::slotEditToolbars()
5004 saveMainWindowSettings(KMKernel::config(),
"Composer");
5005 KEditToolbar dlg(guiFactory(),
this);
5007 connect( &dlg, TQT_SIGNAL(newToolbarConfig()),
5008 TQT_SLOT(slotUpdateToolbars()) );
5013 void KMComposeWin::slotUpdateToolbars()
5015 createGUI(
"kmcomposerui.rc");
5016 applyMainWindowSettings(KMKernel::config(),
"Composer");
5019 void KMComposeWin::slotEditKeys()
5021 KKeyDialog::configure( actionCollection(),
5026 void KMComposeWin::setReplyFocus(
bool hasMessage )
5028 mEditor->setFocus();
5030 if( mMsg->getCursorPos() ) {
5031 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
5033 mEditor->setCursorPosition( 1, 0 );
5038 void KMComposeWin::setFocusToSubject()
5040 mEdtSubject->setFocus();
5043 int KMComposeWin::autoSaveInterval()
const
5045 return GlobalSettings::self()->autosaveInterval() * 1000 * 60;
5048 void KMComposeWin::initAutoSave()
5050 kdDebug(5006) << k_funcinfo << endl;
5053 if ( mAutoSaveFilename.isEmpty() ) {
5054 mAutoSaveFilename = KMFolderMaildir::constructValidFileName();
5060 void KMComposeWin::updateAutoSave()
5062 if ( autoSaveInterval() == 0 ) {
5063 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5066 if ( !mAutoSaveTimer ) {
5067 mAutoSaveTimer =
new TQTimer(
this,
"mAutoSaveTimer" );
5068 connect( mAutoSaveTimer, TQT_SIGNAL( timeout() ),
5069 TQT_TQOBJECT(
this), TQT_SLOT( autoSaveMessage() ) );
5071 mAutoSaveTimer->start( autoSaveInterval() );
5075 void KMComposeWin::setAutoSaveFilename(
const TQString & filename )
5077 mAutoSaveFilename = filename;
5080 void KMComposeWin::cleanupAutoSave()
5082 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5083 if ( !mAutoSaveFilename.isEmpty() ) {
5084 kdDebug(5006) << k_funcinfo <<
"deleting autosave file "
5085 << mAutoSaveFilename << endl;
5087 mAutoSaveFilename );
5088 mAutoSaveFilename = TQString();
5092 void KMComposeWin::slotCompletionModeChanged( KGlobalSettings::Completion mode)
5094 GlobalSettings::self()->setCompletionMode( (
int) mode );
5097 mEdtFrom->setCompletionMode( mode );
5098 mEdtReplyTo->setCompletionMode( mode );
5099 if ( mClassicalRecipients ) {
5100 mEdtTo->setCompletionMode( mode );
5101 mEdtCc->setCompletionMode( mode );
5102 mEdtBcc->setCompletionMode( mode );
5104 mRecipientsEditor->setCompletionMode( mode );
5107 void KMComposeWin::slotConfigChanged()
5112 slotWordWrapToggled( mWordWrapAction->isChecked() );
5119 void KMComposeWin::slotFolderRemoved(
KMFolder* folder)
5122 if ( (mFolder) && (folder->
idString() == mFolder->idString()) )
5124 mFolder = kmkernel->draftsFolder();
5125 kdDebug(5006) <<
"restoring drafts to " << mFolder->idString() << endl;
5127 if (mMsg) mMsg->setParent(0);
5131 void KMComposeWin::editorFocusChanged(
bool gained)
5133 mPasteQuotation->setEnabled(gained);
5136 void KMComposeWin::slotSetAlwaysSend(
bool bAlways )
5138 mAlwaysSend = bAlways;
5141 void KMComposeWin::slotListAction(
const TQString& style )
5144 if ( style == i18n(
"Standard" ) )
5145 mEditor->setParagType( TQStyleSheetItem::DisplayBlock, TQStyleSheetItem::ListDisc );
5146 else if ( style == i18n(
"Bulleted List (Disc)" ) )
5147 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDisc );
5148 else if ( style == i18n(
"Bulleted List (Circle)" ) )
5149 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListCircle );
5150 else if ( style == i18n(
"Bulleted List (Square)" ) )
5151 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListSquare );
5152 else if ( style == i18n(
"Ordered List (Decimal)" ))
5153 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDecimal );
5154 else if ( style == i18n(
"Ordered List (Alpha lower)" ) )
5155 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListLowerAlpha );
5156 else if ( style == i18n(
"Ordered List (Alpha upper)" ) )
5157 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListUpperAlpha );
5158 mEditor->viewport()->setFocus();
5161 void KMComposeWin::slotFontAction(
const TQString& font)
5164 mEditor->TQTextEdit::setFamily( font );
5165 mEditor->viewport()->setFocus();
5168 void KMComposeWin::slotSizeAction(
int size )
5171 mEditor->setPointSize( size );
5172 mEditor->viewport()->setFocus();
5175 void KMComposeWin::slotAlignLeft()
5178 mEditor->TQTextEdit::setAlignment( AlignLeft );
5181 void KMComposeWin::slotAlignCenter()
5184 mEditor->TQTextEdit::setAlignment( AlignHCenter );
5187 void KMComposeWin::slotAlignRight()
5190 mEditor->TQTextEdit::setAlignment( AlignRight );
5193 void KMComposeWin::slotTextBold()
5196 mEditor->TQTextEdit::setBold( textBoldAction->isChecked() );
5199 void KMComposeWin::slotTextItalic()
5202 mEditor->TQTextEdit::setItalic( textItalicAction->isChecked() );
5205 void KMComposeWin::slotTextUnder()
5208 mEditor->TQTextEdit::setUnderline( textUnderAction->isChecked() );
5211 void KMComposeWin::slotFormatReset()
5213 mEditor->setColor(mForeColor);
5214 mEditor->setCurrentFont( mSaveFont );
5216 void KMComposeWin::slotTextColor()
5218 TQColor color = mEditor->color();
5220 if ( KColorDialog::getColor( color,
this ) ) {
5222 mEditor->setColor( color );
5226 void KMComposeWin::fontChanged(
const TQFont &f )
5228 TQFont fontTemp = f;
5229 fontTemp.setBold(
true );
5230 fontTemp.setItalic(
true );
5231 TQFontInfo fontInfo( fontTemp );
5233 if ( fontInfo.bold() ) {
5234 textBoldAction->setChecked( f.bold() );
5235 textBoldAction->setEnabled(
true ) ;
5237 textBoldAction->setEnabled(
false );
5240 if ( fontInfo.italic() ) {
5241 textItalicAction->setChecked( f.italic() );
5242 textItalicAction->setEnabled(
true ) ;
5244 textItalicAction->setEnabled(
false );
5247 textUnderAction->setChecked( f.underline() );
5249 fontAction->setFont( f.family() );
5250 fontSizeAction->setFontSize( f.pointSize() );
5253 void KMComposeWin::alignmentChanged(
int a )
5256 alignLeftAction->setChecked( ( a == AlignAuto ) || ( a & AlignLeft ) );
5257 alignCenterAction->setChecked( ( a & AlignHCenter ) );
5258 alignRightAction->setChecked( ( a & AlignRight ) );
5262 class KToggleActionResetter {
5263 KToggleAction * mAction;
5266 KToggleActionResetter( KToggleAction * action,
bool on )
5267 : mAction( action ), mOn( on ) {}
5268 ~KToggleActionResetter() {
5270 mAction->setChecked( mOn );
5272 void disable() { mAction = 0; }
5276 void KMComposeWin::slotEncryptChiasmusToggled(
bool on ) {
5277 mEncryptWithChiasmus =
false;
5282 KToggleActionResetter resetter( mEncryptChiasmusAction,
false );
5284 const Kleo::CryptoBackend::Protocol * chiasmus =
5285 Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" );
5288 const TQString msg = Kleo::CryptoBackendFactory::instance()->knowsAboutProtocol(
"Chiasmus" )
5289 ? i18n(
"Please configure a Crypto Backend to use for "
5290 "Chiasmus encryption first.\n"
5291 "You can do this in the Crypto Backends tab of "
5292 "the configure dialog's Security page." )
5293 : i18n(
"It looks as though libkleopatra was compiled without "
5294 "Chiasmus support. You might want to recompile "
5295 "libkleopatra with --enable-chiasmus.");
5296 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Backend Configured" ) );
5300 STD_NAMESPACE_PREFIX auto_ptr<Kleo::SpecialJob> job( chiasmus->specialJob(
"x-obtain-keys", TQMap<TQString,TQVariant>() ) );
5302 const TQString msg = i18n(
"Chiasmus backend does not offer the "
5303 "\"x-obtain-keys\" function. Please report this bug." );
5304 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5308 if ( job->exec() ) {
5309 job->showErrorDialog(
this, i18n(
"Chiasmus Backend Error" ) );
5313 const TQVariant result = job->property(
"result" );
5314 if ( result.type() != TQVariant::StringList ) {
5315 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
5316 "The \"x-obtain-keys\" function did not return a "
5317 "string list. Please report this bug." );
5318 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5322 const TQStringList keys = result.toStringList();
5323 if ( keys.empty() ) {
5324 const TQString msg = i18n(
"No keys have been found. Please check that a "
5325 "valid key path has been set in the Chiasmus "
5327 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Keys Found" ) );
5331 ChiasmusKeySelector selectorDlg(
this, i18n(
"Chiasmus Encryption Key Selection" ),
5332 keys, GlobalSettings::chiasmusKey(),
5333 GlobalSettings::chiasmusOptions() );
5334 if ( selectorDlg.exec() != TQDialog::Accepted )
5337 GlobalSettings::setChiasmusOptions( selectorDlg.options() );
5338 GlobalSettings::setChiasmusKey( selectorDlg.key() );
5339 assert( !GlobalSettings::chiasmusKey().isEmpty() );
5340 mEncryptWithChiasmus =
true;
5346 kdDebug(5006) << k_funcinfo << endl;
5347 KMMessagePart *part = mEditorMap[ watcher ];
5348 KTempFile *tf = mEditorTempFiles[ watcher ];
5349 mEditorMap.remove( watcher );
5350 mEditorTempFiles.remove( watcher );
5351 if ( !watcher->fileChanged() )
5354 tf->file()->reset();
5355 TQByteArray data = tf->file()->readAll();
5356 part->setBodyEncodedBinary( data );
5360 void KMComposeWin::slotUpdateSignatureAndEncrypionStateIndicators()
5362 const bool showIndicatorsAlways =
false;
5363 mSignatureStateIndicator->setText( mSignAction->isChecked()? i18n(
"Message will be signed") : i18n(
"Message will not be signed") );
5364 mEncryptionStateIndicator->setText( mEncryptAction->isChecked()? i18n(
"Message will be encrypted") : i18n(
"Message will not be encrypted") );
5365 if ( !showIndicatorsAlways ) {
5366 mSignatureStateIndicator->setShown( mSignAction->isChecked() );
5367 mEncryptionStateIndicator->setShown( mEncryptAction->isChecked() );
5371 void KMComposeWin::slotAttachmentDragStarted()
5373 kdDebug(5006) << k_funcinfo << endl;
5375 TQStringList filenames;
5376 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++idx ) {
5377 if ( (*it)->isSelected() ) {
5378 KMMessagePart* msgPart = mAtmList.at(idx);
5379 KTempDir * tempDir =
new KTempDir();
5380 tempDir->setAutoDelete(
true );
5381 mTempDirs.insert( tempDir );
5382 const TQString fileName = tempDir->name() +
"/" + msgPart->name();
5383 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(),
5385 false,
false,
false);
5387 url.setPath( fileName );
5388 filenames << url.path();
5391 if ( filenames.isEmpty() )
return;
5393 TQUriDrag *drag =
new TQUriDrag( mAtmListView );
5394 drag->setFileNames( filenames );
5398 void KMComposeWin::recipientEditorSizeHintChanged()
5400 TQTimer::singleShot( 1,
this, TQT_SLOT(setMaximumHeaderSize()) );
5403 void KMComposeWin::setMaximumHeaderSize()
5405 mHeadersArea->setMaximumHeight( mHeadersArea->sizeHint().height() );