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 TDERecentAddress::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 <libtdepim/tdefileio.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 <tdeio/netaccess.h> 74 #include "tdelistboxdialog.h" 76 #include "messagecomposer.h" 77 #include "chiasmuskeyselector.h" 79 #include <kcharsets.h> 80 #include <tdecompletionbox.h> 82 #include <kcombobox.h> 83 #include <tdestdaccel.h> 84 #include <tdepopupmenu.h> 85 #include <kedittoolbar.h> 86 #include <kkeydialog.h> 88 #include <tdefiledialog.h> 90 #include <kinputdialog.h> 91 #include <tdemessagebox.h> 93 #include <tdeio/scheduler.h> 94 #include <tdetempfile.h> 95 #include <tdelocale.h> 96 #include <tdeapplication.h> 97 #include <kstatusbar.h> 98 #include <tdeaction.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" 112 #include <tdespell.h> 113 #include <tdespelldlg.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(TDEGlobalSettings::Completion)),
230 TQT_SLOT(slotCompletionModeChanged(TDEGlobalSettings::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(TDEGlobalSettings::Completion)),
264 TQT_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
265 connect(mEdtCc,TQT_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
266 TQT_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
267 connect(mEdtBcc,TQT_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
268 TQT_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
285 mRecipientsEditor =
new RecipientsEditor( mHeadersArea );
286 connect( mRecipientsEditor,
287 TQT_SIGNAL( completionModeChanged( TDEGlobalSettings::Completion ) ),
288 TQT_SLOT( slotCompletionModeChanged( TDEGlobalSettings::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 TDEConfigGroup 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(TDEGlobalSettings::Completion)),
451 TQT_SLOT(slotCompletionModeChanged(TDEGlobalSettings::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<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.begin();
509 while ( it != mMapAtmLoadData.end() )
511 TDEIO::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( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
696 mEdtReplyTo->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
697 if ( mClassicalRecipients ) {
698 mEdtTo->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
699 mEdtCc->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
700 mEdtBcc->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
703 mRecipientsEditor->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
707 if ( GlobalSettings::self()->useDefaultFonts() ) {
708 mBodyFont = TDEGlobalSettings::generalFont();
709 mFixedFont = TDEGlobalSettings::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 TDEConfigGroupSaver 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(
"TDEToggleAction"))
893 TDEToggleAction *act = (TDEToggleAction *) 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 TDEActionMenu *actActionNowMenu, *actActionLaterMenu;
1233 if (kmkernel->msgSender()->sendImmediate())
1236 ( void )
new TDEAction( i18n(
"&Send Mail"),
"mail-send", CTRL+Key_Return,
1237 TQT_TQOBJECT(
this), TQT_SLOT(slotSendNow()), actionCollection(),
"send_default");
1240 actActionNowMenu =
new TDEActionMenu (i18n(
"&Send Mail Via"),
"mail-send",
1241 actionCollection(),
"send_default_via" );
1243 (void)
new TDEAction (i18n(
"Send &Later"),
"queue", 0, TQT_TQOBJECT(
this),
1244 TQT_SLOT(slotSendLater()), actionCollection(),
"send_alternative");
1245 actActionLaterMenu =
new TDEActionMenu (i18n(
"Send &Later Via"),
"queue",
1246 actionCollection(),
"send_alternative_via" );
1252 (void)
new TDEAction (i18n(
"Send &Later"),
"queue",
1254 TQT_TQOBJECT(
this), TQT_SLOT(slotSendLater()), actionCollection(),
"send_default");
1255 actActionLaterMenu =
new TDEActionMenu (i18n(
"Send &Later Via"),
"queue",
1256 actionCollection(),
"send_default_via" );
1258 ( void )
new TDEAction( i18n(
"&Send Mail"),
"mail-send", 0,
1259 TQT_TQOBJECT(
this), TQT_SLOT(slotSendNow()), actionCollection(),
"send_alternative");
1262 actActionNowMenu =
new TDEActionMenu (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 TDEAction (i18n(
"Save as &Draft"),
"document-save", 0,
1294 TQT_TQOBJECT(
this), TQT_SLOT(slotSaveDraft()),
1295 actionCollection(),
"save_in_drafts");
1296 (void)
new TDEAction (i18n(
"Save as &Template"),
"document-save", 0,
1297 TQT_TQOBJECT(
this), TQT_SLOT(slotSaveTemplate()),
1298 actionCollection(),
"save_in_templates");
1299 (void)
new TDEAction (i18n(
"&Insert File..."),
"document-open", 0,
1300 TQT_TQOBJECT(
this), TQT_SLOT(slotInsertFile()),
1301 actionCollection(),
"insert_file");
1302 mRecentAction =
new TDERecentFilesAction (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 TDEAction (i18n(
"&Address Book"),
"contents",0,
1310 TQT_TQOBJECT(
this), TQT_SLOT(slotAddrBook()),
1311 actionCollection(),
"addressbook");
1312 (void)
new TDEAction (i18n(
"&New Composer"),
"mail-message-new",
1313 TDEStdAccel::shortcut(TDEStdAccel::New),
1314 TQT_TQOBJECT(
this), TQT_SLOT(slotNewComposer()),
1315 actionCollection(),
"new_composer");
1316 (void)
new TDEAction (i18n(
"New Main &Window"),
"window-new", 0,
1317 TQT_TQOBJECT(
this), TQT_SLOT(slotNewMailReader()),
1318 actionCollection(),
"open_mailreader");
1320 if ( !mClassicalRecipients ) {
1321 new TDEAction( i18n(
"Select &Recipients..."), CTRL + Key_L, TQT_TQOBJECT(mRecipientsEditor),
1322 TQT_SLOT( selectRecipients() ), actionCollection(),
"select_recipients" );
1323 new TDEAction( 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(),
"tools-check-spelling");
1345 mPasteQuotation =
new TDEAction (i18n(
"Pa&ste as Quotation"),0,TQT_TQOBJECT(
this),TQT_SLOT( slotPasteClipboardAsQuotation()),
1346 actionCollection(),
"paste_quoted");
1348 (void)
new TDEAction (i18n(
"Paste as Attac&hment"),0,TQT_TQOBJECT(
this),TQT_SLOT( slotPasteClipboardAsAttachment()),
1349 actionCollection(),
"paste_att");
1351 TDEAction * addq =
new TDEAction(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 TDEAction * remq =
new TDEAction(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 TDEAction (i18n(
"Cl&ean Spaces"), 0, TQT_TQOBJECT(
this), TQT_SLOT(slotCleanSpace()),
1363 actionCollection(),
"clean_spaces");
1365 mFixedFontAction =
new TDEToggleAction( 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 TDEToggleAction (i18n(
"&Urgent"), 0,
1373 mRequestMDNAction =
new TDEToggleAction ( i18n(
"&Request Disposition Notification"), 0,
1375 "options_request_mdn");
1376 mRequestMDNAction->setChecked(GlobalSettings::self()->requestMDN());
1378 mEncodingAction =
new TDESelectAction( i18n(
"Se&t Encoding" ),
"charset",
1379 0, TQT_TQOBJECT(
this), TQT_SLOT(slotSetCharset() ),
1380 actionCollection(),
"charsets" );
1381 mWordWrapAction =
new TDEToggleAction (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 TDEToggleAction ( 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 TDEToggleAction( i18n(
"&Automatic Spellchecking" ),
"tools-check-spelling", 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 TDEToggleAction (i18n(
"Formatting (HTML)"), 0, TQT_TQOBJECT(
this),
1408 TQT_SLOT(slotToggleMarkup()),
1409 actionCollection(),
"html");
1411 mAllFieldsAction =
new TDEToggleAction (i18n(
"&All Fields"), 0, TQT_TQOBJECT(
this),
1412 TQT_SLOT(slotView()),
1413 actionCollection(),
"show_all_fields");
1414 mIdentityAction =
new TDEToggleAction (i18n(
"&Identity"), 0, TQT_TQOBJECT(
this),
1415 TQT_SLOT(slotView()),
1416 actionCollection(),
"show_identity");
1417 mDictionaryAction =
new TDEToggleAction (i18n(
"&Dictionary"), 0, TQT_TQOBJECT(
this),
1418 TQT_SLOT(slotView()),
1419 actionCollection(),
"show_dictionary");
1420 mFccAction =
new TDEToggleAction (i18n(
"&Sent-Mail Folder"), 0, TQT_TQOBJECT(
this),
1421 TQT_SLOT(slotView()),
1422 actionCollection(),
"show_fcc");
1423 mTransportAction =
new TDEToggleAction (i18n(
"&Mail Transport"), 0, TQT_TQOBJECT(
this),
1424 TQT_SLOT(slotView()),
1425 actionCollection(),
"show_transport");
1426 mFromAction =
new TDEToggleAction (i18n(
"&From"), 0, TQT_TQOBJECT(
this),
1427 TQT_SLOT(slotView()),
1428 actionCollection(),
"show_from");
1429 mReplyToAction =
new TDEToggleAction (i18n(
"&Reply To"), 0, TQT_TQOBJECT(
this),
1430 TQT_SLOT(slotView()),
1431 actionCollection(),
"show_reply_to");
1432 if ( mClassicalRecipients ) {
1433 mToAction =
new TDEToggleAction (i18n(
"&To"), 0, TQT_TQOBJECT(
this),
1434 TQT_SLOT(slotView()),
1435 actionCollection(),
"show_to");
1436 mCcAction =
new TDEToggleAction (i18n(
"&CC"), 0, TQT_TQOBJECT(
this),
1437 TQT_SLOT(slotView()),
1438 actionCollection(),
"show_cc");
1439 mBccAction =
new TDEToggleAction (i18n(
"&BCC"), 0, TQT_TQOBJECT(
this),
1440 TQT_SLOT(slotView()),
1441 actionCollection(),
"show_bcc");
1443 mSubjectAction =
new TDEToggleAction (i18n(
"S&ubject"), 0, TQT_TQOBJECT(
this),
1444 TQT_SLOT(slotView()),
1445 actionCollection(),
"show_subject");
1448 mAppendSignatureAction =
new TDEAction (i18n(
"Append S&ignature"), 0, TQT_TQOBJECT(
this),
1449 TQT_SLOT(slotAppendSignature()),
1450 actionCollection(),
"append_signature");
1451 mPrependSignatureAction =
new TDEAction (i18n(
"Prepend S&ignature"), 0, TQT_TQOBJECT(
this),
1452 TQT_SLOT(slotPrependSignature()),
1453 actionCollection(),
"prepend_signature");
1455 mInsertSignatureAction =
new TDEAction (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 TDEAction (i18n(
"Attach &Public Key..."), 0, TQT_TQOBJECT(
this),
1460 TQT_SLOT(slotInsertPublicKey()),
1461 actionCollection(),
"attach_public_key");
1462 mAttachMPK =
new TDEAction (i18n(
"Attach &My Public Key"), 0, TQT_TQOBJECT(
this),
1463 TQT_SLOT(slotInsertMyPublicKey()),
1464 actionCollection(),
"attach_my_public_key");
1465 (void)
new TDEAction (i18n(
"&Attach File..."),
"attach",
1466 0, TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFile()),
1467 actionCollection(),
"attach");
1468 mAttachRemoveAction =
new TDEAction (i18n(
"&Remove Attachment"), 0, TQT_TQOBJECT(
this),
1469 TQT_SLOT(slotAttachRemove()),
1470 actionCollection(),
"remove");
1471 mAttachSaveAction =
new TDEAction (i18n(
"&Save Attachment As..."),
"document-save",0,
1472 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachSave()),
1473 actionCollection(),
"attach_save");
1474 mAttachPropertiesAction =
new TDEAction (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 TDEAction (i18n(
"&Spellchecker..."), 0, TQT_TQOBJECT(
this), TQT_SLOT(slotSpellcheckConfig()),
1485 actionCollection(),
"setup_spellchecker");
1487 if ( Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" ) ) {
1488 TDEToggleAction * a =
new TDEToggleAction( 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 TDEToggleAction (i18n(
"&Encrypt Message"),
1501 actionCollection(),
"encrypt_message");
1502 mSignAction =
new TDEToggleAction (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 TDESelectAction( 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 TDESelectAction( 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 TDEFontAction(
"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 TDEFontSizeAction(
"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 TDEToggleAction (i18n(
"Align Left"),
"format-text-direction-ltr", 0,
1584 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignLeft()), actionCollection(),
1586 alignLeftAction->setChecked(
true );
1587 alignRightAction =
new TDEToggleAction (i18n(
"Align Right"),
"format-text-direction-rtl", 0,
1588 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignRight()), actionCollection(),
1590 alignCenterAction =
new TDEToggleAction (i18n(
"Align Center"),
"text_center", 0,
1591 TQT_TQOBJECT(
this), TQT_SLOT(slotAlignCenter()), actionCollection(),
1593 textBoldAction =
new TDEToggleAction( i18n(
"&Bold"),
"format-text-bold", CTRL+Key_B,
1594 TQT_TQOBJECT(
this), TQT_SLOT(slotTextBold()),
1595 actionCollection(),
"format-text-bold");
1596 textItalicAction =
new TDEToggleAction( i18n(
"&Italic"),
"format-text-italic", CTRL+Key_I,
1597 TQT_TQOBJECT(
this), TQT_SLOT(slotTextItalic()),
1598 actionCollection(),
"format-text-italic");
1599 textUnderAction =
new TDEToggleAction( i18n(
"&Underline"),
"format-text-underline", CTRL+Key_U,
1600 TQT_TQOBJECT(
this), TQT_SLOT(slotTextUnder()),
1601 actionCollection(),
"format-text-underline");
1602 actionFormatReset =
new TDEAction( i18n(
"Reset Font Settings" ),
"eraser", 0,
1603 TQT_TQOBJECT(
this), TQT_SLOT( slotFormatReset() ),
1604 actionCollection(),
"format_reset");
1605 actionFormatColor =
new TDEAction( 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 TDEAction* 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 );
1989 if (transport.isEmpty() && !mMsg->originatingAccountName().isEmpty()) {
1990 TQString transportCandidate = mMsg->originatingAccountName();
1991 bool transportFound =
false;
1992 for (
int i = 0; i < mTransport->count(); ++i ) {
1993 if ( mTransport->text(i) == transportCandidate ) {
1994 transportFound =
true;
1995 setTransport(transportCandidate);
2001 if (!mBtnFcc->isChecked())
2003 if (!mMsg->fcc().isEmpty())
2004 setFcc(mMsg->fcc());
2006 setFcc(ident.fcc());
2009 const bool stickyDictionary = mBtnDictionary->isChecked() && !mIgnoreStickyFields;
2010 if ( !stickyDictionary ) {
2011 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
2014 partNode * root = partNode::fromMessage( mMsg );
2016 KMail::ObjectTreeParser otp;
2017 otp.parseObjectTree( root );
2019 KMail::AttachmentCollector ac;
2020 ac.collectAttachmentsFrom( root );
2022 for ( std::vector<partNode*>::const_iterator it = ac.attachments().begin() ; it != ac.attachments().end() ; ++it )
2023 addAttach(
new KMMessagePart( (*it)->msgPart() ) );
2025 mEditor->setText( otp.textualContent() );
2026 mCharset = otp.textualContentCharset();
2027 if ( partNode * n = root->findType( DwMime::kTypeText, DwMime::kSubtypeHtml ) )
2028 if ( partNode * p = n->parentNode() )
2029 if ( p->hasType( DwMime::kTypeMultipart ) &&
2030 p->hasSubType( DwMime::kSubtypeAlternative ) )
2031 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" ) {
2032 toggleMarkup(
true );
2035 mCharset = n->msgPart().charset();
2036 TQCString bodyDecoded = n->msgPart().bodyDecoded();
2039 const TQTextCodec *codec = KMMsgBase::codecForName( mCharset );
2041 mEditor->setText( codec->toUnicode( bodyDecoded ) );
2043 mEditor->setText( TQString::fromLocal8Bit( bodyDecoded ) );
2047 if ( mCharset.isEmpty() )
2048 mCharset = mMsg->charset();
2049 if ( mCharset.isEmpty() )
2050 mCharset = mDefCharset;
2051 setCharset( mCharset );
2054 if ( mMsg->numBodyParts() == 0 && otp.textualContent().isEmpty() ) {
2055 mCharset=mMsg->charset();
2056 if ( mCharset.isEmpty() || mCharset ==
"default" )
2057 mCharset = mDefCharset;
2059 TQCString bodyDecoded = mMsg->bodyDecoded();
2061 if( allowDecryption )
2062 decryptOrStripOffCleartextSignature( bodyDecoded );
2064 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2066 mEditor->setText(codec->toUnicode(bodyDecoded));
2068 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2070 #ifdef BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS 2071 const int num = mMsg->numBodyParts();
2072 kdDebug(5006) <<
"KMComposeWin::setMsg() mMsg->numBodyParts=" 2073 << mMsg->numBodyParts() << endl;
2076 KMMessagePart bodyPart;
2077 int firstAttachment = 0;
2079 mMsg->bodyPart(1, &bodyPart);
2080 if ( bodyPart.typeStr().lower() ==
"text" &&
2081 bodyPart.subtypeStr().lower() ==
"html" ) {
2083 partNode *root = partNode::fromMessage( mMsg );
2084 partNode *node = root->findType( DwMime::kTypeText,
2085 DwMime::kSubtypeHtml );
2086 if ( node && node->parentNode() &&
2087 node->parentNode()->hasType( DwMime::kTypeMultipart ) &&
2088 node->parentNode()->hasSubType( DwMime::kSubtypeAlternative ) ) {
2090 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/html found" << endl;
2091 firstAttachment = 2;
2092 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" )
2093 toggleMarkup(
true );
2095 delete root; root = 0;
2097 if ( firstAttachment == 0 ) {
2098 mMsg->bodyPart(0, &bodyPart);
2099 if ( bodyPart.typeStr().lower() ==
"text" ) {
2101 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/* found" << endl;
2102 firstAttachment = 1;
2106 if ( firstAttachment != 0 )
2108 mCharset = bodyPart.charset();
2109 if ( mCharset.isEmpty() || mCharset ==
"default" )
2110 mCharset = mDefCharset;
2112 TQCString bodyDecoded = bodyPart.bodyDecoded();
2114 if( allowDecryption )
2115 decryptOrStripOffCleartextSignature( bodyDecoded );
2123 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2125 mEditor->setText(codec->toUnicode(bodyDecoded));
2127 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2129 }
else mEditor->setText(
"");
2130 for(
int i = firstAttachment; i < num; ++i )
2132 KMMessagePart *msgPart =
new KMMessagePart;
2133 mMsg->bodyPart(i, msgPart);
2134 TQCString mimeType = msgPart->typeStr().lower() +
'/' 2135 + msgPart->subtypeStr().lower();
2138 if( mimeType !=
"application/pgp-signature" ) {
2143 mCharset=mMsg->charset();
2144 if ( mCharset.isEmpty() || mCharset ==
"default" )
2145 mCharset = mDefCharset;
2147 TQCString bodyDecoded = mMsg->bodyDecoded();
2149 if( allowDecryption )
2150 decryptOrStripOffCleartextSignature( bodyDecoded );
2152 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2154 mEditor->setText(codec->toUnicode(bodyDecoded));
2156 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2159 setCharset(mCharset);
2160 #endif // BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS 2162 if( (GlobalSettings::self()->autoTextSignature()==
"auto") && mayAutoSign ) {
2170 if ( GlobalSettings::self()->prependSignature() ) {
2171 TQTimer::singleShot( 0,
this, TQT_SLOT(slotPrependSignature()) );
2173 TQTimer::singleShot( 0,
this, TQT_SLOT(slotAppendSignature()) );
2177 if ( mMsg->getCursorPos() > 0 ) {
2180 mPreserveUserCursorPosition =
true;
2182 setModified( isModified );
2185 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
2188 mPreventFccOverwrite = ( !newMsg->
fcc().isEmpty() && ident.fcc() != newMsg->
fcc() );
2193 void KMComposeWin::setFcc(
const TQString &idString )
2196 if ( ! idString.isEmpty() && kmkernel->findFolderById( idString ) ) {
2197 mFcc->setFolder( idString );
2199 mFcc->setFolder( kmkernel->sentFolder() );
2205 bool KMComposeWin::isModified()
const 2207 return ( mEditor->isModified() ||
2208 mEdtFrom->edited() ||
2209 ( mEdtReplyTo && mEdtReplyTo->edited() ) ||
2210 ( mEdtTo && mEdtTo->edited() ) ||
2211 ( mEdtCc && mEdtCc->edited() ) ||
2212 ( mEdtBcc && mEdtBcc->edited() ) ||
2213 ( mRecipientsEditor && mRecipientsEditor->isModified() ) ||
2214 mEdtSubject->edited() ||
2216 ( mTransport->lineEdit() && mTransport->lineEdit()->edited() ) );
2221 void KMComposeWin::setModified(
bool modified )
2223 mEditor->setModified( modified );
2225 mEdtFrom->setEdited(
false );
2226 if ( mEdtReplyTo ) mEdtReplyTo->setEdited(
false );
2227 if ( mEdtTo ) mEdtTo->setEdited(
false );
2228 if ( mEdtCc ) mEdtCc->setEdited(
false );
2229 if ( mEdtBcc ) mEdtBcc->setEdited(
false );
2230 if ( mRecipientsEditor ) mRecipientsEditor->clearModified();
2231 mEdtSubject->setEdited(
false );
2232 mAtmModified = false ;
2233 if ( mTransport->lineEdit() )
2234 mTransport->lineEdit()->setEdited(
false );
2240 bool KMComposeWin::queryClose ()
2242 if ( !mEditor->checkExternalEditorFinished() )
2244 if ( kmkernel->shuttingDown() || kapp->sessionSaving() )
2246 if ( mComposer && mComposer->isPerformingSignOperation() )
2249 if ( isModified() ) {
2250 bool istemplate = ( mFolder!=0 && mFolder->isTemplates() );
2251 const TQString savebut = ( istemplate ?
2252 i18n(
"Re&save as Template") :
2253 i18n(
"&Save as Draft") );
2254 const TQString savetext = ( istemplate ?
2255 i18n(
"Resave this message in the Templates folder. " 2256 "It can then be used at a later time.") :
2257 i18n(
"Save this message in the Drafts folder. " 2258 "It can then be edited and sent at a later time.") );
2260 const int rc = KMessageBox::warningYesNoCancel(
this,
2261 i18n(
"Do you want to save the message for later or discard it?"),
2262 i18n(
"Close Composer"),
2263 KGuiItem(savebut,
"document-save", TQString(), savetext),
2264 KStdGuiItem::discard() );
2265 if ( rc == KMessageBox::Cancel )
2267 else if ( rc == KMessageBox::Yes ) {
2282 bool KMComposeWin::userForgotAttachment()
2284 bool checkForForgottenAttachments =
2285 mCheckForForgottenAttachments && GlobalSettings::self()->showForgottenAttachmentWarning();
2287 if ( !checkForForgottenAttachments || ( mAtmList.count() > 0 ) )
2291 TQStringList attachWordsList = GlobalSettings::self()->attachmentKeywords();
2293 if ( attachWordsList.isEmpty() ) {
2295 attachWordsList << TQString::fromLatin1(
"attachment")
2296 << TQString::fromLatin1(
"attached");
2297 if ( TQString::fromLatin1(
"attachment") != i18n(
"attachment") )
2298 attachWordsList << i18n(
"attachment");
2299 if ( TQString::fromLatin1(
"attached") != i18n(
"attached") )
2300 attachWordsList << i18n(
"attached");
2303 TQRegExp rx ( TQString::fromLatin1(
"\\b") +
2304 attachWordsList.join(
"\\b|\\b") +
2305 TQString::fromLatin1(
"\\b") );
2306 rx.setCaseSensitive(
false );
2308 bool gotMatch =
false;
2312 TQString subj = subject();
2313 gotMatch = ( KMMessage::stripOffPrefixes( subj ) == subj )
2314 && ( rx.search( subj ) >= 0 );
2319 TQRegExp quotationRx (
"^([ \\t]*([|>:}#]|[A-Za-z]+>))+");
2320 for (
int i = 0; i < mEditor->numLines(); ++i ) {
2321 TQString line = mEditor->textLine( i );
2322 gotMatch = ( quotationRx.search( line ) < 0 )
2323 && ( rx.search( line ) >= 0 );
2332 int rc = KMessageBox::warningYesNoCancel(
this,
2333 i18n(
"The message you have composed seems to refer to an " 2334 "attached file but you have not attached anything.\n" 2335 "Do you want to attach a file to your message?"),
2336 i18n(
"File Attachment Reminder"),
2337 i18n(
"&Attach File..."),
2338 i18n(
"&Send as Is") );
2339 if ( rc == KMessageBox::Cancel )
2341 if ( rc == KMessageBox::Yes ) {
2350 void KMComposeWin::applyChanges(
bool dontSignNorEncrypt,
bool dontDisable )
2352 kdDebug(5006) <<
"entering KMComposeWin::applyChanges" << endl;
2354 if(!mMsg || mComposer) {
2355 kdDebug(5006) <<
"KMComposeWin::applyChanges() : mMsg == 0!\n" << endl;
2356 emit applyChangesDone(
false );
2361 mComposer =
new MessageComposer(
this );
2362 connect( mComposer, TQT_SIGNAL( done(
bool ) ),
2363 TQT_TQOBJECT(
this), TQT_SLOT( slotComposerDone(
bool ) ) );
2368 if ( !dontDisable ) setEnabled(
false );
2370 mComposer->setDisableBreaking( mDisableBreaking );
2371 mComposer->applyChanges( dontSignNorEncrypt );
2374 void KMComposeWin::slotComposerDone(
bool rc )
2376 deleteAll( mComposedMessages );
2377 mComposedMessages = mComposer->composedMessageList();
2378 emit applyChangesDone( rc );
2386 const KPIM::Identity & KMComposeWin::identity()
const {
2387 return kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
2390 uint KMComposeWin::identityUid()
const {
2391 return mIdentity->currentIdentity();
2394 Kleo::CryptoMessageFormat KMComposeWin::cryptoMessageFormat()
const {
2395 if ( !mCryptoModuleAction )
2396 return Kleo::AutoFormat;
2397 return cb2format( mCryptoModuleAction->currentItem() );
2400 bool KMComposeWin::encryptToSelf()
const {
2402 TDEConfigGroup group( KMKernel::config(),
"Composer" );
2403 return group.readBoolEntry(
"crypto-encrypt-to-self",
true );
2406 bool KMComposeWin::queryExit ()
2412 bool KMComposeWin::addAttach(
const KURL aUrl)
2414 if ( !aUrl.isValid() ) {
2415 KMessageBox::sorry(
this, i18n(
"<qt><p>KMail could not recognize the location of the attachment (%1);</p>" 2416 "<p>you have to specify the full path if you wish to attach a file.</p></qt>" )
2417 .arg( aUrl.prettyURL() ) );
2421 const int maxAttachmentSize = GlobalSettings::maximumAttachmentSize();
2422 const uint maximumAttachmentSizeInByte = maxAttachmentSize*1024*1024;
2423 if ( aUrl.isLocalFile() && TQFileInfo( aUrl.pathOrURL() ).size() > maximumAttachmentSizeInByte ) {
2424 KMessageBox::sorry(
this, i18n(
"<qt><p>Your administrator has disallowed attaching files bigger than %1 MB.</p>" ).arg( maxAttachmentSize ) );
2428 TDEIO::TransferJob *job = TDEIO::get(aUrl);
2429 TDEIO::Scheduler::scheduleJob( job );
2432 ld.data = TQByteArray();
2434 if( !aUrl.fileEncoding().isEmpty() )
2435 ld.encoding = aUrl.fileEncoding().latin1();
2437 mMapAtmLoadData.insert(job, ld);
2438 mAttachJobs[job] = aUrl;
2439 connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
2440 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileResult(TDEIO::Job *)));
2441 connect(job, TQT_SIGNAL(data(TDEIO::Job *,
const TQByteArray &)),
2442 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileData(TDEIO::Job *,
const TQByteArray &)));
2448 void KMComposeWin::addAttach(
const KMMessagePart* msgPart)
2450 mAtmList.append(msgPart);
2453 if (mAtmList.count()==1)
2455 mAtmListView->resize(mAtmListView->width(), 50);
2456 mAtmListView->show();
2461 KMAtmListViewItem *lvi =
new KMAtmListViewItem( mAtmListView );
2462 msgPartToItem(msgPart, lvi);
2463 mAtmItemList.append(lvi);
2466 if ( mTempDir != 0 ) {
2471 connect( lvi, TQT_SIGNAL( compress(
int ) ),
2472 TQT_TQOBJECT(
this), TQT_SLOT( compressAttach(
int ) ) );
2473 connect( lvi, TQT_SIGNAL( uncompress(
int ) ),
2474 TQT_TQOBJECT(
this), TQT_SLOT( uncompressAttach(
int ) ) );
2476 slotUpdateAttachActions();
2481 void KMComposeWin::slotUpdateAttachActions()
2483 int selectedCount = 0;
2484 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
2485 if ( (*it)->isSelected() ) {
2490 mAttachRemoveAction->setEnabled( selectedCount >= 1 );
2491 mAttachSaveAction->setEnabled( selectedCount == 1 );
2492 mAttachPropertiesAction->setEnabled( selectedCount == 1 );
2498 TQString KMComposeWin::prettyMimeType(
const TQString& type )
2500 TQString t = type.lower();
2501 KServiceType::Ptr st = KServiceType::serviceType( t );
2502 return st ? st->comment() : t;
2505 void KMComposeWin::msgPartToItem(
const KMMessagePart* msgPart,
2506 KMAtmListViewItem *lvi,
bool loadDefaults)
2508 assert(msgPart != 0);
2510 if (!msgPart->fileName().isEmpty())
2511 lvi->setText(0, msgPart->fileName());
2513 lvi->setText(0, msgPart->name());
2514 lvi->setText(1, TDEIO::convertSize( msgPart->decodedSize()));
2515 lvi->setText(2, msgPart->contentTransferEncodingStr());
2516 lvi->setText(3, prettyMimeType(msgPart->typeStr() +
"/" + msgPart->subtypeStr()));
2517 lvi->setAttachmentSize(msgPart->decodedSize());
2519 if ( loadDefaults ) {
2520 if( canSignEncryptAttachments() ) {
2521 lvi->enableCryptoCBs(
true );
2522 lvi->setEncrypt( mEncryptAction->isChecked() );
2523 lvi->setSign( mSignAction->isChecked() );
2525 lvi->enableCryptoCBs(
false );
2532 void KMComposeWin::removeAttach(
const TQString &aUrl)
2535 KMMessagePart* msgPart;
2536 for(idx=0,msgPart=mAtmList.first(); msgPart;
2537 msgPart=mAtmList.next(),idx++) {
2538 if (msgPart->name() == aUrl) {
2547 void KMComposeWin::removeAttach(
int idx)
2549 mAtmModified =
true;
2551 KMAtmListViewItem *item =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( idx ) );
2552 if ( item->itemBelow() )
2553 mAtmSelectNew = item->itemBelow();
2554 else if ( item->itemAbove() )
2555 mAtmSelectNew = item->itemAbove();
2557 mAtmList.remove(idx);
2558 delete mAtmItemList.take(idx);
2560 if( mAtmList.isEmpty() )
2562 mAtmListView->hide();
2563 mAtmListView->setMinimumSize(0, 0);
2570 bool KMComposeWin::encryptFlagOfAttachment(
int idx)
2572 return (
int)(mAtmItemList.count()) > idx
2573 ? static_cast<KMAtmListViewItem*>( mAtmItemList.at( idx ) )->isEncrypt()
2579 bool KMComposeWin::signFlagOfAttachment(
int idx)
2581 return (
int)(mAtmItemList.count()) > idx
2582 ? ((KMAtmListViewItem*)(mAtmItemList.at( idx )))->isSign()
2588 void KMComposeWin::addrBookSelInto()
2590 if ( mClassicalRecipients ) {
2591 if ( GlobalSettings::self()->addresseeSelectorType() ==
2592 GlobalSettings::EnumAddresseeSelectorType::New ) {
2593 addrBookSelIntoNew();
2595 addrBookSelIntoOld();
2598 kdWarning() <<
"To be implemented: call recipients picker." << endl;
2602 void KMComposeWin::addrBookSelIntoOld()
2604 AddressesDialog dlg(
this );
2609 if ( !txt.isEmpty() ) {
2610 lst = KPIM::splitEmailAddrList( txt );
2611 dlg.setSelectedTo( lst );
2614 txt = mEdtCc->text();
2615 if ( !txt.isEmpty() ) {
2616 lst = KPIM::splitEmailAddrList( txt );
2617 dlg.setSelectedCC( lst );
2620 txt = mEdtBcc->text();
2621 if ( !txt.isEmpty() ) {
2622 lst = KPIM::splitEmailAddrList( txt );
2623 dlg.setSelectedBCC( lst );
2626 dlg.setRecentAddresses( RecentAddresses::self( KMKernel::config() )->tdeabcAddresses() );
2628 if (dlg.exec()==TQDialog::Rejected)
return;
2630 mEdtTo->setText( dlg.to().join(
", ") );
2631 mEdtTo->setEdited(
true );
2633 mEdtCc->setText( dlg.cc().join(
", ") );
2634 mEdtCc->setEdited(
true );
2636 mEdtBcc->setText( dlg.bcc().join(
", ") );
2637 mEdtBcc->setEdited(
true );
2640 if ( !mEdtBcc->text().isEmpty() ) {
2641 mShowHeaders |= HDR_BCC;
2642 rethinkFields(
false );
2646 void KMComposeWin::addrBookSelIntoNew()
2648 AddresseeEmailSelection selection;
2650 AddresseeSelectorDialog dlg( &selection );
2656 if ( !txt.isEmpty() ) {
2657 lst = KPIM::splitEmailAddrList( txt );
2658 selection.setSelectedTo( lst );
2661 txt = mEdtCc->text();
2662 if ( !txt.isEmpty() ) {
2663 lst = KPIM::splitEmailAddrList( txt );
2664 selection.setSelectedCC( lst );
2667 txt = mEdtBcc->text();
2668 if ( !txt.isEmpty() ) {
2669 lst = KPIM::splitEmailAddrList( txt );
2670 selection.setSelectedBCC( lst );
2673 if (dlg.exec()==TQDialog::Rejected)
return;
2675 TQStringList list = selection.to() + selection.toDistributionLists();
2676 mEdtTo->setText( list.join(
", ") );
2677 mEdtTo->setEdited(
true );
2679 list = selection.cc() + selection.ccDistributionLists();
2680 mEdtCc->setText( list.join(
", ") );
2681 mEdtCc->setEdited(
true );
2683 list = selection.bcc() + selection.bccDistributionLists();
2684 mEdtBcc->setText( list.join(
", ") );
2685 mEdtBcc->setEdited(
true );
2688 if ( !mEdtBcc->text().isEmpty() ) {
2689 mShowHeaders |= HDR_BCC;
2690 rethinkFields(
false );
2696 void KMComposeWin::setCharset(
const TQCString& aCharset,
bool forceDefault)
2698 if ((forceDefault && GlobalSettings::self()->forceReplyCharset()) || aCharset.isEmpty())
2699 mCharset = mDefCharset;
2701 mCharset = aCharset.lower();
2703 if ( mCharset.isEmpty() || mCharset ==
"default" )
2704 mCharset = mDefCharset;
2708 mEncodingAction->setCurrentItem( 0 );
2712 TQStringList encodings = mEncodingAction->items();
2714 bool charsetFound =
false;
2715 for ( TQStringList::Iterator it = encodings.begin(); it != encodings.end();
2718 if (i > 0 && ((mCharset ==
"us-ascii" && i == 1) ||
2719 (i != 1 && TDEGlobal::charsets()->codecForName(
2720 TDEGlobal::charsets()->encodingForName(*it))
2721 == TDEGlobal::charsets()->codecForName(mCharset))))
2723 mEncodingAction->setCurrentItem( i );
2725 charsetFound =
true;
2729 if (!aCharset.isEmpty() && !charsetFound) setCharset(
"",
true);
2734 void KMComposeWin::slotAddrBook()
2736 KAddrBookExternal::openAddressBook(
this);
2741 void KMComposeWin::slotAddrBookFrom()
2748 void KMComposeWin::slotAddrBookReplyTo()
2755 void KMComposeWin::slotAddrBookTo()
2761 void KMComposeWin::slotAttachFile()
2769 KURL recentURL = KFileDialog::getStartURL( TQString(), recent );
2770 if ( !recentURL.url().isEmpty() &&
2771 !TDEIO::NetAccess::exists( recentURL,
true,
this ) ) {
2772 recentURL = KURL( TQDir::homeDirPath() );
2775 KFileDialog fdlg( recentURL.url(), TQString(),
this, 0, true );
2776 fdlg.setOperationMode( KFileDialog::Other );
2777 fdlg.setCaption( i18n(
"Attach File" ) );
2778 fdlg.okButton()->setGuiItem( KGuiItem( i18n(
"&Attach" ),
"document-open" ) );
2779 fdlg.setMode( KFile::Files );
2781 KURL::List files = fdlg.selectedURLs();
2783 for (KURL::List::Iterator it = files.begin(); it != files.end(); ++it)
2789 void KMComposeWin::slotAttachFileData(TDEIO::Job *job,
const TQByteArray &data)
2791 TQMap<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2792 assert(it != mMapAtmLoadData.end());
2793 TQBuffer buff((*it).data);
2794 buff.open(IO_WriteOnly | IO_Append);
2795 buff.writeBlock(data.data(), data.size());
2801 void KMComposeWin::slotAttachFileResult(TDEIO::Job *job)
2803 TQMap<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2804 assert(it != mMapAtmLoadData.end());
2806 TQMap<TDEIO::Job*, KURL>::iterator jit = mAttachJobs.find(job);
2807 bool attachURLfound = (jit != mAttachJobs.end());
2810 attachURL = jit.data();
2811 mAttachJobs.remove(jit);
2815 mMapAtmLoadData.remove(it);
2816 job->showErrorDialog();
2818 emit attachmentAdded(attachURL,
false);
2823 (*it).data.resize((*it).data.size() + 1);
2824 (*it).data[(*it).data.size() - 1] =
'\0';
2825 if (
const TQTextCodec * codec = TDEGlobal::charsets()->codecForName((*it).encoding) )
2826 mEditor->insert( codec->toUnicode( (*it).data ) );
2828 mEditor->insert( TQString::fromLocal8Bit( (*it).data ) );
2829 mMapAtmLoadData.remove(it);
2831 emit attachmentAdded(attachURL,
true);
2834 TQCString partCharset;
2835 if ( !( *it ).url.fileEncoding().isEmpty() ) {
2836 partCharset = TQCString( ( *it ).url.fileEncoding().latin1() );
2839 TDELocale *loc = TDEGlobal::locale();
2840 ed.setAutoDetectLanguage( EncodingDetector::scriptForLanguageCode ( loc->language() ) );
2843 if ( partCharset.isEmpty() )
2844 partCharset = mCharset;
2847 KMMessagePart* msgPart;
2850 TQString name( (*it).url.fileName() );
2852 TQString mimeType =
static_cast<TDEIO::MimetypeJob*
>(job)->mimetype();
2854 if ( name.isEmpty() ) {
2857 if( mimeType ==
"text/html" )
2858 name =
"index.html";
2861 TQStringList patterns( KMimeType::mimeType( mimeType )->patterns() );
2863 if( !patterns.isEmpty() ) {
2865 int i = ext.findRev(
'.' );
2871 name = TQString(
"unknown") += ext;
2875 name.truncate( 256 );
2877 TQCString encoding = KMMsgBase::autoDetectCharset(partCharset,
2879 if ( encoding.isEmpty() )
2883 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
2884 encName = KMMsgBase::encodeRFC2047String( name, encoding );
2886 encName = KMMsgBase::encodeRFC2231String( name, encoding );
2887 bool RFC2231encoded =
false;
2888 if ( !GlobalSettings::self()->outlookCompatibleAttachments() )
2889 RFC2231encoded = name != TQString( encName );
2892 msgPart =
new KMMessagePart;
2893 msgPart->setName(name);
2894 TQValueList<int> allowedCTEs;
2895 if ( mimeType ==
"message/rfc822" ) {
2896 msgPart->setMessageBody( (*it).data );
2897 allowedCTEs << DwMime::kCte7bit;
2898 allowedCTEs << DwMime::kCte8bit;
2900 msgPart->setBodyAndGuessCte((*it).data, allowedCTEs,
2901 !kmkernel->msgSender()->sendQuotedPrintable());
2902 kdDebug(5006) <<
"autodetected cte: " << msgPart->cteStr() << endl;
2904 int slash = mimeType.find(
'/' );
2906 slash = mimeType.length();
2907 msgPart->setTypeStr( mimeType.left( slash ).latin1() );
2908 msgPart->setSubtypeStr( mimeType.mid( slash + 1 ).latin1() );
2909 msgPart->setContentDisposition(TQCString(
"attachment;\n\tfilename")
2910 + ( RFC2231encoded ?
"*=" + encName :
"=\"" + encName +
'"' ) );
2912 mMapAtmLoadData.remove(it);
2914 if ( msgPart->typeStr().lower() ==
"text" ) {
2915 msgPart->setCharset(partCharset);
2919 TDEConfigGroup composer(KMKernel::config(),
"Composer");
2920 if ( GlobalSettings::self()->showMessagePartDialogOnAttach() ) {
2924 for ( TQValueListConstIterator<int> it = allowedCTEs.begin() ;
2925 it != allowedCTEs.end() ; ++it )
2927 case DwMime::kCteBase64: encodings |= KMMsgPartDialog::Base64;
break;
2928 case DwMime::kCteQp: encodings |= KMMsgPartDialog::QuotedPrintable;
break;
2929 case DwMime::kCte7bit: encodings |= KMMsgPartDialog::SevenBit;
break;
2930 case DwMime::kCte8bit: encodings |= KMMsgPartDialog::EightBit;
break;
2933 dlg.setShownEncodings( encodings );
2934 dlg.setMsgPart(msgPart);
2939 emit attachmentAdded(attachURL,
false);
2943 mAtmModified =
true;
2949 emit attachmentAdded(attachURL,
true);
2954 void KMComposeWin::slotInsertFile()
2956 KFileDialog fdlg(TQString(), TQString(),
this, 0,
true);
2957 fdlg.setOperationMode( KFileDialog::Opening );
2958 fdlg.okButton()->setText(i18n(
"&Insert"));
2959 fdlg.setCaption(i18n(
"Insert File"));
2960 fdlg.toolBar()->insertCombo(KMMsgBase::supportedEncodings(
false), 4711,
2962 KComboBox *combo = fdlg.toolBar()->getCombo(4711);
2963 for (
int i = 0; i < combo->count(); i++)
2964 if (TDEGlobal::charsets()->codecForName(TDEGlobal::charsets()->
2965 encodingForName(combo->text(i)))
2966 == TQTextCodec::codecForLocale()) combo->setCurrentItem(i);
2967 if (!fdlg.exec())
return;
2969 KURL u = fdlg.selectedURL();
2970 mRecentAction->addURL(u);
2973 TDEConfig *config = KMKernel::config();
2974 TDEConfigGroupSaver saver( config,
"Composer" );
2975 TQString encoding = TDEGlobal::charsets()->encodingForName(combo->currentText()).latin1();
2976 TQStringList urls = config->readListEntry(
"recent-urls" );
2977 TQStringList encodings = config->readListEntry(
"recent-encodings" );
2980 uint mMaxRecentFiles = 30;
2981 while (urls.count() > mMaxRecentFiles)
2982 urls.erase( urls.fromLast() );
2983 while (encodings.count() > mMaxRecentFiles)
2984 encodings.erase( encodings.fromLast() );
2986 if (urls.count() != encodings.count()) {
2990 urls.prepend( u.prettyURL() );
2991 encodings.prepend( encoding );
2992 config->writeEntry(
"recent-urls", urls );
2993 config->writeEntry(
"recent-encodings", encodings );
2994 mRecentAction->saveEntries( config );
2996 slotInsertRecentFile(u);
3001 void KMComposeWin::slotInsertRecentFile(
const KURL& u)
3003 if (u.fileName().isEmpty())
return;
3005 TDEIO::Job *job = TDEIO::get(u);
3008 ld.data = TQByteArray();
3012 TDEConfig *config = KMKernel::config();
3013 TDEConfigGroupSaver saver( config,
"Composer" );
3014 TQStringList urls = config->readListEntry(
"recent-urls" );
3015 TQStringList encodings = config->readListEntry(
"recent-encodings" );
3016 int index = urls.findIndex( u.prettyURL() );
3018 TQString encoding = encodings[ index ];
3019 ld.encoding = encoding.latin1();
3022 mMapAtmLoadData.insert(job, ld);
3023 connect(job, TQT_SIGNAL(result(TDEIO::Job *)),
3024 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileResult(TDEIO::Job *)));
3025 connect(job, TQT_SIGNAL(data(TDEIO::Job *,
const TQByteArray &)),
3026 TQT_TQOBJECT(
this), TQT_SLOT(slotAttachFileData(TDEIO::Job *,
const TQByteArray &)));
3031 void KMComposeWin::slotSetCharset()
3033 if (mEncodingAction->currentItem() == 0)
3035 mAutoCharset =
true;
3038 mAutoCharset =
false;
3040 mCharset = TDEGlobal::charsets()->encodingForName( mEncodingAction->
3041 currentText() ).latin1();
3046 void KMComposeWin::slotSelectCryptoModule(
bool init )
3049 setModified(
true );
3051 if( canSignEncryptAttachments() ) {
3053 if( 0 == mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3056 if( !mAtmList.isEmpty() ) {
3057 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3059 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3060 lvi->setSign( mSignAction->isChecked() );
3061 lvi->setEncrypt( mEncryptAction->isChecked() );
3066 for(
int col=0; col < mAtmColEncrypt; col++ )
3067 totalWidth += mAtmListView->columnWidth( col );
3068 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3073 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3074 int newWidth = mAtmListView->columnWidth( col ) * reducedTotalWidth
3076 mAtmListView->setColumnWidth( col, newWidth );
3077 usedWidth += newWidth;
3082 mAtmListView->setColumnWidth( mAtmColEncrypt-1,
3083 reducedTotalWidth - usedWidth );
3084 mAtmListView->setColumnWidth( mAtmColEncrypt, mAtmEncryptColWidth );
3085 mAtmListView->setColumnWidth( mAtmColSign, mAtmSignColWidth );
3086 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3088 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3089 lvi->enableCryptoCBs(
true );
3094 if( 0 != mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3095 mAtmEncryptColWidth = mAtmListView->columnWidth( mAtmColEncrypt );
3096 mAtmSignColWidth = mAtmListView->columnWidth( mAtmColSign );
3099 for(
int col=0; col < mAtmListView->columns(); col++ )
3100 totalWidth += mAtmListView->columnWidth( col );
3101 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3106 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3107 int newWidth = mAtmListView->columnWidth( col ) * totalWidth
3108 / reducedTotalWidth;
3109 mAtmListView->setColumnWidth( col, newWidth );
3110 usedWidth += newWidth;
3115 mAtmListView->setColumnWidth( mAtmColEncrypt-1, totalWidth - usedWidth );
3116 mAtmListView->setColumnWidth( mAtmColEncrypt, 0 );
3117 mAtmListView->setColumnWidth( mAtmColSign, 0 );
3118 for( KMAtmListViewItem* lvi = static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3120 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3121 lvi->enableCryptoCBs(
false );
3127 static void showExportError( TQWidget * w,
const GpgME::Error & err ) {
3129 const TQString msg = i18n(
"<qt><p>An error occurred while trying to export " 3130 "the key from the backend:</p>" 3131 "<p><b>%1</b></p></qt>")
3132 .arg( TQString::fromLocal8Bit( err.asString() ) );
3133 KMessageBox::error( w, msg, i18n(
"Key Export Failed") );
3138 void KMComposeWin::slotInsertMyPublicKey()
3142 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() ).pgpEncryptionKey();
3143 if ( !mFingerprint.isEmpty() )
3144 startPublicKeyExport();
3147 void KMComposeWin::startPublicKeyExport() {
3148 if ( mFingerprint.isEmpty() || !Kleo::CryptoBackendFactory::instance()->openpgp() )
3150 Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->openpgp()->publicKeyExportJob(
true );
3153 connect( job, TQT_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
3154 this, TQT_SLOT(slotPublicKeyExportResult(
const GpgME::Error&,
const TQByteArray&)) );
3156 const GpgME::Error err = job->start( mFingerprint );
3158 showExportError(
this, err );
3160 (
void)
new Kleo::ProgressDialog( job, i18n(
"Exporting key..."),
this );
3163 void KMComposeWin::slotPublicKeyExportResult(
const GpgME::Error & err,
const TQByteArray & keydata ) {
3165 showExportError(
this, err );
3170 KMMessagePart * msgPart =
new KMMessagePart();
3171 msgPart->setName( i18n(
"OpenPGP key 0x%1").arg( mFingerprint ) );
3172 msgPart->setTypeStr(
"application");
3173 msgPart->setSubtypeStr(
"pgp-keys");
3174 TQValueList<int> dummy;
3175 msgPart->setBodyAndGuessCte(keydata, dummy,
false);
3176 msgPart->setContentDisposition(
"attachment;\n\tfilename=0x" + TQCString( mFingerprint.latin1() ) +
".asc" );
3184 void KMComposeWin::slotInsertPublicKey()
3186 Kleo::KeySelectionDialog dlg( i18n(
"Attach Public OpenPGP Key"),
3187 i18n(
"Select the public key which should " 3189 std::vector<GpgME::Key>(),
3190 Kleo::KeySelectionDialog::PublicKeys|Kleo::KeySelectionDialog::OpenPGPKeys,
3193 this,
"attach public key selection dialog" );
3194 if ( dlg.exec() != TQDialog::Accepted )
3197 mFingerprint = dlg.fingerprint();
3198 startPublicKeyExport();
3203 void KMComposeWin::slotAttachPopupMenu(TQListViewItem *,
const TQPoint &,
int)
3207 mAttachMenu =
new TQPopupMenu(
this);
3209 mOpenId = mAttachMenu->insertItem(i18n(
"to open",
"Open"),
this,
3210 TQT_SLOT(slotAttachOpen()));
3211 mOpenWithId = mAttachMenu->insertItem(i18n(
"Open With..."),
this,
3212 TQT_SLOT(slotAttachOpenWith()));
3213 mViewId = mAttachMenu->insertItem(i18n(
"to view",
"View"),
this,
3214 TQT_SLOT(slotAttachView()));
3215 mEditId = mAttachMenu->insertItem( i18n(
"Edit"),
this, TQT_SLOT(slotAttachEdit()) );
3216 mEditWithId = mAttachMenu->insertItem( i18n(
"Edit With..."),
this,
3217 TQT_SLOT(slotAttachEditWith()) );
3218 mRemoveId = mAttachMenu->insertItem(i18n(
"Remove"),
this, TQT_SLOT(slotAttachRemove()));
3219 mSaveAsId = mAttachMenu->insertItem( SmallIconSet(
"document-save-as"), i18n(
"Save As..."),
this,
3220 TQT_SLOT( slotAttachSave() ) );
3221 mPropertiesId = mAttachMenu->insertItem( i18n(
"Properties"),
this,
3222 TQT_SLOT( slotAttachProperties() ) );
3223 mAttachMenu->insertSeparator();
3224 mAttachMenu->insertItem(i18n(
"Add Attachment..."),
this, TQT_SLOT(slotAttachFile()));
3227 int selectedCount = 0;
3228 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
3229 if ( (*it)->isSelected() ) {
3234 mAttachMenu->setItemEnabled( mOpenId, selectedCount > 0 );
3235 mAttachMenu->setItemEnabled( mOpenWithId, selectedCount > 0 );
3236 mAttachMenu->setItemEnabled( mViewId, selectedCount > 0 );
3237 mAttachMenu->setItemEnabled( mEditId, selectedCount == 1 );
3238 mAttachMenu->setItemEnabled( mEditWithId, selectedCount == 1 );
3239 mAttachMenu->setItemEnabled( mRemoveId, selectedCount > 0 );
3240 mAttachMenu->setItemEnabled( mSaveAsId, selectedCount == 1 );
3241 mAttachMenu->setItemEnabled( mPropertiesId, selectedCount == 1 );
3243 mAttachMenu->popup(TQCursor::pos());
3247 int KMComposeWin::currentAttachmentNum()
3250 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i )
3251 if ( *it == mAtmListView->currentItem() )
3257 void KMComposeWin::slotAttachProperties()
3259 int idx = currentAttachmentNum();
3261 if (idx < 0)
return;
3263 KMMessagePart* msgPart = mAtmList.at(idx);
3266 dlg.setMsgPart(msgPart);
3267 KMAtmListViewItem* listItem = (KMAtmListViewItem*)(mAtmItemList.at(idx));
3268 if( canSignEncryptAttachments() && listItem ) {
3269 dlg.setCanSign(
true );
3270 dlg.setCanEncrypt(
true );
3271 dlg.setSigned( listItem->isSign() );
3272 dlg.setEncrypted( listItem->isEncrypt() );
3274 dlg.setCanSign(
false );
3275 dlg.setCanEncrypt(
false );
3279 mAtmModified =
true;
3282 msgPartToItem(msgPart, listItem);
3283 if( canSignEncryptAttachments() ) {
3284 listItem->setSign( dlg.isSigned() );
3285 listItem->setEncrypt( dlg.isEncrypted() );
3292 void KMComposeWin::compressAttach(
int idx )
3294 if (idx < 0)
return;
3297 for ( i = 0; i < mAtmItemList.count(); ++i )
3298 if ( mAtmItemList.at( i )->itemPos() == idx )
3301 if ( i > mAtmItemList.count() )
3304 KMMessagePart* msgPart;
3305 msgPart = mAtmList.at( i );
3307 TQBuffer dev( array );
3308 KZip zip( &TQT_TQIODEVICE_OBJECT(dev) );
3309 TQByteArray decoded = msgPart->bodyDecodedBinary();
3310 if ( ! zip.open( IO_WriteOnly ) ) {
3311 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3312 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3316 zip.setCompression( KZip::DeflateCompression );
3317 if ( ! zip.writeFile( msgPart->name(),
"",
"", decoded.size(),
3318 decoded.data() ) ) {
3319 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3320 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3324 if ( array.size() >= decoded.size() ) {
3325 if ( KMessageBox::questionYesNo(
this, i18n(
"The compressed file is larger " 3326 "than the original. Do you want to keep the original one?" ), TQString(), i18n(
"Keep"), i18n(
"Compress") )
3327 == KMessageBox::Yes ) {
3328 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3332 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedCodec(
3333 msgPart->cteStr() );
3335 msgPart->setCteStr(
"base64" );
3336 msgPart->setBodyEncodedBinary( array );
3337 TQString name = msgPart->name() +
".zip";
3339 msgPart->setName( name );
3341 TQCString cDisp =
"attachment;";
3342 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3344 kdDebug(5006) <<
"encoding: " << encoding << endl;
3345 if ( encoding.isEmpty() ) encoding =
"utf-8";
3346 kdDebug(5006) <<
"encoding after: " << encoding << endl;
3348 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3349 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3351 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3353 cDisp +=
"\n\tfilename";
3354 if ( name != TQString( encName ) )
3355 cDisp +=
"*=" + encName;
3357 cDisp +=
"=\"" + encName +
'"';
3358 msgPart->setContentDisposition( cDisp );
3360 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedMimeType(
3361 msgPart->typeStr(), msgPart->subtypeStr() );
3362 msgPart->setTypeStr(
"application" );
3363 msgPart->setSubtypeStr(
"x-zip" );
3365 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) );
3366 msgPartToItem( msgPart, listItem,
false );
3371 void KMComposeWin::uncompressAttach(
int idx )
3373 if (idx < 0)
return;
3376 for ( i = 0; i < mAtmItemList.count(); ++i )
3377 if ( mAtmItemList.at( i )->itemPos() == idx )
3380 if ( i > mAtmItemList.count() )
3383 KMMessagePart* msgPart;
3384 msgPart = mAtmList.at( i );
3386 TQBuffer dev( msgPart->bodyDecodedBinary() );
3387 KZip zip( &TQT_TQIODEVICE_OBJECT(dev) );
3388 TQByteArray decoded;
3390 decoded = msgPart->bodyDecodedBinary();
3391 if ( ! zip.open( IO_ReadOnly ) ) {
3392 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3393 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3396 const KArchiveDirectory *dir = zip.directory();
3398 KZipFileEntry *entry;
3399 if ( dir->entries().count() != 1 ) {
3400 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3401 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3404 entry = (KZipFileEntry*)dir->entry( dir->entries()[0] );
3407 static_cast<KMAtmListViewItem*>( mAtmItemList.at(i) )->uncompressedCodec() );
3409 msgPart->setBodyEncodedBinary( entry->data() );
3410 TQString name = entry->name();
3411 msgPart->setName( name );
3415 TQCString cDisp =
"attachment;";
3416 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3418 if ( encoding.isEmpty() ) encoding =
"utf-8";
3421 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3422 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3424 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3426 cDisp +=
"\n\tfilename";
3427 if ( name != TQString( encName ) )
3428 cDisp +=
"*=" + encName;
3430 cDisp +=
"=\"" + encName +
'"';
3431 msgPart->setContentDisposition( cDisp );
3433 TQCString type, subtype;
3434 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->uncompressedMimeType( type,
3437 msgPart->setTypeStr( type );
3438 msgPart->setSubtypeStr( subtype );
3440 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>(mAtmItemList.at( i ));
3441 msgPartToItem( msgPart, listItem,
false );
3446 void KMComposeWin::slotAttachView()
3449 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3450 if ( (*it)->isSelected() ) {
3456 void KMComposeWin::slotAttachOpen()
3459 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3460 if ( (*it)->isSelected() ) {
3461 openAttach( i,
false );
3467 void KMComposeWin::slotAttachOpenWith()
3470 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3471 if ( (*it)->isSelected() ) {
3472 openAttach( i,
true );
3477 void KMComposeWin::slotAttachEdit()
3480 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3481 if ( (*it)->isSelected() ) {
3482 editAttach( i,
false );
3487 void KMComposeWin::slotAttachEditWith()
3490 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3491 if ( (*it)->isSelected() ) {
3492 editAttach( i,
true );
3498 bool KMComposeWin::inlineSigningEncryptionSelected() {
3499 if ( !mSignAction->isChecked() && !mEncryptAction->isChecked() )
3501 return cryptoMessageFormat() == Kleo::InlineOpenPGPFormat;
3505 void KMComposeWin::viewAttach(
int index )
3508 KMMessagePart* msgPart;
3509 msgPart = mAtmList.at(index);
3510 pname = msgPart->name().stripWhiteSpace();
3511 if (pname.isEmpty()) pname=msgPart->contentDescription();
3512 if (pname.isEmpty()) pname=
"unnamed";
3514 KTempFile* atmTempFile =
new KTempFile();
3515 mAtmTempList.append( atmTempFile );
3516 atmTempFile->setAutoDelete(
true );
3517 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3519 KMReaderMainWin *win =
new KMReaderMainWin(msgPart,
false,
3520 atmTempFile->name(), pname, mCharset );
3525 void KMComposeWin::openAttach(
int index,
bool with )
3527 KMMessagePart* msgPart = mAtmList.at(index);
3528 const TQString contentTypeStr =
3529 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3531 KMimeType::Ptr mimetype;
3532 mimetype = KMimeType::mimeType( contentTypeStr );
3534 KTempFile* atmTempFile =
new KTempFile();
3535 mAtmTempList.append( atmTempFile );
3536 const bool autoDelete =
true;
3537 atmTempFile->setAutoDelete( autoDelete );
3540 url.setPath( atmTempFile->name() );
3542 KPIM::kByteArrayToFile( msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3544 if ( ::chmod( TQFile::encodeName( atmTempFile->name() ), S_IRUSR ) != 0) {
3545 TQFile::remove(url.path());
3549 KService::Ptr offer =
3550 KServiceTypeProfile::preferredService( mimetype->name(),
"Application" );
3552 if ( with || !offer || mimetype->name() ==
"application/octet-stream" ) {
3553 if ( ( !KRun::displayOpenWithDialog( url, autoDelete ) ) && autoDelete ) {
3554 TQFile::remove(url.path());
3558 if ( ( !KRun::run( *offer, url, autoDelete ) ) && autoDelete ) {
3559 TQFile::remove( url.path() );
3564 void KMComposeWin::editAttach(
int index,
bool openWith)
3566 KMMessagePart* msgPart = mAtmList.at(index);
3567 const TQString contentTypeStr =
3568 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3570 KTempFile* atmTempFile =
new KTempFile();
3571 mAtmTempList.append( atmTempFile );
3572 atmTempFile->setAutoDelete(
true );
3573 atmTempFile->file()->writeBlock( msgPart->bodyDecodedBinary() );
3574 atmTempFile->file()->flush();
3579 TQT_TQOBJECT(
this), this );
3581 if ( watcher->start() ) {
3582 mEditorMap.insert( watcher, msgPart );
3583 mEditorTempFiles.insert( watcher, atmTempFile );
3588 void KMComposeWin::slotAttachSave()
3590 KMMessagePart* msgPart;
3591 TQString fileName, pname;
3592 int idx = currentAttachmentNum();
3594 if (idx < 0)
return;
3596 msgPart = mAtmList.at(idx);
3597 pname = msgPart->name();
3598 if (pname.isEmpty()) pname=
"unnamed";
3600 KURL url = KFileDialog::getSaveURL(pname, TQString(), 0, i18n(
"Save Attachment As"));
3605 kmkernel->byteArrayToRemoteFile(msgPart->bodyDecodedBinary(), url);
3610 void KMComposeWin::slotAttachRemove()
3613 bool attachmentRemoved =
false;
3615 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ) {
3616 if ( (*it)->isSelected() ) {
3618 attachmentRemoved =
true;
3626 if ( attachmentRemoved ) {
3627 setModified(
true );
3628 slotUpdateAttachActions();
3629 if ( mAtmSelectNew ) {
3630 mAtmListView->setSelected( mAtmSelectNew,
true );
3631 mAtmListView->setCurrentItem( mAtmSelectNew );
3637 void KMComposeWin::slotFind()
3642 void KMComposeWin::slotSearchAgain()
3644 mEditor->repeatSearch();
3648 void KMComposeWin::slotReplace()
3654 void KMComposeWin::slotUpdateFont()
3656 kdDebug() <<
"KMComposeWin::slotUpdateFont " << endl;
3657 if ( ! mFixedFontAction ) {
3660 mEditor->setFont( mFixedFontAction->isChecked() ? mFixedFont : mBodyFont );
3663 TQString KMComposeWin::quotePrefixName()
const 3668 int languageNr = GlobalSettings::self()->replyCurrentLanguage();
3669 ReplyPhrases replyPhrases( TQString::number(languageNr) );
3670 replyPhrases.readConfig();
3671 TQString quotePrefix = msg()->formatString(
3672 replyPhrases.indentPrefix() );
3674 quotePrefix = msg()->formatString(quotePrefix);
3678 void KMComposeWin::slotPasteClipboardAsQuotation()
3680 if( mEditor->hasFocus() && msg() )
3682 TQString s = TQApplication::clipboard()->text();
3684 mEditor->insert(addQuotesToText(s));
3688 void KMComposeWin::slotPasteClipboardAsAttachment()
3690 KURL url( TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3691 if ( url.isValid() ) {
3692 addAttach(TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3696 TQMimeSource *mimeSource = TQApplication::clipboard()->data();
3697 if ( TQImageDrag::canDecode(mimeSource) ) {
3698 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3702 TQString attName = KInputDialog::getText(
"KMail", i18n(
"Name of the attachment:"), TQString(), &ok,
this );
3705 KMMessagePart *msgPart =
new KMMessagePart;
3706 msgPart->setName(attName);
3707 TQValueList<int> dummy;
3708 msgPart->setBodyAndGuessCte(TQCString(TQApplication::clipboard()->text().latin1()), dummy,
3709 kmkernel->msgSender()->sendQuotedPrintable());
3714 void KMComposeWin::slotAddQuotes()
3716 if( mEditor->hasFocus() && msg() )
3722 if ( mEditor->hasMarkedText() ) {
3723 TQString s = mEditor->markedText();
3725 mEditor->insert(addQuotesToText(s));
3727 int l = mEditor->currentLine();
3728 int c = mEditor->currentColumn();
3729 TQString s = mEditor->textLine(l);
3730 s.prepend(quotePrefixName());
3731 mEditor->insertLine(s,l);
3732 mEditor->removeLine(l+1);
3733 mEditor->setCursorPosition(l,c+2);
3738 TQString KMComposeWin::addQuotesToText(
const TQString &inputText)
3740 TQString answer = TQString( inputText );
3741 TQString indentStr = quotePrefixName();
3742 answer.replace(
'\n',
'\n' + indentStr);
3743 answer.prepend( indentStr );
3748 TQString KMComposeWin::removeQuotesFromText(
const TQString &inputText)
3750 TQString s = inputText;
3753 TQString quotePrefix =
'^' + quotePrefixName();
3754 TQRegExp rx(quotePrefix);
3758 quotePrefix =
'\n' + quotePrefixName();
3760 s.replace(rx,
"\n");
3765 void KMComposeWin::slotRemoveQuotes()
3767 if( mEditor->hasFocus() && msg() )
3773 if ( mEditor->hasMarkedText() ) {
3774 TQString s = mEditor->markedText();
3775 mEditor->insert(removeQuotesFromText(s));
3777 int l = mEditor->currentLine();
3778 int c = mEditor->currentColumn();
3779 TQString s = mEditor->textLine(l);
3780 mEditor->insertLine(removeQuotesFromText(s),l);
3781 mEditor->removeLine(l+1);
3782 mEditor->setCursorPosition(l,c-2);
3788 void KMComposeWin::slotUndo()
3790 TQWidget* fw = focusWidget();
3793 if ( ::tqqt_cast<KEdit*>(fw) )
3794 static_cast<TQTextEdit*
>(fw)->undo();
3795 else if (::tqqt_cast<TQLineEdit*>(fw))
3796 static_cast<TQLineEdit*>(fw)->undo();
3799 void KMComposeWin::slotRedo()
3801 TQWidget* fw = focusWidget();
3804 if (::tqqt_cast<KEdit*>(fw))
3805 static_cast<KEdit*
>(fw)->redo();
3806 else if (::tqqt_cast<TQLineEdit*>(fw))
3807 static_cast<TQLineEdit*>(fw)->redo();
3811 void KMComposeWin::slotCut()
3813 TQWidget* fw = focusWidget();
3816 if (::tqqt_cast<KEdit*>(fw))
3817 static_cast<KEdit*
>(fw)->cut();
3818 else if (::tqqt_cast<TQLineEdit*>(fw))
3819 static_cast<TQLineEdit*>(fw)->cut();
3824 void KMComposeWin::slotCopy()
3826 TQWidget* fw = focusWidget();
3833 TQKeyEvent k(TQEvent::KeyPress, Key_C, 0, ControlButton);
3834 kapp->notify(TQT_TQOBJECT(fw), TQT_TQEVENT(&k));
3839 void KMComposeWin::slotPasteClipboard()
3841 paste( TQClipboard::Clipboard );
3844 void KMComposeWin::paste( TQClipboard::Mode mode )
3846 TQWidget* fw = focusWidget();
3849 TQMimeSource *mimeSource = TQApplication::clipboard()->data( mode );
3850 if ( mimeSource->provides(
"image/png") ) {
3851 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3852 }
else if ( KURLDrag::canDecode( mimeSource ) ) {
3854 if( KURLDrag::decode( mimeSource, urlList ) ) {
3855 const TQString asText = i18n(
"Add as Text");
3856 const TQString asAttachment = i18n(
"Add as Attachment");
3857 const TQString text = i18n(
"Please select whether you want to insert the content as text into the editor, " 3858 "or append the referenced file as an attachment.");
3859 const TQString caption = i18n(
"Paste as text or attachment?");
3861 int id = KMessageBox::questionYesNoCancel(
this, text, caption,
3862 KGuiItem( asText ), KGuiItem( asAttachment) );
3864 case KMessageBox::Yes:
3865 for ( KURL::List::Iterator it = urlList.begin();
3866 it != urlList.end(); ++it ) {
3867 mEditor->insert( (*it).url() );
3870 case KMessageBox::No:
3871 for ( KURL::List::Iterator it = urlList.begin();
3872 it != urlList.end(); ++it ) {
3878 }
else if ( TQTextDrag::canDecode( mimeSource ) ) {
3880 if ( TQTextDrag::decode( mimeSource, s ) )
3881 mEditor->insert( s );
3887 void KMComposeWin::slotMarkAll()
3889 TQWidget* fw = focusWidget();
3892 if (::tqqt_cast<TQLineEdit*>(fw))
3893 static_cast<TQLineEdit*
>(fw)->selectAll();
3894 else if (::tqqt_cast<KEdit*>(fw))
3895 static_cast<KEdit*>(fw)->selectAll();
3900 void KMComposeWin::slotClose()
3907 void KMComposeWin::slotNewComposer()
3913 win =
new KMComposeWin(msg);
3919 void KMComposeWin::slotNewMailReader()
3921 KMMainWin *kmmwin =
new KMMainWin(0);
3928 void KMComposeWin::slotUpdWinTitle(
const TQString& text)
3934 setCaption(
"("+i18n(
"unnamed")+
")");
3935 else setCaption( s.replace( TQChar(
'\n'),
' ' ) );
3940 void KMComposeWin::slotEncryptToggled(
bool on)
3942 setEncryption( on,
true );
3943 slotUpdateSignatureAndEncrypionStateIndicators();
3948 void KMComposeWin::setEncryption(
bool encrypt,
bool setByUser )
3950 bool wasModified = isModified();
3952 setModified(
true );
3953 if ( !mEncryptAction->isEnabled() )
3957 else if ( encrypt && encryptToSelf() && !mLastIdentityHasEncryptionKey ) {
3959 KMessageBox::sorry(
this,
3960 i18n(
"<qt><p>You have requested that messages be " 3961 "encrypted to yourself, but the currently selected " 3962 "identity does not define an (OpenPGP or S/MIME) " 3963 "encryption key to use for this.</p>" 3964 "<p>Please select the key(s) to use " 3965 "in the identity configuration.</p>" 3967 i18n(
"Undefined Encryption Key") );
3968 setModified( wasModified );
3974 mEncryptAction->setChecked( encrypt );
3978 mEncryptAction->setIcon(
"encrypted");
3980 mEncryptAction->setIcon(
"decrypted");
3983 if ( canSignEncryptAttachments() ) {
3984 for ( KMAtmListViewItem* entry =
3985 static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
3987 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
3988 entry->setEncrypt( encrypt );
3994 void KMComposeWin::slotSignToggled(
bool on)
3996 setSigning( on,
true );
3997 slotUpdateSignatureAndEncrypionStateIndicators();
4002 void KMComposeWin::setSigning(
bool sign,
bool setByUser )
4004 bool wasModified = isModified();
4006 setModified(
true );
4007 if ( !mSignAction->isEnabled() )
4011 if ( sign && !mLastIdentityHasSigningKey ) {
4013 KMessageBox::sorry(
this,
4014 i18n(
"<qt><p>In order to be able to sign " 4015 "this message you first have to " 4016 "define the (OpenPGP or S/MIME) signing key " 4018 "<p>Please select the key to use " 4019 "in the identity configuration.</p>" 4021 i18n(
"Undefined Signing Key") );
4022 setModified( wasModified );
4028 mSignAction->setChecked( sign );
4031 if ( canSignEncryptAttachments() ) {
4032 for ( KMAtmListViewItem* entry =
4033 static_cast<KMAtmListViewItem*>( mAtmItemList.first() );
4035 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
4036 entry->setSign( sign );
4042 void KMComposeWin::slotWordWrapToggled(
bool on)
4046 mEditor->setWordWrap( TQTextEdit::FixedColumnWidth );
4047 mEditor->setWrapColumnOrWidth( GlobalSettings::self()->lineWrapWidth() );
4051 mEditor->setWordWrap( TQTextEdit::WidgetWidth );
4056 void KMComposeWin::disableWordWrap()
4058 mEditor->setWordWrap( TQTextEdit::NoWrap );
4061 void KMComposeWin::disableRecipientNumberCheck()
4063 mCheckForRecipients =
false;
4066 void KMComposeWin::disableForgottenAttachmentsCheck()
4068 mCheckForForgottenAttachments =
false;
4071 void KMComposeWin::ignoreStickyFields()
4073 mIgnoreStickyFields =
true;
4074 mBtnTransport->setChecked(
false );
4075 mBtnDictionary->setChecked(
false );
4076 mBtnIdentity->setChecked(
false );
4077 mBtnTransport->setEnabled(
false );
4078 mBtnDictionary->setEnabled(
false );
4079 mBtnIdentity->setEnabled(
false );
4083 void KMComposeWin::slotPrint()
4085 mMessageWasModified = isModified();
4086 connect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4087 TQT_TQOBJECT(
this), TQT_SLOT( slotContinuePrint(
bool ) ) );
4088 applyChanges(
true );
4091 void KMComposeWin::slotContinuePrint(
bool rc )
4093 disconnect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4094 TQT_TQOBJECT(
this), TQT_SLOT( slotContinuePrint(
bool ) ) );
4097 if ( mComposedMessages.isEmpty() ) {
4098 kdDebug(5006) <<
"Composing the message failed." << endl;
4101 KMCommand *command =
new KMPrintCommand(
this, mComposedMessages.first() );
4103 setModified( mMessageWasModified );
4108 bool KMComposeWin::validateAddresses( TQWidget * parent,
const TQString & addresses )
4110 TQString brokenAddress;
4112 if ( !( errorCode == KPIM::AddressOk || errorCode == KPIM::AddressEmpty ) ) {
4113 TQString errorMsg(
"<qt><p><b>" + brokenAddress +
4114 "</b></p><p>" + KPIM::emailParseResultToString( errorCode ) +
4116 KMessageBox::sorry( parent, errorMsg, i18n(
"Invalid Email Address") );
4123 void KMComposeWin::doSend( KMail::MessageSender::SendMethod method,
4124 KMComposeWin::SaveIn saveIn )
4126 if ( method != KMail::MessageSender::SendLater && kmkernel->isOffline() ) {
4127 KMessageBox::information(
this,
4128 i18n(
"KMail is currently in offline mode," 4129 "your messages will be kept in the outbox until you go online."),
4130 i18n(
"Online/Offline"),
"kmailIsOffline" );
4131 mSendMethod = KMail::MessageSender::SendLater;
4133 mSendMethod = method;
4137 if ( saveIn == KMComposeWin::None ) {
4138 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() ) {
4139 if ( !( mShowHeaders & HDR_FROM ) ) {
4140 mShowHeaders |= HDR_FROM;
4141 rethinkFields(
false );
4143 mEdtFrom->setFocus();
4144 KMessageBox::sorry(
this,
4145 i18n(
"You must enter your email address in the " 4146 "From: field. You should also set your email " 4147 "address for all identities, so that you do " 4148 "not have to enter it for each message.") );
4151 if ( to().isEmpty() )
4153 if ( cc().isEmpty() && bcc().isEmpty()) {
4154 if ( mEdtTo ) mEdtTo->setFocus();
4155 KMessageBox::information(
this,
4156 i18n(
"You must specify at least one receiver," 4157 "either in the To: field or as CC or as BCC.") );
4161 if ( mEdtTo ) mEdtTo->setFocus();
4163 KMessageBox::questionYesNo(
this,
4164 i18n(
"To field is missing." 4165 "Send message anyway?"),
4166 i18n(
"No To: specified") );
4167 if ( rc == KMessageBox::No ){
4174 if ( !validateAddresses(
this, to().stripWhiteSpace() ) ) {
4178 if ( !validateAddresses(
this, cc().stripWhiteSpace() ) ) {
4182 if ( !validateAddresses(
this, bcc().stripWhiteSpace() ) ) {
4186 if (subject().isEmpty())
4188 mEdtSubject->setFocus();
4190 KMessageBox::questionYesNo(
this,
4191 i18n(
"You did not specify a subject. " 4192 "Send message anyway?"),
4193 i18n(
"No Subject Specified"),
4194 i18n(
"S&end as Is"),
4195 i18n(
"&Specify the Subject"),
4196 "no_subject_specified" );
4197 if( rc == KMessageBox::No )
4203 if ( userForgotAttachment() )
4208 mMsg->setDateToday();
4215 TQString hf = mMsg->headerField(
"X-KMail-Transport");
4216 if ((mTransport->currentText() != mTransport->text(0)) ||
4217 (!hf.isEmpty() && (hf != mTransport->text(0))))
4218 mMsg->setHeaderField(
"X-KMail-Transport", mTransport->currentText());
4220 mDisableBreaking = ( saveIn != KMComposeWin::None );
4222 const bool neverEncrypt = ( mDisableBreaking && GlobalSettings::self()->neverEncryptDrafts() )
4223 || mSigningAndEncryptionExplicitlyDisabled;
4224 connect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4225 TQT_SLOT( slotContinueDoSend(
bool ) ) );
4227 if ( mEditor->textFormat() == TQt::RichText )
4228 mMsg->setHeaderField(
"X-KMail-Markup",
"true" );
4230 mMsg->removeHeaderField(
"X-KMail-Markup" );
4231 if ( mEditor->textFormat() == TQt::RichText && inlineSigningEncryptionSelected() ) {
4232 TQString keepBtnText = mEncryptAction->isChecked() ?
4233 mSignAction->isChecked() ? i18n(
"&Keep markup, do not sign/encrypt" )
4234 : i18n(
"&Keep markup, do not encrypt" )
4235 : i18n(
"&Keep markup, do not sign" );
4236 TQString yesBtnText = mEncryptAction->isChecked() ?
4237 mSignAction->isChecked() ? i18n(
"Sign/Encrypt (delete markup)")
4238 : i18n(
"Encrypt (delete markup)" )
4239 : i18n(
"Sign (delete markup)" );
4240 int ret = KMessageBox::warningYesNoCancel(
this,
4241 i18n(
"<qt><p>Inline signing/encrypting of HTML messages is not possible;</p>" 4242 "<p>do you want to delete your markup?</p></qt>"),
4243 i18n(
"Sign/Encrypt Message?"),
4244 KGuiItem( yesBtnText ),
4245 KGuiItem( keepBtnText ) );
4246 if ( KMessageBox::Cancel == ret )
4248 if ( KMessageBox::No == ret ) {
4249 mEncryptAction->setChecked(
false);
4250 mSignAction->setChecked(
false);
4253 toggleMarkup(
false);
4257 if (neverEncrypt && saveIn != KMComposeWin::None ) {
4260 mMsg->setHeaderField(
"X-KMail-SignatureActionEnabled", mSignAction->isChecked()?
"true":
"false" );
4261 mMsg->setHeaderField(
"X-KMail-EncryptActionEnabled", mEncryptAction->isChecked()?
"true":
"false" );
4262 mMsg->setHeaderField(
"X-KMail-CryptoMessageFormat", TQString::number( cryptoMessageFormat() ) );
4264 mMsg->removeHeaderField(
"X-KMail-SignatureActionEnabled" );
4265 mMsg->removeHeaderField(
"X-KMail-EncryptActionEnabled" );
4266 mMsg->removeHeaderField(
"X-KMail-CryptoMessageFormat" );
4270 kdDebug(5006) <<
"KMComposeWin::doSend() - calling applyChanges()" 4272 applyChanges( neverEncrypt );
4275 bool KMComposeWin::saveDraftOrTemplate(
const TQString &folderName,
4278 KMFolder *theFolder = 0, *imapTheFolder = 0;
4280 if ( !folderName.isEmpty() ) {
4281 theFolder = kmkernel->folderMgr()->findIdString( folderName );
4282 if ( theFolder == 0 )
4285 theFolder = kmkernel->dimapFolderMgr()->findIdString( folderName );
4286 if ( theFolder == 0 )
4287 imapTheFolder = kmkernel->imapFolderMgr()->findIdString( folderName );
4288 if ( !theFolder && !imapTheFolder ) {
4289 const KPIM::Identity &
id = kmkernel->identityManager()
4290 ->identityForUoidOrDefault( msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt() );
4291 KMessageBox::information( 0,
4292 i18n(
"The custom drafts or templates folder for " 4293 "identify \"%1\" does not exist (anymore); " 4294 "therefore, the default drafts or templates " 4295 "folder will be used.")
4296 .arg(
id.identityName() ) );
4299 if ( imapTheFolder && imapTheFolder->noContent() )
4302 bool didOpen =
false;
4303 if ( theFolder == 0 ) {
4304 theFolder = ( mSaveIn==KMComposeWin::Drafts ?
4305 kmkernel->draftsFolder() : kmkernel->templatesFolder() );
4308 theFolder->
open(
"composer" );
4311 kdDebug(5006) << k_funcinfo <<
"theFolder=" << theFolder->name() << endl;
4312 if ( imapTheFolder )
4313 kdDebug(5006) << k_funcinfo <<
"imapTheFolder=" << imapTheFolder->name() << endl;
4315 bool sentOk = !( theFolder->
addMsg( msg ) );
4319 msg = theFolder->
getMsg( theFolder->
count() - 1 );
4322 if ( imapTheFolder ) {
4324 imapTheFolder->moveMsg( msg );
4325 (
static_cast<KMFolderImap*
>( imapTheFolder->storage() ))->getFolder();
4329 theFolder->
close(
"composer" );
4333 void KMComposeWin::slotContinueDoSend(
bool sentOk )
4335 kdDebug(5006) <<
"KMComposeWin::slotContinueDoSend( " << sentOk <<
" )" 4337 disconnect(
this, TQT_SIGNAL( applyChangesDone(
bool ) ),
4338 TQT_TQOBJECT(
this), TQT_SLOT( slotContinueDoSend(
bool ) ) );
4341 mDisableBreaking =
false;
4345 for ( TQValueVector<KMMessage*>::iterator it = mComposedMessages.begin() ; it != mComposedMessages.end() ; ++it ) {
4348 (*it)->cleanupHeader();
4351 (*it)->setComplete(
true );
4353 if ( mSaveIn==KMComposeWin::Drafts ) {
4354 sentOk = saveDraftOrTemplate( (*it)->drafts(), (*it) );
4355 }
else if ( mSaveIn==KMComposeWin::Templates ) {
4356 sentOk = saveDraftOrTemplate( (*it)->templates(), (*it) );
4360 if( !mComposer->originalBCC().isEmpty() )
4362 TQString recips = (*it)->headerField(
"X-KMail-Recipients" );
4363 if( !recips.isEmpty() ) {
4366 (*it)->cleanupHeader();
4367 sentOk = kmkernel->msgSender()->send((*it), mSendMethod);
4376 RecentAddresses::self( KMKernel::config() )->add( bcc() );
4377 RecentAddresses::self( KMKernel::config() )->add( cc() );
4378 RecentAddresses::self( KMKernel::config() )->add( to() );
4380 setModified(
false );
4381 mAutoDeleteMsg =
false;
4388 bool KMComposeWin::checkTransport()
const 4391 KMessageBox::information( mMainWidget,
4392 i18n(
"Please create an account for sending and try again.") );
4400 void KMComposeWin::slotSendLater()
4402 if ( !checkTransport() )
4404 if ( !checkRecipientNumber() )
4406 if ( mEditor->checkExternalEditorFinished() )
4407 doSend( KMail::MessageSender::SendLater );
4412 void KMComposeWin::slotSaveDraft() {
4413 if ( mEditor->checkExternalEditorFinished() )
4414 doSend( KMail::MessageSender::SendLater, KMComposeWin::Drafts );
4418 void KMComposeWin::slotSaveTemplate() {
4419 if ( mEditor->checkExternalEditorFinished() )
4420 doSend( KMail::MessageSender::SendLater, KMComposeWin::Templates );
4424 void KMComposeWin::slotSendNowVia(
int item )
4427 TQString customTransport = availTransports[ item ];
4429 mTransport->setCurrentText( customTransport );
4434 void KMComposeWin::slotSendLaterVia(
int item )
4437 TQString customTransport = availTransports[ item ];
4439 mTransport->setCurrentText( customTransport );
4445 void KMComposeWin::slotSendNow() {
4446 if ( !mEditor->checkExternalEditorFinished() )
4448 if ( !checkTransport() )
4450 if ( !checkRecipientNumber() )
4452 if ( GlobalSettings::self()->confirmBeforeSend() )
4454 int rc = KMessageBox::warningYesNoCancel( mMainWidget,
4455 i18n(
"About to send email..."),
4456 i18n(
"Send Confirmation"),
4458 i18n(
"Send &Later") );
4460 if ( rc == KMessageBox::Yes )
4461 doSend( KMail::MessageSender::SendImmediate );
4462 else if ( rc == KMessageBox::No )
4463 doSend( KMail::MessageSender::SendLater );
4466 doSend( KMail::MessageSender::SendImmediate );
4471 bool KMComposeWin::checkRecipientNumber()
const 4473 uint thresHold = GlobalSettings::self()->recipientThreshold();
4474 if ( mCheckForRecipients &&
4475 GlobalSettings::self()->tooManyRecipients() &&
4476 mRecipientsEditor->recipients().count() > thresHold ) {
4477 if ( KMessageBox::questionYesNo( mMainWidget,
4478 i18n(
"You are trying to send the mail to more than %1 recipients. Send message anyway?").arg(thresHold),
4479 i18n(
"Too many receipients"),
4480 i18n(
"&Send as Is"),
4481 i18n(
"&Edit Recipients")) == KMessageBox::No ) {
4490 void KMComposeWin::slotAppendSignature()
4496 void KMComposeWin::slotPrependSignature()
4498 insertSignature( Prepend );
4502 void KMComposeWin::slotInsertSignatureAtCursor()
4504 insertSignature( AtCursor );
4508 void KMComposeWin::insertSignature( SignaturePlacement placement )
4510 bool mod = mEditor->isModified();
4512 const KPIM::Identity &ident =
4513 kmkernel->identityManager()->
4514 identityForUoidOrDefault( mIdentity->currentIdentity() );
4516 mOldSigText = GlobalSettings::self()->prependSignature()? ident.signature().rawText() : ident.signatureText();
4518 if( !mOldSigText.isEmpty() )
4521 int paragraph, index;
4522 mEditor->getCursorPosition( ¶graph, &index );
4523 index = mEditor->indexOfCurrentLineStart( paragraph, index );
4525 switch( placement ) {
4527 mEditor->setText( mEditor->text() + mOldSigText );
4530 mOldSigText =
"\n\n" + mOldSigText +
"\n";
4531 mEditor->insertAt( mOldSigText, paragraph, index );
4538 if ( mEditor->paragraphLength( paragraph ) > 0 )
4539 mOldSigText = mOldSigText +
"\n";
4540 if ( mOldSigText.startsWith(
"\n" ) )
4541 mOldSigText = mOldSigText.remove( 0, 1 );
4546 mOldSigText =
"\n" + mOldSigText;
4548 mEditor->insertAt( mOldSigText, paragraph, index );
4552 mEditor->setModified(mod);
4554 if ( mPreserveUserCursorPosition ) {
4555 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
4560 mPreserveUserCursorPosition =
false;
4565 mEditor->setCursorPosition( paragraph, 0 );
4568 mEditor->setCursorPosition( paragraph + 1, 0 );
4570 if ( placement == Prepend || placement == Append )
4571 mEditor->setContentsPos( 0, 0 );
4578 void KMComposeWin::slotHelp()
4584 void KMComposeWin::slotCleanSpace()
4595 if ( mEditor->hasMarkedText() ) {
4596 s = mEditor->markedText();
4600 s = mEditor->text();
4605 bool restore =
false;
4606 const KPIM::Identity & ident =
4607 kmkernel->identityManager()->identityForUoid( mId );
4608 if ( !ident.isNull() ) {
4609 sig = ident.signatureText();
4610 if( !sig.isEmpty() ) {
4611 if( s.endsWith( sig ) ) {
4612 s.truncate( s.length() - sig.length() );
4619 TQRegExp squeeze(
"[\t ]+" );
4620 s.replace( squeeze, TQChar(
' ' ) );
4623 TQRegExp trailing(
"\\s+$" );
4624 s.replace( trailing, TQChar(
'\n' ) );
4627 TQRegExp singleSpace(
"[\n]{2,}" );
4628 s.replace( singleSpace, TQChar(
'\n' ) );
4641 if ( !mEditor->hasMarkedText() )
4643 mEditor->insert( s );
4647 void KMComposeWin::slotToggleMarkup()
4649 if ( markupAction->isChecked() ) {
4651 toolBar(
"htmlToolBar")->show();
4653 fontChanged( mEditor->currentFont() );
4654 mSaveFont = mEditor->currentFont();
4657 toggleMarkup(
false);
4661 void KMComposeWin::toggleMarkup(
bool markup)
4664 if ( !mUseHTMLEditor ) {
4665 kdDebug(5006) <<
"setting RichText editor" << endl;
4666 mUseHTMLEditor =
true;
4670 int paraFrom, indexFrom, paraTo, indexTo;
4671 mEditor->getSelection ( ¶From, &indexFrom, ¶To, &indexTo);
4672 mEditor->selectAll();
4674 bool _bold = textBoldAction->isChecked();
4675 bool _italic = textItalicAction->isChecked();
4676 mEditor->setColor(TQColor(0,0,0));
4677 textBoldAction->setChecked(_bold);
4678 textItalicAction->setChecked(_italic);
4679 mEditor->setSelection ( paraFrom, indexFrom, paraTo, indexTo);
4681 mEditor->setTextFormat(TQt::RichText);
4682 mEditor->setModified(
true);
4683 markupAction->setChecked(
true);
4684 toolBar(
"htmlToolBar" )->show();
4685 mEditor->deleteAutoSpellChecking();
4686 mAutoSpellCheckingAction->setChecked(
false);
4687 slotAutoSpellCheckingToggled(
false);
4690 kdDebug(5006) <<
"setting PlainText editor" << endl;
4691 mHtmlMarkup =
false;
4692 toolBar(
"htmlToolBar")->hide();
4693 if ( mUseHTMLEditor ) {
4694 mUseHTMLEditor =
false;
4695 mEditor->setTextFormat(TQt::PlainText);
4696 TQString text = mEditor->text();
4697 mEditor->setText(text);
4698 mEditor->setModified(
true);
4699 slotAutoSpellCheckingToggled(
true);
4704 void KMComposeWin::htmlToolBarVisibilityChanged(
bool visible )
4708 markupAction->setChecked(
false );
4709 toggleMarkup(
false );
4713 void KMComposeWin::slotSubjectTextSpellChecked()
4715 mSubjectTextWasSpellChecked =
true;
4719 void KMComposeWin::slotAutoSpellCheckingToggled(
bool on )
4721 if ( mEditor->autoSpellChecking(on) == -1 ) {
4722 mAutoSpellCheckingAction->setChecked(
false);
4727 temp = i18n(
"Spellcheck: on" );
4729 temp = i18n(
"Spellcheck: off" );
4730 statusBar()->changeItem( temp, 3 );
4733 void KMComposeWin::slotSpellcheck()
4735 if (mSpellCheckInProgress)
return;
4736 mSubjectTextWasSpellChecked =
false;
4737 mSpellCheckInProgress=
true;
4743 mEditor->spellcheck();
4746 void KMComposeWin::slotUpdateSignatureActions()
4750 const KPIM::Identity & ident =
4751 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
4752 TQString sig = ident.signatureText();
4754 if ( sig.isEmpty() ) {
4755 mAppendSignatureAction->setEnabled(
false );
4756 mPrependSignatureAction->setEnabled(
false );
4757 mInsertSignatureAction->setEnabled(
false );
4760 mAppendSignatureAction->setEnabled(
true );
4761 mPrependSignatureAction->setEnabled(
true );
4762 mInsertSignatureAction->setEnabled(
true );
4766 void KMComposeWin::polish()
4769 markupAction->setChecked(mHtmlMarkup);
4771 toolBar(
"htmlToolBar")->show();
4773 toolBar(
"htmlToolBar")->hide();
4774 KMail::Composer::polish();
4778 void KMComposeWin::slotSpellcheckDone(
int result)
4780 kdDebug(5006) <<
"spell check complete: result = " << result << endl;
4781 mSpellCheckInProgress=
false;
4786 statusBar()->changeItem(i18n(
" Spell check canceled."),0);
4789 statusBar()->changeItem(i18n(
" Spell check stopped."),0);
4792 statusBar()->changeItem(i18n(
" Spell check complete."),0);
4795 TQTimer::singleShot( 2000,
this, TQT_SLOT(slotSpellcheckDoneClearStatus()) );
4798 void KMComposeWin::slotSpellcheckDoneClearStatus()
4800 statusBar()->changeItem(
"", 0);
4805 void KMComposeWin::slotIdentityChanged( uint uoid )
4807 const KPIM::Identity & ident =
4808 kmkernel->identityManager()->identityForUoid( uoid );
4809 if( ident.isNull() )
return;
4812 slotUpdateSignatureActions();
4814 if( !ident.fullEmailAddr().isNull() )
4815 mEdtFrom->setText(ident.fullEmailAddr());
4817 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() )
4818 mShowHeaders |= HDR_FROM;
4819 if ( mEdtReplyTo ) mEdtReplyTo->setText(ident.replyToAddr());
4821 if ( mRecipientsEditor ) {
4823 const KPIM::Identity & oldIdentity =
4824 kmkernel->identityManager()->identityForUoidOrDefault( mId );
4825 if ( oldIdentity.bcc() != ident.bcc() ) {
4826 mRecipientsEditor->removeRecipient( oldIdentity.bcc(), Recipient::Bcc );
4827 mRecipientsEditor->addRecipient( ident.bcc(), Recipient::Bcc );
4828 mRecipientsEditor->setFocusBottom();
4834 if( mEdtBcc && !mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4837 if( !mEdtBcc->text().isEmpty() && mEdtBcc->text() != ident.bcc() && !mEdtBcc->edited() ) {
4838 mEdtBcc->setText( ident.bcc() );
4843 if ( mEdtBcc->text() != ident.bcc() && !mEdtBcc->text().isEmpty() ) {
4844 TQString temp_string( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4845 mEdtBcc->setText( temp_string );
4849 mEdtBcc->setText( ident.bcc() );
4856 if( mEdtBcc && mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4857 if( !mEdtBcc->text().isEmpty() ) {
4858 TQString temp_string ( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4859 mEdtBcc->setText( temp_string );
4861 mEdtBcc->setText( ident.bcc() );
4867 if( mEdtBcc && !mEdtBcc->edited() && ident.bcc().isEmpty() ) {
4868 mEdtBcc->setText( ident.bcc() );
4871 if ( !ident.bcc().isEmpty() ) {
4872 mShowHeaders |= HDR_BCC;
4875 if ( ident.organization().isEmpty() )
4876 mMsg->removeHeaderField(
"Organization");
4878 mMsg->setHeaderField(
"Organization", ident.organization());
4880 if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
4881 mMsg->removeHeaderField(
"X-Face");
4884 TQString xface = ident.xface();
4885 if (!xface.isEmpty())
4887 int numNL = ( xface.length() - 1 ) / 70;
4888 for (
int i = numNL; i > 0; --i )
4889 xface.insert( i*70,
"\n\t" );
4890 mMsg->setHeaderField(
"X-Face", xface);
4894 if ( !mBtnTransport->isChecked() && !mIgnoreStickyFields ) {
4895 TQString transp = ident.transport();
4896 if ( transp.isEmpty() )
4898 mMsg->removeHeaderField(
"X-KMail-Transport");
4899 transp = GlobalSettings::self()->defaultTransport();
4902 mMsg->setHeaderField(
"X-KMail-Transport", transp);
4903 setTransport( transp );
4906 if ( !mBtnDictionary->isChecked() && !mIgnoreStickyFields ) {
4907 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
4910 if ( !mBtnFcc->isChecked() && !mPreventFccOverwrite ) {
4911 setFcc( ident.fcc() );
4914 TQString edtText = mEditor->text();
4916 if ( mOldSigText.isEmpty() ) {
4917 const KPIM::Identity &
id =
4920 identityForUoidOrDefault( mMsg->headerField(
"X-KMail-Identity" ).
4921 stripWhiteSpace().toUInt() );
4922 mOldSigText = GlobalSettings::self()->prependSignature() ?
id.signature().rawText() :
id.signatureText();
4926 if ( !GlobalSettings::prependSignature() ) {
4929 while ( !edtText.isEmpty() && edtText[edtText.length()-1].isSpace() )
4930 edtText.truncate( edtText.length() - 1 );
4932 while ( !mOldSigText.isEmpty() && mOldSigText[mOldSigText.length()-1].isSpace() )
4933 mOldSigText.truncate( mOldSigText.length() - 1 );
4935 if ( edtText.endsWith( mOldSigText ) )
4936 edtText.truncate( edtText.length() - mOldSigText.length() );
4939 mOldSigText = ident.signatureText();
4940 if( ( !mOldSigText.isEmpty() ) &&
4941 ( GlobalSettings::self()->autoTextSignature() ==
"auto" ) ) {
4942 edtText.append( mOldSigText );
4944 mEditor->setText( edtText );
4946 const int pos = edtText.find( mOldSigText );
4947 if ( pos >= 0 && !mOldSigText.isEmpty() ) {
4948 const int oldLength = mOldSigText.length();
4949 mOldSigText =
"\n\n"+ ident.signature().rawText() +
"\n";
4950 edtText = edtText.replace( pos, oldLength, mOldSigText );
4951 mEditor->setText( edtText );
4953 insertSignature( Append );
4959 bool bNewIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4960 bool bNewIdentityHasEncryptionKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4961 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
4962 !ident.pgpEncryptionKey().isEmpty() );
4964 if ( !bNewIdentityHasEncryptionKey && mLastIdentityHasEncryptionKey ) {
4965 mLastEncryptActionState = mEncryptAction->isChecked();
4966 setEncryption(
false );
4968 if ( !bNewIdentityHasSigningKey && mLastIdentityHasSigningKey ) {
4969 mLastSignActionState = mSignAction->isChecked();
4970 setSigning(
false );
4973 if ( bNewIdentityHasEncryptionKey && !mLastIdentityHasEncryptionKey )
4974 setEncryption( mLastEncryptActionState );
4975 if ( bNewIdentityHasSigningKey && !mLastIdentityHasSigningKey )
4976 setSigning( mLastSignActionState );
4978 mLastIdentityHasSigningKey = bNewIdentityHasSigningKey;
4979 mLastIdentityHasEncryptionKey = bNewIdentityHasEncryptionKey;
4981 setModified(
true );
4985 rethinkFields(
false );
4989 void KMComposeWin::slotSpellcheckConfig()
4991 KDialogBase dlg(KDialogBase::Plain, i18n(
"Spellchecker"),
4992 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok,
4993 TQT_TQWIDGET(
this), 0,
true,
true );
4995 TQTabDialog qtd (
this,
"tabdialog",
true);
4996 KSpellConfig mKSpellConfig (&qtd);
4997 mKSpellConfig.layout()->setMargin( KDialog::marginHint() );
4999 qtd.addTab (&mKSpellConfig, i18n(
"Spellchecker"));
5000 qtd.setCancelButton ();
5002 twin.setIcons (qtd.winId(), kapp->icon(), kapp->miniIcon());
5003 qtd.setCancelButton(KStdGuiItem::cancel().text());
5004 qtd.setOkButton(KStdGuiItem::ok().text());
5007 mKSpellConfig.writeGlobalSettings();
5011 void KMComposeWin::slotStatusMessage(
const TQString &message)
5013 statusBar()->changeItem( message, 0 );
5016 void KMComposeWin::slotEditToolbars()
5018 saveMainWindowSettings(KMKernel::config(),
"Composer");
5019 KEditToolbar dlg(guiFactory(),
this);
5021 connect( &dlg, TQT_SIGNAL(newToolbarConfig()),
5022 TQT_SLOT(slotUpdateToolbars()) );
5027 void KMComposeWin::slotUpdateToolbars()
5029 createGUI(
"kmcomposerui.rc");
5030 applyMainWindowSettings(KMKernel::config(),
"Composer");
5033 void KMComposeWin::slotEditKeys()
5035 KKeyDialog::configure( actionCollection(),
5040 void KMComposeWin::setReplyFocus(
bool hasMessage )
5042 mEditor->setFocus();
5044 if( mMsg->getCursorPos() ) {
5045 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
5047 mEditor->setCursorPosition( 1, 0 );
5052 void KMComposeWin::setFocusToSubject()
5054 mEdtSubject->setFocus();
5057 int KMComposeWin::autoSaveInterval()
const 5059 return GlobalSettings::self()->autosaveInterval() * 1000 * 60;
5062 void KMComposeWin::initAutoSave()
5064 kdDebug(5006) << k_funcinfo << endl;
5067 if ( mAutoSaveFilename.isEmpty() ) {
5068 mAutoSaveFilename = KMFolderMaildir::constructValidFileName();
5074 void KMComposeWin::updateAutoSave()
5076 if ( autoSaveInterval() == 0 ) {
5077 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5080 if ( !mAutoSaveTimer ) {
5081 mAutoSaveTimer =
new TQTimer(
this,
"mAutoSaveTimer" );
5082 connect( mAutoSaveTimer, TQT_SIGNAL( timeout() ),
5083 TQT_TQOBJECT(
this), TQT_SLOT( autoSaveMessage() ) );
5085 mAutoSaveTimer->start( autoSaveInterval() );
5089 void KMComposeWin::setAutoSaveFilename(
const TQString & filename )
5091 mAutoSaveFilename = filename;
5094 void KMComposeWin::cleanupAutoSave()
5096 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5097 if ( !mAutoSaveFilename.isEmpty() ) {
5098 kdDebug(5006) << k_funcinfo <<
"deleting autosave file " 5099 << mAutoSaveFilename << endl;
5101 mAutoSaveFilename );
5102 mAutoSaveFilename = TQString();
5106 void KMComposeWin::slotCompletionModeChanged( TDEGlobalSettings::Completion mode)
5108 GlobalSettings::self()->setCompletionMode( (
int) mode );
5111 mEdtFrom->setCompletionMode( mode );
5112 mEdtReplyTo->setCompletionMode( mode );
5113 if ( mClassicalRecipients ) {
5114 mEdtTo->setCompletionMode( mode );
5115 mEdtCc->setCompletionMode( mode );
5116 mEdtBcc->setCompletionMode( mode );
5118 mRecipientsEditor->setCompletionMode( mode );
5121 void KMComposeWin::slotConfigChanged()
5126 slotWordWrapToggled( mWordWrapAction->isChecked() );
5133 void KMComposeWin::slotFolderRemoved(
KMFolder* folder)
5136 if ( (mFolder) && (folder->
idString() == mFolder->idString()) )
5138 mFolder = kmkernel->draftsFolder();
5139 kdDebug(5006) <<
"restoring drafts to " << mFolder->idString() << endl;
5141 if (mMsg) mMsg->setParent(0);
5145 void KMComposeWin::editorFocusChanged(
bool gained)
5147 mPasteQuotation->setEnabled(gained);
5150 void KMComposeWin::slotSetAlwaysSend(
bool bAlways )
5152 mAlwaysSend = bAlways;
5155 void KMComposeWin::slotListAction(
const TQString& style )
5158 if ( style == i18n(
"Standard" ) )
5159 mEditor->setParagType( TQStyleSheetItem::DisplayBlock, TQStyleSheetItem::ListDisc );
5160 else if ( style == i18n(
"Bulleted List (Disc)" ) )
5161 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDisc );
5162 else if ( style == i18n(
"Bulleted List (Circle)" ) )
5163 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListCircle );
5164 else if ( style == i18n(
"Bulleted List (Square)" ) )
5165 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListSquare );
5166 else if ( style == i18n(
"Ordered List (Decimal)" ))
5167 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDecimal );
5168 else if ( style == i18n(
"Ordered List (Alpha lower)" ) )
5169 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListLowerAlpha );
5170 else if ( style == i18n(
"Ordered List (Alpha upper)" ) )
5171 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListUpperAlpha );
5172 mEditor->viewport()->setFocus();
5175 void KMComposeWin::slotFontAction(
const TQString& font)
5178 mEditor->TQTextEdit::setFamily( font );
5179 mEditor->viewport()->setFocus();
5182 void KMComposeWin::slotSizeAction(
int size )
5185 mEditor->setPointSize( size );
5186 mEditor->viewport()->setFocus();
5189 void KMComposeWin::slotAlignLeft()
5192 mEditor->TQTextEdit::setAlignment( AlignLeft );
5195 void KMComposeWin::slotAlignCenter()
5198 mEditor->TQTextEdit::setAlignment( AlignHCenter );
5201 void KMComposeWin::slotAlignRight()
5204 mEditor->TQTextEdit::setAlignment( AlignRight );
5207 void KMComposeWin::slotTextBold()
5210 mEditor->TQTextEdit::setBold( textBoldAction->isChecked() );
5213 void KMComposeWin::slotTextItalic()
5216 mEditor->TQTextEdit::setItalic( textItalicAction->isChecked() );
5219 void KMComposeWin::slotTextUnder()
5222 mEditor->TQTextEdit::setUnderline( textUnderAction->isChecked() );
5225 void KMComposeWin::slotFormatReset()
5227 mEditor->setColor(mForeColor);
5228 mEditor->setCurrentFont( mSaveFont );
5230 void KMComposeWin::slotTextColor()
5232 TQColor color = mEditor->color();
5234 if ( KColorDialog::getColor( color,
this ) ) {
5236 mEditor->setColor( color );
5240 void KMComposeWin::fontChanged(
const TQFont &f )
5242 TQFont fontTemp = f;
5243 fontTemp.setBold(
true );
5244 fontTemp.setItalic(
true );
5245 TQFontInfo fontInfo( fontTemp );
5247 if ( fontInfo.bold() ) {
5248 textBoldAction->setChecked( f.bold() );
5249 textBoldAction->setEnabled(
true ) ;
5251 textBoldAction->setEnabled(
false );
5254 if ( fontInfo.italic() ) {
5255 textItalicAction->setChecked( f.italic() );
5256 textItalicAction->setEnabled(
true ) ;
5258 textItalicAction->setEnabled(
false );
5261 textUnderAction->setChecked( f.underline() );
5263 fontAction->setFont( f.family() );
5264 fontSizeAction->setFontSize( f.pointSize() );
5267 void KMComposeWin::alignmentChanged(
int a )
5270 alignLeftAction->setChecked( ( a == AlignAuto ) || ( a & AlignLeft ) );
5271 alignCenterAction->setChecked( ( a & AlignHCenter ) );
5272 alignRightAction->setChecked( ( a & AlignRight ) );
5276 class TDEToggleActionResetter {
5277 TDEToggleAction * mAction;
5280 TDEToggleActionResetter( TDEToggleAction * action,
bool on )
5281 : mAction( action ), mOn( on ) {}
5282 ~TDEToggleActionResetter() {
5284 mAction->setChecked( mOn );
5286 void disable() { mAction = 0; }
5290 void KMComposeWin::slotEncryptChiasmusToggled(
bool on ) {
5291 mEncryptWithChiasmus =
false;
5296 TDEToggleActionResetter resetter( mEncryptChiasmusAction,
false );
5298 const Kleo::CryptoBackend::Protocol * chiasmus =
5299 Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" );
5302 const TQString msg = Kleo::CryptoBackendFactory::instance()->knowsAboutProtocol(
"Chiasmus" )
5303 ? i18n(
"Please configure a Crypto Backend to use for " 5304 "Chiasmus encryption first.\n" 5305 "You can do this in the Crypto Backends tab of " 5306 "the configure dialog's Security page." )
5307 : i18n(
"It looks as though libkleopatra was compiled without " 5308 "Chiasmus support. You might want to recompile " 5309 "libkleopatra with --enable-chiasmus.");
5310 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Backend Configured" ) );
5314 STD_NAMESPACE_PREFIX auto_ptr<Kleo::SpecialJob> job( chiasmus->specialJob(
"x-obtain-keys", TQMap<TQString,TQVariant>() ) );
5316 const TQString msg = i18n(
"Chiasmus backend does not offer the " 5317 "\"x-obtain-keys\" function. Please report this bug." );
5318 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5322 if ( job->exec() ) {
5323 job->showErrorDialog(
this, i18n(
"Chiasmus Backend Error" ) );
5327 const TQVariant result = job->property(
"result" );
5328 if ( result.type() != TQVariant::StringList ) {
5329 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: " 5330 "The \"x-obtain-keys\" function did not return a " 5331 "string list. Please report this bug." );
5332 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5336 const TQStringList keys = result.toStringList();
5337 if ( keys.empty() ) {
5338 const TQString msg = i18n(
"No keys have been found. Please check that a " 5339 "valid key path has been set in the Chiasmus " 5341 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Keys Found" ) );
5345 ChiasmusKeySelector selectorDlg(
this, i18n(
"Chiasmus Encryption Key Selection" ),
5346 keys, GlobalSettings::chiasmusKey(),
5347 GlobalSettings::chiasmusOptions() );
5348 if ( selectorDlg.exec() != TQDialog::Accepted )
5351 GlobalSettings::setChiasmusOptions( selectorDlg.options() );
5352 GlobalSettings::setChiasmusKey( selectorDlg.key() );
5353 assert( !GlobalSettings::chiasmusKey().isEmpty() );
5354 mEncryptWithChiasmus =
true;
5360 kdDebug(5006) << k_funcinfo << endl;
5361 KMMessagePart *part = mEditorMap[ watcher ];
5362 KTempFile *tf = mEditorTempFiles[ watcher ];
5363 mEditorMap.remove( watcher );
5364 mEditorTempFiles.remove( watcher );
5365 if ( !watcher->fileChanged() )
5368 tf->file()->reset();
5369 TQByteArray data = tf->file()->readAll();
5370 part->setBodyEncodedBinary( data );
5374 void KMComposeWin::slotUpdateSignatureAndEncrypionStateIndicators()
5376 const bool showIndicatorsAlways =
false;
5377 mSignatureStateIndicator->setText( mSignAction->isChecked()? i18n(
"Message will be signed") : i18n(
"Message will not be signed") );
5378 mEncryptionStateIndicator->setText( mEncryptAction->isChecked()? i18n(
"Message will be encrypted") : i18n(
"Message will not be encrypted") );
5379 if ( !showIndicatorsAlways ) {
5380 mSignatureStateIndicator->setShown( mSignAction->isChecked() );
5381 mEncryptionStateIndicator->setShown( mEncryptAction->isChecked() );
5385 void KMComposeWin::slotAttachmentDragStarted()
5387 kdDebug(5006) << k_funcinfo << endl;
5389 TQStringList filenames;
5390 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++idx ) {
5391 if ( (*it)->isSelected() ) {
5392 KMMessagePart* msgPart = mAtmList.at(idx);
5393 KTempDir * tempDir =
new KTempDir();
5394 tempDir->setAutoDelete(
true );
5395 mTempDirs.insert( tempDir );
5396 const TQString fileName = tempDir->name() +
"/" + msgPart->name();
5397 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(),
5399 false,
false,
false);
5401 url.setPath( fileName );
5402 filenames << url.path();
5405 if ( filenames.isEmpty() )
return;
5407 TQUriDrag *drag =
new TQUriDrag( mAtmListView );
5408 drag->setFileNames( filenames );
5412 void KMComposeWin::recipientEditorSizeHintChanged()
5414 TQTimer::singleShot( 1,
this, TQT_SLOT(setMaximumHeaderSize()) );
5417 void KMComposeWin::setMaximumHeaderSize()
5419 mHeadersArea->setMaximumHeight( mHeadersArea->sizeHint().height() );
static TQCString defaultCharset()
Get the default message charset.
static TQString smartQuote(const TQString &msg, int maxLineLength)
Given argument msg add quoting characters and relayout for max width maxLength.
void initHeader(uint identity=0)
Initialize header fields.
const DwString & asDwString() const
Return the entire message contents in the DwString.
static KPIM::EmailParseResult isValidEmailAddressList(const TQString &aStr, TQString &brokenAddress)
Validate a list of email addresses, and also allow aliases and distribution lists to be expanded befo...
Provides encoding detection capabilities.
static TQString localDataPath()
Returns the full path of the user's local data directory for KMail.
static TQString expandAliases(const TQString &recipients)
Expands aliases (distribution lists and nick names) and appends a domain part to all email addresses ...
DCOP interface for mail composer window.
TQString idString() const
Returns a string that can be used to identify this folder.
Starts an editor for the given URL and emits an signal when editing has been finished.
int count(bool cache=false) const
Number of messages in this folder.
KMMessage * getMsg(int idx)
Read message at given index.
sets a cursor and makes sure it's restored on destruction Create a KCursorSaver object when you want ...
void close(const char *owner, bool force=false)
Close folder.
static const TQStringList & preferredCharsets()
Get a list of preferred message charsets.
TQString fcc() const
Get or set the 'Fcc' header field.
A combo box for selecting the dictionary used for spell checking.
static TQStringList transportNames()
Returns the list for transport names.
bool analyze(const char *data, int len)
Analyze text data.
int open(const char *owner)
Open folder for access.
KMMsgInfo * unGetMsg(int idx)
Replace KMMessage with KMMsgInfo and delete KMMessage.
The attachment dialog with convenience backward compatible methods.
TQString headerField(const TQCString &name) const
Returns the value of a header field with the given name.
int addMsg(KMMessage *msg, int *index_return=0)
Add the given message to the folder.
const char * encoding() const
Convenience method.