9 #define REALLY_WANT_KMCOMPOSEWIN_H
10 #include "kmcomposewin.h"
11 #undef REALLY_WANT_KMCOMPOSEWIN_H
14 #include "kmlineeditspell.h"
15 #include "kmatmlistview.h"
17 #include "kmmainwin.h"
18 #include "kmreadermainwin.h"
19 #include "messagesender.h"
20 #include "kmmsgpartdlg.h"
21 #include <kpgpblock.h>
22 #include <kaddrbook.h>
23 #include "kmaddrbook.h"
24 #include "kmmsgdict.h"
25 #include "kmfolderimap.h"
26 #include "kmfoldermgr.h"
27 #include "kmfoldercombobox.h"
28 #include "kmtransport.h"
29 #include "kmcommands.h"
30 #include "kcursorsaver.h"
32 #include "encodingdetector.h"
33 #include "attachmentlistview.h"
34 #include "transportmanager.h"
35 using KMail::AttachmentListView;
36 #include "dictionarycombobox.h"
38 #include "addressesdialog.h"
39 using KPIM::AddressesDialog;
40 #include "addresseeemailselection.h"
41 using KPIM::AddresseeEmailSelection;
42 using KPIM::AddresseeSelectorDialog;
43 #include <maillistdrag.h>
44 using KPIM::MailListDrag;
45 #include "recentaddresses.h"
46 using TDERecentAddress::RecentAddresses;
47 #include "kleo_util.h"
49 #include "recipientseditor.h"
50 #include "editorwatcher.h"
52 #include "attachmentcollector.h"
53 #include "objecttreeparser.h"
55 #include "kmfoldermaildir.h"
57 #include <libkpimidentities/identitymanager.h>
58 #include <libkpimidentities/identitycombo.h>
59 #include <libkpimidentities/identity.h>
60 #include <libtdepim/tdefileio.h>
61 #include <libemailfunctions/email.h>
62 #include <kleo/cryptobackendfactory.h>
63 #include <kleo/exportjob.h>
64 #include <kleo/specialjob.h>
65 #include <ui/progressdialog.h>
66 #include <ui/keyselectiondialog.h>
68 #include <gpgmepp/context.h>
69 #include <gpgmepp/key.h>
71 #include <tdeio/netaccess.h>
73 #include "tdelistboxdialog.h"
75 #include "messagecomposer.h"
76 #include "chiasmuskeyselector.h"
78 #include <kcharsets.h>
79 #include <tdecompletionbox.h>
81 #include <kcombobox.h>
82 #include <tdestdaccel.h>
83 #include <tdepopupmenu.h>
84 #include <kedittoolbar.h>
85 #include <kkeydialog.h>
87 #include <tdefiledialog.h>
89 #include <kinputdialog.h>
90 #include <tdemessagebox.h>
92 #include <tdeio/scheduler.h>
93 #include <tdetempfile.h>
94 #include <tdelocale.h>
95 #include <tdeapplication.h>
96 #include <kstatusbar.h>
97 #include <tdeaction.h>
98 #include <kstdaction.h>
99 #include <kdirwatch.h>
100 #include <kstdguiitem.h>
101 #include <kiconloader.h>
102 #include <kpushbutton.h>
103 #include <kuserprofile.h>
105 #include <ktempdir.h>
106 #include <kstandarddirs.h>
108 #include "globalsettings.h"
109 #include "replyphrases.h"
111 #include <tdespell.h>
112 #include <tdespelldlg.h>
113 #include <spellingfilter.h>
114 #include <ksyntaxhighlighter.h>
115 #include <kcolordialog.h>
117 #include <ksavefile.h>
119 #include <tqtabdialog.h>
120 #include <tqregexp.h>
121 #include <tqbuffer.h>
122 #include <tqtooltip.h>
123 #include <tqtextcodec.h>
124 #include <tqheader.h>
125 #include <tqwhatsthis.h>
126 #include <tqfontdatabase.h>
128 #include <mimelib/mimepp.h>
133 #include <sys/stat.h>
134 #include <sys/types.h>
141 #include "kmcomposewin.moc"
143 #include "snippetwidget.h"
145 KMail::Composer * KMail::makeComposer(
KMMessage * msg, uint identitiy ) {
146 return KMComposeWin::create( msg, identitiy );
149 KMail::Composer * KMComposeWin::create(
KMMessage * msg, uint identitiy ) {
150 return new KMComposeWin( msg, identitiy );
154 KMComposeWin::KMComposeWin(
KMMessage *aMsg, uint
id )
156 mSpellCheckInProgress( false ),
158 mAtmModified( false ),
162 mSigningAndEncryptionExplicitlyDisabled( false ),
164 mUseHTMLEditor( false ),
166 mAttachPK( 0 ), mAttachMPK( 0 ),
167 mAttachRemoveAction( 0 ), mAttachSaveAction( 0 ), mAttachPropertiesAction( 0 ),
168 mAppendSignatureAction( 0 ), mPrependSignatureAction( 0 ), mInsertSignatureAction( 0 ),
169 mSignAction( 0 ), mEncryptAction( 0 ), mRequestMDNAction( 0 ),
170 mUrgentAction( 0 ), mAllFieldsAction( 0 ), mFromAction( 0 ),
171 mReplyToAction( 0 ), mToAction( 0 ), mCcAction( 0 ), mBccAction( 0 ),
173 mIdentityAction( 0 ), mTransportAction( 0 ), mFccAction( 0 ),
174 mWordWrapAction( 0 ), mFixedFontAction( 0 ), mAutoSpellCheckingAction( 0 ),
175 mDictionaryAction( 0 ), mSnippetAction( 0 ),
176 mEncodingAction( 0 ),
177 mCryptoModuleAction( 0 ),
178 mEncryptChiasmusAction( 0 ),
179 mEncryptWithChiasmus( false ),
182 mAutoSaveTimer( 0 ), mLastAutoSaveErrno( 0 ),
183 mSignatureStateIndicator( 0 ), mEncryptionStateIndicator( 0 ),
184 mPreserveUserCursorPosition( false ),
185 mPreventFccOverwrite( false ),
186 mCheckForRecipients( true ),
187 mCheckForForgottenAttachments( true ),
188 mIgnoreStickyFields( false )
190 mClassicalRecipients = GlobalSettings::self()->recipientsEditorType() ==
191 GlobalSettings::EnumRecipientsEditorType::Classic;
193 mSubjectTextWasSpellChecked =
false;
194 if (kmkernel->xmlGuiInstance())
195 setInstance( kmkernel->xmlGuiInstance() );
196 mMainWidget =
new TQWidget(
this);
198 mHeadersToEditorSplitter =
new TQSplitter( TQt::Vertical, mMainWidget,
"mHeadersToEditorSplitter" );
199 mHeadersToEditorSplitter->setChildrenCollapsible(
false );
200 mHeadersArea =
new TQWidget( mHeadersToEditorSplitter );
201 mHeadersArea->setSizePolicy( mHeadersToEditorSplitter->sizePolicy().horData(), TQSizePolicy::Maximum );
202 TQVBoxLayout *v =
new TQVBoxLayout( mMainWidget );
203 v->addWidget( mHeadersToEditorSplitter );
204 mIdentity =
new KPIM::IdentityCombo(kmkernel->identityManager(), mHeadersArea);
205 TQToolTip::add( mIdentity,
206 i18n(
"Select an identity for this message" ) );
209 TQToolTip::add( mDictionaryCombo,
210 i18n(
"Select the dictionary to use when spell-checking this message" ) );
212 mFcc =
new KMFolderComboBox(mHeadersArea);
213 mFcc->showOutboxFolder(
false );
214 TQToolTip::add( mFcc,
215 i18n(
"Select the sent-mail folder where a copy of this message will be saved" ) );
217 mTransport =
new TQComboBox(
true, mHeadersArea);
218 TQToolTip::add( mTransport,
219 i18n(
"Select the outgoing account to use for sending this message" ) );
221 mEdtFrom =
new KMLineEdit(
false,mHeadersArea,
"fromLine");
222 TQToolTip::add( mEdtFrom,
223 i18n(
"Set the \"From:\" email address for this message" ) );
225 mEdtReplyTo =
new KMLineEdit(
true,mHeadersArea,
"replyToLine");
226 TQToolTip::add( mEdtReplyTo,
227 i18n(
"Set the \"Reply-To:\" email address for this message" ) );
228 connect(mEdtReplyTo,TQ_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
229 TQ_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
231 if ( mClassicalRecipients ) {
232 mRecipientsEditor = 0;
234 mEdtTo =
new KMLineEdit(
true,mHeadersArea,
"toLine");
235 mEdtCc =
new KMLineEdit(
true,mHeadersArea,
"ccLine");
236 mEdtBcc =
new KMLineEdit(
true,mHeadersArea,
"bccLine");
238 mLblTo =
new TQLabel(mHeadersArea);
239 mLblCc =
new TQLabel(mHeadersArea);
240 mLblBcc =
new TQLabel(mHeadersArea);
242 mBtnTo =
new TQPushButton(
"...",mHeadersArea);
243 mBtnCc =
new TQPushButton(
"...",mHeadersArea);
244 mBtnBcc =
new TQPushButton(
"...",mHeadersArea);
247 TQString tip = i18n(
"Select email address(es)");
248 TQToolTip::add( mBtnTo, tip );
249 TQToolTip::add( mBtnCc, tip );
250 TQToolTip::add( mBtnBcc, tip );
252 mBtnTo->setFocusPolicy(TQWidget::NoFocus);
253 mBtnCc->setFocusPolicy(TQWidget::NoFocus);
254 mBtnBcc->setFocusPolicy(TQWidget::NoFocus);
257 connect(mBtnTo,TQ_SIGNAL(clicked()),TQ_SLOT(slotAddrBookTo()));
258 connect(mBtnCc,TQ_SIGNAL(clicked()),TQ_SLOT(slotAddrBookTo()));
259 connect(mBtnBcc,TQ_SIGNAL(clicked()),TQ_SLOT(slotAddrBookTo()));
262 connect(mEdtTo,TQ_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
263 TQ_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
264 connect(mEdtCc,TQ_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
265 TQ_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
266 connect(mEdtBcc,TQ_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
267 TQ_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
284 mRecipientsEditor =
new RecipientsEditor( mHeadersArea );
285 connect( mRecipientsEditor,
286 TQ_SIGNAL( completionModeChanged( TDEGlobalSettings::Completion ) ),
287 TQ_SLOT( slotCompletionModeChanged( TDEGlobalSettings::Completion ) ) );
288 connect( mRecipientsEditor, TQ_SIGNAL(sizeHintChanged()), TQ_SLOT(recipientEditorSizeHintChanged()) );
290 mRecipientsEditor->setFocus();
292 mEdtSubject =
new KMLineEditSpell(
false,mHeadersArea,
"subjectLine");
293 TQToolTip::add( mEdtSubject,
294 i18n(
"Set a subject for this message" ) );
296 mLblIdentity =
new TQLabel( i18n(
"&Identity:"), mHeadersArea );
297 mDictionaryLabel =
new TQLabel( i18n(
"&Dictionary:"), mHeadersArea );
298 mLblFcc =
new TQLabel( i18n(
"&Sent-Mail folder:"), mHeadersArea );
299 mLblTransport =
new TQLabel( i18n(
"&Mail transport:"), mHeadersArea );
300 mLblFrom =
new TQLabel( i18n(
"sender address field",
"&From:"), mHeadersArea );
301 mLblReplyTo =
new TQLabel( i18n(
"&Reply to:"), mHeadersArea );
302 mLblSubject =
new TQLabel( i18n(
"S&ubject:"), mHeadersArea );
304 TQString sticky = i18n(
"Sticky");
305 mBtnIdentity =
new TQCheckBox(sticky,mHeadersArea);
306 TQToolTip::add( mBtnIdentity,
307 i18n(
"Use the selected value as your identity for future messages" ) );
308 mBtnFcc =
new TQCheckBox(sticky,mHeadersArea);
309 TQToolTip::add( mBtnFcc,
310 i18n(
"Use the selected value as your sent-mail folder for future messages" ) );
311 mBtnTransport =
new TQCheckBox(sticky,mHeadersArea);
312 TQToolTip::add( mBtnTransport,
313 i18n(
"Use the selected value as your outgoing account for future messages" ) );
314 mBtnDictionary =
new TQCheckBox( sticky, mHeadersArea );
315 TQToolTip::add( mBtnDictionary,
316 i18n(
"Use the selected value as your dictionary for future messages" ) );
319 mHtmlMarkup = GlobalSettings::self()->useHtmlMarkup();
320 mShowHeaders = GlobalSettings::self()->headers();
324 mAtmList.setAutoDelete(
true);
325 mAtmTempList.setAutoDelete(
true);
326 mAtmModified =
false;
327 mAutoDeleteMsg =
false;
330 mFixedFontAction = 0;
333 mSplitter =
new TQSplitter( TQt::Vertical, mHeadersToEditorSplitter,
"mSplitter" );
334 mSplitter->setChildrenCollapsible(
false );
335 mSnippetSplitter =
new TQSplitter( TQt::Horizontal, mSplitter,
"mSnippetSplitter");
336 mSnippetSplitter->setChildrenCollapsible(
false );
338 TQWidget *editorAndCryptoStateIndicators =
new TQWidget( mSnippetSplitter );
339 TQVBoxLayout *vbox =
new TQVBoxLayout( editorAndCryptoStateIndicators );
340 TQHBoxLayout *hbox =
new TQHBoxLayout( vbox );
342 mSignatureStateIndicator =
new TQLabel( editorAndCryptoStateIndicators );
343 mSignatureStateIndicator->setAlignment( TQt::AlignHCenter );
344 hbox->addWidget( mSignatureStateIndicator );
346 TDEConfigGroup reader( KMKernel::config(),
"Reader" );
347 TQPalette p( mSignatureStateIndicator->palette() );
349 TQColor defaultSignedColor( 0x40, 0xFF, 0x40 );
350 TQColor defaultEncryptedColor( 0x00, 0x80, 0xFF );
351 p.setColor( TQColorGroup::Background, reader.readColorEntry(
"PGPMessageOkKeyOk", &defaultSignedColor ) );
352 mSignatureStateIndicator->setPalette( p );
354 mEncryptionStateIndicator =
new TQLabel( editorAndCryptoStateIndicators );
355 mEncryptionStateIndicator->setAlignment( TQt::AlignHCenter );
356 hbox->addWidget( mEncryptionStateIndicator );
357 p.setColor( TQColorGroup::Background, reader.readColorEntry(
"PGPMessageEncr" , &defaultEncryptedColor ) );
358 mEncryptionStateIndicator->setPalette( p );
361 mEditor =
new KMEdit( editorAndCryptoStateIndicators,
this, mDictionaryCombo->spellConfig() );
362 vbox->addWidget( mEditor );
364 mSnippetWidget =
new SnippetWidget( mEditor, actionCollection(), mSnippetSplitter );
365 mSnippetWidget->setShown( GlobalSettings::self()->showSnippetManager() );
368 mSplitter->setOpaqueResize(
true );
370 mEditor->initializeAutoSpellChecking();
371 mEditor->setTextFormat(TQt::PlainText);
372 mEditor->setAcceptDrops(
true );
374 TQWhatsThis::add( mBtnIdentity,
375 GlobalSettings::self()->stickyIdentityItem()->whatsThis() );
376 TQWhatsThis::add( mBtnFcc,
377 GlobalSettings::self()->stickyFccItem()->whatsThis() );
378 TQWhatsThis::add( mBtnTransport,
379 GlobalSettings::self()->stickyTransportItem()->whatsThis() );
380 TQWhatsThis::add( mBtnTransport,
381 GlobalSettings::self()->stickyDictionaryItem()->whatsThis() );
383 mSpellCheckInProgress=
false;
385 setCaption( i18n(
"Composer") );
386 setMinimumSize(200,200);
388 mBtnIdentity->setFocusPolicy(TQWidget::NoFocus);
389 mBtnFcc->setFocusPolicy(TQWidget::NoFocus);
390 mBtnTransport->setFocusPolicy(TQWidget::NoFocus);
391 mBtnDictionary->setFocusPolicy( TQWidget::NoFocus );
393 mAtmListView =
new AttachmentListView(
this, mSplitter,
394 "attachment list view" );
395 mAtmListView->setSelectionMode( TQListView::Extended );
396 mAtmListView->addColumn( i18n(
"Name"), 200 );
397 mAtmListView->addColumn( i18n(
"Size"), 80 );
398 mAtmListView->addColumn( i18n(
"Encoding"), 120 );
399 int atmColType = mAtmListView->addColumn( i18n(
"Type"), 120 );
401 mAtmListView->header()->setStretchEnabled(
true, atmColType );
402 mAtmEncryptColWidth = 80;
403 mAtmSignColWidth = 80;
404 mAtmCompressColWidth = 100;
405 mAtmColCompress = mAtmListView->addColumn( i18n(
"Compress"),
406 mAtmCompressColWidth );
407 mAtmColEncrypt = mAtmListView->addColumn( i18n(
"Encrypt"),
408 mAtmEncryptColWidth );
409 mAtmColSign = mAtmListView->addColumn( i18n(
"Sign"),
411 mAtmListView->setColumnWidth( mAtmColEncrypt, 0 );
412 mAtmListView->setColumnWidth( mAtmColSign, 0 );
413 mAtmListView->setAllColumnsShowFocus(
true );
415 connect( mAtmListView,
416 TQ_SIGNAL( doubleClicked( TQListViewItem* ) ),
417 TQ_SLOT( slotAttachEdit() ) );
418 connect( mAtmListView,
419 TQ_SIGNAL( rightButtonPressed( TQListViewItem*,
const TQPoint&,
int ) ),
420 TQ_SLOT( slotAttachPopupMenu( TQListViewItem*,
const TQPoint&,
int ) ) );
421 connect( mAtmListView,
422 TQ_SIGNAL( selectionChanged() ),
423 TQ_SLOT( slotUpdateAttachActions() ) );
424 connect( mAtmListView,
425 TQ_SIGNAL( attachmentDeleted() ),
426 TQ_SLOT( slotAttachRemove() ) );
427 connect( mAtmListView,
428 TQ_SIGNAL( dragStarted() ),
429 TQ_SLOT( slotAttachmentDragStarted() ) );
436 slotUpdateSignatureAndEncrypionStateIndicators();
438 applyMainWindowSettings(KMKernel::config(),
"Composer");
440 connect( mEdtSubject, TQ_SIGNAL( subjectTextSpellChecked() ),
441 TQ_SLOT( slotSubjectTextSpellChecked() ) );
442 connect(mEdtSubject,TQ_SIGNAL(textChanged(
const TQString&)),
443 TQ_SLOT(slotUpdWinTitle(
const TQString&)));
444 connect(mIdentity,TQ_SIGNAL(identityChanged(uint)),
445 TQ_SLOT(slotIdentityChanged(uint)));
446 connect( kmkernel->identityManager(), TQ_SIGNAL(changed(uint)),
447 TQ_SLOT(slotIdentityChanged(uint)));
449 connect(mEdtFrom,TQ_SIGNAL(completionModeChanged(TDEGlobalSettings::Completion)),
450 TQ_SLOT(slotCompletionModeChanged(TDEGlobalSettings::Completion)));
451 connect(kmkernel->folderMgr(),TQ_SIGNAL(folderRemoved(
KMFolder*)),
452 TQ_SLOT(slotFolderRemoved(
KMFolder*)));
453 connect(kmkernel->imapFolderMgr(),TQ_SIGNAL(folderRemoved(
KMFolder*)),
454 TQ_SLOT(slotFolderRemoved(
KMFolder*)));
455 connect(kmkernel->dimapFolderMgr(),TQ_SIGNAL(folderRemoved(
KMFolder*)),
456 TQ_SLOT(slotFolderRemoved(
KMFolder*)));
457 connect( kmkernel, TQ_SIGNAL( configChanged() ),
458 this, TQ_SLOT( slotConfigChanged() ) );
460 connect (mEditor, TQ_SIGNAL (spellcheck_done(
int)),
461 this, TQ_SLOT (slotSpellcheckDone (
int)));
462 connect (mEditor, TQ_SIGNAL( attachPNGImageData(
const TQByteArray &) ),
463 this, TQ_SLOT ( slotAttachPNGImageData(
const TQByteArray &) ) );
464 connect (mEditor, TQ_SIGNAL( focusChanged(
bool) ),
465 this, TQ_SLOT (editorFocusChanged(
bool)) );
467 mMainWidget->resize(480,510);
468 setCentralWidget(mMainWidget);
471 if ( !mClassicalRecipients ) {
477 if ( GlobalSettings::self()->useExternalEditor() ) {
478 mEditor->setUseExternalEditor(
true);
479 mEditor->setExternalEditorPath( GlobalSettings::self()->externalEditor() );
483 slotUpdateSignatureActions();
487 fontChanged( mEditor->currentFont() );
493 KMComposeWin::~KMComposeWin()
498 mAutoDeleteMsg =
false;
499 mFolder->addMsg(mMsg);
501 mFolder->unGetMsg( mFolder->count() - 1 );
503 if (mAutoDeleteMsg) {
507 TQMap<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.begin();
508 while ( it != mMapAtmLoadData.end() )
510 TDEIO::Job *job = it.key();
511 mMapAtmLoadData.remove( it );
513 it = mMapAtmLoadData.begin();
515 deleteAll( mComposedMessages );
517 for ( std::set<KTempDir*>::iterator it = mTempDirs.begin() ; it != mTempDirs.end() ; ++it ) {
522 void KMComposeWin::setAutoDeleteWindow(
bool f )
525 setWFlags( getWFlags() | WDestructiveClose );
527 setWFlags( getWFlags() & ~WDestructiveClose );
531 void KMComposeWin::send(
int how)
547 void KMComposeWin::addAttachmentsAndSend(
const KURL::List &urls,
const TQString &,
int how)
554 mAttachFilesSend = how;
555 mAttachFilesPending = urls;
556 connect(
this, TQ_SIGNAL(attachmentAdded(
const KURL&,
bool)), TQ_SLOT(slotAttachedFile(
const KURL&)));
557 for( KURL::List::ConstIterator itr = urls.begin(); itr != urls.end(); ++itr ) {
558 if (!addAttach( *itr ))
559 mAttachFilesPending.remove(mAttachFilesPending.find(*itr));
562 if (mAttachFilesPending.isEmpty() && mAttachFilesSend == how)
564 send(mAttachFilesSend);
565 mAttachFilesSend = -1;
569 void KMComposeWin::slotAttachedFile(
const KURL &url)
571 if (mAttachFilesPending.isEmpty())
573 mAttachFilesPending.remove(mAttachFilesPending.find(url));
574 if (mAttachFilesPending.isEmpty())
576 send(mAttachFilesSend);
577 mAttachFilesSend = -1;
582 void KMComposeWin::addAttachment(KURL url,TQString )
588 void KMComposeWin::addAttachment(
const TQString &name,
590 const TQByteArray &data,
591 const TQCString &type,
592 const TQCString &subType,
593 const TQCString ¶mAttr,
594 const TQString ¶mValue,
595 const TQCString &contDisp)
597 if (!data.isEmpty()) {
598 KMMessagePart *msgPart =
new KMMessagePart;
599 msgPart->setName(name);
600 if( type ==
"message" && subType ==
"rfc822" ) {
601 msgPart->setMessageBody( data );
603 TQValueList<int> dummy;
604 msgPart->setBodyAndGuessCte(data, dummy,
605 kmkernel->msgSender()->sendQuotedPrintable());
607 msgPart->setTypeStr(type);
608 msgPart->setSubtypeStr(subType);
609 msgPart->setParameter(paramAttr,paramValue);
610 msgPart->setContentDisposition(contDisp);
616 void KMComposeWin::slotAttachPNGImageData(
const TQByteArray &image)
620 TQString attName = KInputDialog::getText(
"KMail", i18n(
"Name of the attachment:"), TQString(), &ok,
this );
624 if ( !attName.lower().endsWith(
".png") ) attName +=
".png";
626 addAttachment( attName,
"base64", image,
"image",
"png", TQCString(), TQString(), TQCString() );
630 void KMComposeWin::setBody(TQString body)
632 mEditor->setText(body);
636 bool KMComposeWin::event(TQEvent *e)
638 if (e->type() == TQEvent::ApplicationPaletteChange)
642 return KMail::Composer::event(e);
647 void KMComposeWin::readColorConfig(
void)
649 if ( GlobalSettings::self()->useDefaultColors() ) {
650 mForeColor = TQColor(kapp->palette().active().text());
651 mBackColor = TQColor(kapp->palette().active().base());
653 mForeColor = GlobalSettings::self()->foregroundColor();
654 mBackColor = GlobalSettings::self()->backgroundColor();
658 mPalette = kapp->palette();
659 TQColorGroup cgrp = mPalette.active();
660 cgrp.setColor( TQColorGroup::Base, mBackColor);
661 cgrp.setColor( TQColorGroup::Text, mForeColor);
662 mPalette.setDisabled(cgrp);
663 mPalette.setActive(cgrp);
664 mPalette.setInactive(cgrp);
666 mEdtFrom->setPalette(mPalette);
667 mEdtReplyTo->setPalette(mPalette);
668 if ( mClassicalRecipients ) {
669 mEdtTo->setPalette(mPalette);
670 mEdtCc->setPalette(mPalette);
671 mEdtBcc->setPalette(mPalette);
673 mEdtSubject->setPalette(mPalette);
674 mTransport->setPalette(mPalette);
675 mEditor->setPalette(mPalette);
676 mFcc->setPalette(mPalette);
680 void KMComposeWin::readConfig(
bool reload )
683 mBtnIdentity->setChecked( GlobalSettings::self()->stickyIdentity() );
684 if (mBtnIdentity->isChecked()) {
685 mId = (GlobalSettings::self()->previousIdentity()!=0) ?
686 GlobalSettings::self()->previousIdentity() : mId;
688 mBtnFcc->setChecked( GlobalSettings::self()->stickyFcc() );
689 mBtnTransport->setChecked( GlobalSettings::self()->stickyTransport() );
690 mBtnDictionary->setChecked( GlobalSettings::self()->stickyDictionary() );
691 TQStringList transportHistory = GlobalSettings::self()->transportHistory();
692 TQString currentTransport = GlobalSettings::self()->currentTransport();
694 mEdtFrom->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
695 mEdtReplyTo->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
696 if ( mClassicalRecipients ) {
697 mEdtTo->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
698 mEdtCc->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
699 mEdtBcc->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
702 mRecipientsEditor->setCompletionMode( (TDEGlobalSettings::Completion)GlobalSettings::self()->completionMode() );
706 if ( GlobalSettings::self()->useDefaultFonts() ) {
707 mBodyFont = TDEGlobalSettings::generalFont();
708 mFixedFont = TDEGlobalSettings::fixedFont();
710 mBodyFont = GlobalSettings::self()->composerFont();
711 mFixedFont = GlobalSettings::self()->fixedFont();
715 mEdtFrom->setFont(mBodyFont);
716 mEdtReplyTo->setFont(mBodyFont);
717 if ( mClassicalRecipients ) {
718 mEdtTo->setFont(mBodyFont);
719 mEdtCc->setFont(mBodyFont);
720 mEdtBcc->setFont(mBodyFont);
722 mEdtSubject->setFont(mBodyFont);
725 TQSize siz = GlobalSettings::self()->composerSize();
726 if (siz.width() < 200) siz.setWidth(200);
727 if (siz.height() < 200) siz.setHeight(200);
730 if ( !GlobalSettings::self()->snippetSplitterPosition().isEmpty() ) {
731 mSnippetSplitter->setSizes( GlobalSettings::self()->snippetSplitterPosition() );
733 TQValueList<int> defaults;
734 defaults << (int)(width() * 0.8) << (int)(width() * 0.2);
735 mSnippetSplitter->setSizes( defaults );
739 mIdentity->setCurrentIdentity( mId );
741 kdDebug(5006) <<
"KMComposeWin::readConfig. " << mIdentity->currentIdentityName() << endl;
742 const KPIM::Identity & ident =
743 kmkernel->identityManager()->identityForUoid( mIdentity->currentIdentity() );
746 mTransport->insertStringList( KMTransportInfo::availableTransports() );
747 while ( transportHistory.count() > (uint)GlobalSettings::self()->maxTransportEntries() )
748 transportHistory.remove( transportHistory.last() );
749 mTransport->insertStringList( transportHistory );
750 mTransport->setCurrentText( GlobalSettings::self()->defaultTransport() );
751 if ( mBtnTransport->isChecked() ) {
752 setTransport( currentTransport );
755 if ( mBtnDictionary->isChecked() ) {
756 mDictionaryCombo->setCurrentByDictionaryName( GlobalSettings::self()->previousDictionary() );
758 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
761 TQString fccName =
"";
762 if ( mBtnFcc->isChecked() ) {
763 fccName = GlobalSettings::self()->previousFcc();
764 }
else if ( !ident.fcc().isEmpty() ) {
765 fccName = ident.fcc();
772 void KMComposeWin::writeConfig(
void)
774 GlobalSettings::self()->setHeaders( mShowHeaders );
775 GlobalSettings::self()->setStickyFcc( mBtnFcc->isChecked() );
776 if ( !mIgnoreStickyFields ) {
777 GlobalSettings::self()->setCurrentTransport( mTransport->currentText() );
778 GlobalSettings::self()->setStickyTransport( mBtnTransport->isChecked() );
779 GlobalSettings::self()->setStickyDictionary( mBtnDictionary->isChecked() );
780 GlobalSettings::self()->setStickyIdentity( mBtnIdentity->isChecked() );
781 GlobalSettings::self()->setPreviousIdentity( mIdentity->currentIdentity() );
783 GlobalSettings::self()->setPreviousFcc( mFcc->getFolder()->idString() );
784 GlobalSettings::self()->setPreviousDictionary( mDictionaryCombo->currentDictionaryName() );
785 GlobalSettings::self()->setAutoSpellChecking(
786 mAutoSpellCheckingAction->isChecked() );
787 TQStringList transportHistory = GlobalSettings::self()->transportHistory();
788 transportHistory.remove(mTransport->currentText());
789 if (KMTransportInfo::availableTransports().findIndex(mTransport
790 ->currentText()) == -1) {
791 transportHistory.prepend(mTransport->currentText());
793 GlobalSettings::self()->setTransportHistory( transportHistory );
794 GlobalSettings::self()->setUseFixedFont( mFixedFontAction->isChecked() );
795 GlobalSettings::self()->setUseHtmlMarkup( mHtmlMarkup );
796 GlobalSettings::self()->setComposerSize( size() );
797 GlobalSettings::self()->setShowSnippetManager( mSnippetAction->isChecked() );
799 TDEConfigGroupSaver saver( KMKernel::config(),
"Geometry" );
800 saveMainWindowSettings( KMKernel::config(),
"Composer" );
801 GlobalSettings::setSnippetSplitterPosition( mSnippetSplitter->sizes() );
804 GlobalSettings::self()->writeConfig();
808 void KMComposeWin::autoSaveMessage()
810 kdDebug(5006) << k_funcinfo << endl;
811 if ( !mMsg || mComposer || mAutoSaveFilename.isEmpty() )
813 kdDebug(5006) << k_funcinfo <<
"autosaving message" << endl;
815 if ( mAutoSaveTimer )
816 mAutoSaveTimer->stop();
818 connect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
819 this, TQ_SLOT( slotContinueAutoSave() ) );
823 applyChanges(
true,
true );
828 void KMComposeWin::slotContinueAutoSave()
830 disconnect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
831 this, TQ_SLOT( slotContinueAutoSave() ) );
834 if ( mComposedMessages.isEmpty() ) {
835 kdDebug(5006) <<
"Composing the message failed." << endl;
838 KMMessage *msg = mComposedMessages.first();
842 kdDebug(5006) << k_funcinfo <<
"opening autoSaveFile " << mAutoSaveFilename
844 const TQString filename =
846 KSaveFile autoSaveFile( filename, 0600 );
847 int status = autoSaveFile.status();
848 kdDebug(5006) << k_funcinfo <<
"autoSaveFile.status() = " << status << endl;
850 kdDebug(5006) <<
"autosaving message in " << filename << endl;
851 int fd = autoSaveFile.handle();
853 if ( ::write( fd, msgStr.data(), msgStr.length() ) == -1 )
857 kdDebug(5006) << k_funcinfo <<
"closing autoSaveFile" << endl;
858 autoSaveFile.close();
859 mLastAutoSaveErrno = 0;
862 kdDebug(5006) << k_funcinfo <<
"autosaving failed" << endl;
863 autoSaveFile.abort();
864 if ( status != mLastAutoSaveErrno ) {
866 KMessageBox::queuedMessageBox( 0, KMessageBox::Sorry,
867 i18n(
"Autosaving the message as %1 "
870 .arg( filename, strerror( status ) ),
871 i18n(
"Autosaving Failed") );
872 mLastAutoSaveErrno = status;
876 if ( autoSaveInterval() > 0 )
881 void KMComposeWin::slotView(
void)
890 if (!sender()->isA(
"TDEToggleAction"))
892 TDEToggleAction *act = (TDEToggleAction *) sender();
894 if (act == mAllFieldsAction)
896 else if (act == mIdentityAction)
898 else if (act == mTransportAction)
900 else if (act == mFromAction)
902 else if (act == mReplyToAction)
904 else if (act == mToAction)
906 else if (act == mCcAction)
908 else if (act == mBccAction)
910 else if (act == mSubjectAction)
912 else if (act == mFccAction)
914 else if ( act == mDictionaryAction )
919 kdDebug(5006) <<
"Something is wrong (Oh, yeah?)" << endl;
926 if (!act->isChecked())
929 if (
id > 0) mShowHeaders = mShowHeaders & ~id;
930 else mShowHeaders = abs(mShowHeaders);
935 if (
id > 0) mShowHeaders |= id;
936 else mShowHeaders = -abs(mShowHeaders);
941 int KMComposeWin::calcColumnWidth(
int which,
long allShowing,
int width)
943 if ( (allShowing & which) == 0 )
947 if ( which == HDR_IDENTITY )
949 else if ( which == HDR_DICTIONARY )
950 w = mDictionaryLabel;
951 else if ( which == HDR_FCC )
953 else if ( which == HDR_TRANSPORT )
955 else if ( which == HDR_FROM )
957 else if ( which == HDR_REPLY_TO )
959 else if ( which == HDR_SUBJECT )
964 w->setBuddy( mEditor );
967 return TQMAX( width, w->sizeHint().width() );
970 void KMComposeWin::rethinkFields(
bool fromSlot)
973 int mask, row, numRows;
976 if (mShowHeaders < 0)
977 showHeaders = HDR_ALL;
979 showHeaders = mShowHeaders;
981 for (mask=1,mNumHeaders=0; mask<=showHeaders; mask<<=1)
982 if ((showHeaders&mask) != 0) mNumHeaders++;
984 numRows = mNumHeaders + 1;
988 mGrid =
new TQGridLayout( mHeadersArea, numRows, 3, KDialogBase::marginHint()/2, KDialogBase::spacingHint());
989 mGrid->setColStretch(0, 1);
990 mGrid->setColStretch(1, 100);
991 mGrid->setColStretch(2, 1);
992 mGrid->setRowStretch( mNumHeaders + 1, 100 );
995 kdDebug(5006) <<
"KMComposeWin::rethinkFields" << endl;
996 if (mRecipientsEditor)
997 mLabelWidth = mRecipientsEditor->setFirstColumnWidth( 0 );
998 mLabelWidth = calcColumnWidth( HDR_IDENTITY, showHeaders, mLabelWidth );
999 mLabelWidth = calcColumnWidth( HDR_DICTIONARY, showHeaders, mLabelWidth );
1000 mLabelWidth = calcColumnWidth( HDR_FCC, showHeaders, mLabelWidth );
1001 mLabelWidth = calcColumnWidth( HDR_TRANSPORT, showHeaders, mLabelWidth );
1002 mLabelWidth = calcColumnWidth( HDR_FROM, showHeaders, mLabelWidth );
1003 mLabelWidth = calcColumnWidth( HDR_REPLY_TO, showHeaders, mLabelWidth );
1004 mLabelWidth = calcColumnWidth( HDR_SUBJECT, showHeaders, mLabelWidth );
1006 if (!fromSlot) mAllFieldsAction->setChecked(showHeaders==HDR_ALL);
1008 if (!fromSlot) mIdentityAction->setChecked(abs(mShowHeaders)&HDR_IDENTITY);
1009 rethinkHeaderLine(showHeaders,HDR_IDENTITY, row,
1010 mLblIdentity, mIdentity, mBtnIdentity);
1012 if (!fromSlot) mDictionaryAction->setChecked(abs(mShowHeaders)&HDR_DICTIONARY);
1013 rethinkHeaderLine(showHeaders,HDR_DICTIONARY, row,
1014 mDictionaryLabel, mDictionaryCombo, mBtnDictionary );
1016 if (!fromSlot) mFccAction->setChecked(abs(mShowHeaders)&HDR_FCC);
1017 rethinkHeaderLine(showHeaders,HDR_FCC, row,
1018 mLblFcc, mFcc, mBtnFcc);
1020 if (!fromSlot) mTransportAction->setChecked(abs(mShowHeaders)&HDR_TRANSPORT);
1021 rethinkHeaderLine(showHeaders,HDR_TRANSPORT, row,
1022 mLblTransport, mTransport, mBtnTransport);
1024 if (!fromSlot) mFromAction->setChecked(abs(mShowHeaders)&HDR_FROM);
1025 rethinkHeaderLine(showHeaders,HDR_FROM, row,
1026 mLblFrom, mEdtFrom );
1028 TQWidget *prevFocus = mEdtFrom;
1030 if (!fromSlot) mReplyToAction->setChecked(abs(mShowHeaders)&HDR_REPLY_TO);
1031 rethinkHeaderLine(showHeaders,HDR_REPLY_TO,row,
1032 mLblReplyTo, mEdtReplyTo, 0);
1033 if ( showHeaders & HDR_REPLY_TO ) {
1034 prevFocus = connectFocusMoving( prevFocus, mEdtReplyTo );
1037 if ( mClassicalRecipients ) {
1038 if (!fromSlot) mToAction->setChecked(abs(mShowHeaders)&HDR_TO);
1039 rethinkHeaderLine(showHeaders, HDR_TO, row,
1040 mLblTo, mEdtTo, mBtnTo,
1041 i18n(
"Primary Recipients"),
1042 i18n(
"<qt>The email addresses you put "
1043 "in this field receive a copy of the email.</qt>"));
1044 if ( showHeaders & HDR_TO ) {
1045 prevFocus = connectFocusMoving( prevFocus, mEdtTo );
1048 if (!fromSlot) mCcAction->setChecked(abs(mShowHeaders)&HDR_CC);
1049 rethinkHeaderLine(showHeaders, HDR_CC, row,
1050 mLblCc, mEdtCc, mBtnCc,
1051 i18n(
"Additional Recipients"),
1052 i18n(
"<qt>The email addresses you put "
1053 "in this field receive a copy of the email. "
1054 "Technically it is the same thing as putting all the "
1055 "addresses in the <b>To:</b> field but differs in "
1056 "that it usually symbolises the receiver of the "
1057 "Carbon Copy (CC) is a listener, not the main "
1058 "recipient.</qt>"));
1059 if ( showHeaders & HDR_CC ) {
1060 prevFocus = connectFocusMoving( prevFocus, mEdtCc );
1063 if (!fromSlot) mBccAction->setChecked(abs(mShowHeaders)&HDR_BCC);
1064 rethinkHeaderLine(showHeaders,HDR_BCC, row,
1065 mLblBcc, mEdtBcc, mBtnBcc,
1066 i18n(
"Hidden Recipients"),
1067 i18n(
"<qt>Essentially the same thing "
1068 "as the <b>Copy To:</b> field but differs in that "
1069 "all other recipients do not see who receives a "
1070 "blind copy.</qt>"));
1071 if ( showHeaders & HDR_BCC ) {
1072 prevFocus = connectFocusMoving( prevFocus, mEdtBcc );
1075 mGrid->addMultiCellWidget( mRecipientsEditor, row, row, 0, 2 );
1078 if ( showHeaders & HDR_REPLY_TO ) {
1079 connect( mEdtReplyTo, TQ_SIGNAL( focusDown() ), mRecipientsEditor,
1080 TQ_SLOT( setFocusTop() ) );
1082 connect( mEdtFrom, TQ_SIGNAL( focusDown() ), mRecipientsEditor,
1083 TQ_SLOT( setFocusTop() ) );
1085 if ( showHeaders & HDR_REPLY_TO ) {
1086 connect( mRecipientsEditor, TQ_SIGNAL( focusUp() ), mEdtReplyTo, TQ_SLOT( setFocus() ) );
1088 connect( mRecipientsEditor, TQ_SIGNAL( focusUp() ), mEdtFrom, TQ_SLOT( setFocus() ) );
1091 connect( mRecipientsEditor, TQ_SIGNAL( focusDown() ), mEdtSubject,
1092 TQ_SLOT( setFocus() ) );
1093 connect( mEdtSubject, TQ_SIGNAL( focusUp() ), mRecipientsEditor,
1094 TQ_SLOT( setFocusBottom() ) );
1096 prevFocus = mRecipientsEditor;
1098 if (!fromSlot) mSubjectAction->setChecked(abs(mShowHeaders)&HDR_SUBJECT);
1099 rethinkHeaderLine(showHeaders,HDR_SUBJECT, row,
1100 mLblSubject, mEdtSubject);
1101 connectFocusMoving( mEdtSubject, mEditor );
1103 assert(row<=mNumHeaders);
1106 if( !mAtmList.isEmpty() )
1107 mAtmListView->show();
1109 mAtmListView->hide();
1110 resize(this->size());
1113 mHeadersArea->setMaximumHeight( mHeadersArea->sizeHint().height() );
1115 mHeadersArea->show();
1117 slotUpdateAttachActions();
1118 mIdentityAction->setEnabled(!mAllFieldsAction->isChecked());
1119 mDictionaryAction->setEnabled( !mAllFieldsAction->isChecked() );
1120 mTransportAction->setEnabled(!mAllFieldsAction->isChecked());
1121 mFromAction->setEnabled(!mAllFieldsAction->isChecked());
1122 if ( mReplyToAction ) mReplyToAction->setEnabled(!mAllFieldsAction->isChecked());
1123 if ( mToAction ) mToAction->setEnabled(!mAllFieldsAction->isChecked());
1124 if ( mCcAction ) mCcAction->setEnabled(!mAllFieldsAction->isChecked());
1125 if ( mBccAction ) mBccAction->setEnabled(!mAllFieldsAction->isChecked());
1126 mFccAction->setEnabled(!mAllFieldsAction->isChecked());
1127 mSubjectAction->setEnabled(!mAllFieldsAction->isChecked());
1128 if (mRecipientsEditor)
1129 mRecipientsEditor->setFirstColumnWidth( mLabelWidth );
1132 TQWidget *KMComposeWin::connectFocusMoving( TQWidget *prev, TQWidget *next )
1134 connect( prev, TQ_SIGNAL( focusDown() ), next, TQ_SLOT( setFocus() ) );
1135 connect( next, TQ_SIGNAL( focusUp() ), prev, TQ_SLOT( setFocus() ) );
1141 void KMComposeWin::rethinkHeaderLine(
int aValue,
int aMask,
int& aRow,
1143 TQLineEdit* aEdt, TQPushButton* aBtn,
1144 const TQString &toolTip,
const TQString &whatsThis )
1148 if ( !toolTip.isEmpty() )
1149 TQToolTip::add( aLbl, toolTip );
1150 if ( !whatsThis.isEmpty() )
1151 TQWhatsThis::add( aLbl, whatsThis );
1152 aLbl->setFixedWidth( mLabelWidth );
1153 aLbl->setBuddy(aEdt);
1154 mGrid->addWidget(aLbl, aRow, 0);
1155 aEdt->setBackgroundColor( mBackColor );
1159 mGrid->addWidget(aEdt, aRow, 1);
1161 mGrid->addWidget(aBtn, aRow, 2);
1164 mGrid->addMultiCellWidget(aEdt, aRow, aRow, 1, 2 );
1172 if (aBtn) aBtn->hide();
1177 void KMComposeWin::rethinkHeaderLine(
int aValue,
int aMask,
int& aRow,
1179 TQComboBox* aCbx, TQCheckBox* aChk)
1184 aLbl->resize((
int)aLbl->sizeHint().width(),aLbl->sizeHint().height() + 6);
1185 aLbl->setMinimumSize(aLbl->size());
1187 aLbl->setBuddy(aCbx);
1188 mGrid->addWidget(aLbl, aRow, 0);
1190 aCbx->setMinimumSize(100, aLbl->height()+2);
1192 mGrid->addWidget(aCbx, aRow, 1);
1194 mGrid->addWidget(aChk, aRow, 2);
1195 aChk->setFixedSize(aChk->sizeHint().width(), aLbl->height());
1210 void KMComposeWin::getTransportMenu()
1212 TQStringList availTransports;
1214 mActNowMenu->clear();
1215 mActLaterMenu->clear();
1217 TQStringList::Iterator it;
1219 for(it = availTransports.begin(); it != availTransports.end() ; ++it,
id++)
1221 mActNowMenu->insertItem((*it).replace(
"&",
"&&"),
id);
1222 mActLaterMenu->insertItem((*it).replace(
"&",
"&&"),
id);
1228 void KMComposeWin::setupActions(
void)
1230 TDEActionMenu *actActionNowMenu, *actActionLaterMenu;
1232 if (kmkernel->msgSender()->sendImmediate())
1235 ( void )
new TDEAction( i18n(
"&Send Mail"),
"mail-send", CTRL+Key_Return,
1236 this, TQ_SLOT(slotSendNow()), actionCollection(),
"send_default");
1239 actActionNowMenu =
new TDEActionMenu (i18n(
"&Send Mail Via"),
"mail-send",
1240 actionCollection(),
"send_default_via" );
1242 (void)
new TDEAction (i18n(
"Send &Later"),
"queue", 0,
this,
1243 TQ_SLOT(slotSendLater()), actionCollection(),
"send_alternative");
1244 actActionLaterMenu =
new TDEActionMenu (i18n(
"Send &Later Via"),
"queue",
1245 actionCollection(),
"send_alternative_via" );
1251 (void)
new TDEAction (i18n(
"Send &Later"),
"queue",
1253 this, TQ_SLOT(slotSendLater()), actionCollection(),
"send_default");
1254 actActionLaterMenu =
new TDEActionMenu (i18n(
"Send &Later Via"),
"queue",
1255 actionCollection(),
"send_default_via" );
1257 ( void )
new TDEAction( i18n(
"&Send Mail"),
"mail-send", 0,
1258 this, TQ_SLOT(slotSendNow()), actionCollection(),
"send_alternative");
1261 actActionNowMenu =
new TDEActionMenu (i18n(
"&Send Mail Via"),
"mail-send",
1262 actionCollection(),
"send_alternative_via" );
1267 actActionNowMenu->setDelayed(
true);
1268 actActionLaterMenu->setDelayed(
true);
1270 connect( actActionNowMenu, TQ_SIGNAL( activated() ),
this,
1271 TQ_SLOT( slotSendNow() ) );
1272 connect( actActionLaterMenu, TQ_SIGNAL( activated() ),
this,
1273 TQ_SLOT( slotSendLater() ) );
1276 mActNowMenu = actActionNowMenu->popupMenu();
1277 mActLaterMenu = actActionLaterMenu->popupMenu();
1279 connect( mActNowMenu, TQ_SIGNAL( activated(
int ) ),
this,
1280 TQ_SLOT( slotSendNowVia(
int ) ) );
1281 connect( mActNowMenu, TQ_SIGNAL( aboutToShow() ),
this,
1282 TQ_SLOT( getTransportMenu() ) );
1284 connect( mActLaterMenu, TQ_SIGNAL( activated(
int ) ),
this,
1285 TQ_SLOT( slotSendLaterVia(
int ) ) );
1286 connect( mActLaterMenu, TQ_SIGNAL( aboutToShow() ),
this,
1287 TQ_SLOT( getTransportMenu() ) );
1292 (void)
new TDEAction (i18n(
"Save as &Draft"),
"document-save", 0,
1293 this, TQ_SLOT(slotSaveDraft()),
1294 actionCollection(),
"save_in_drafts");
1295 (void)
new TDEAction (i18n(
"Save as &Template"),
"document-save", 0,
1296 this, TQ_SLOT(slotSaveTemplate()),
1297 actionCollection(),
"save_in_templates");
1298 (void)
new TDEAction (i18n(
"&Insert File..."),
"document-open", 0,
1299 this, TQ_SLOT(slotInsertFile()),
1300 actionCollection(),
"insert_file");
1301 mRecentAction =
new TDERecentFilesAction (i18n(
"&Insert File Recent"),
1303 this, TQ_SLOT(slotInsertRecentFile(
const KURL&)),
1304 actionCollection(),
"insert_file_recent");
1306 mRecentAction->loadEntries( KMKernel::config() );
1308 (void)
new TDEAction (i18n(
"&Address Book"),
"contents",0,
1309 this, TQ_SLOT(slotAddrBook()),
1310 actionCollection(),
"addressbook");
1311 (void)
new TDEAction (i18n(
"&New Composer"),
"mail-message-new",
1312 TDEStdAccel::shortcut(TDEStdAccel::New),
1313 this, TQ_SLOT(slotNewComposer()),
1314 actionCollection(),
"new_composer");
1315 (void)
new TDEAction (i18n(
"New Main &Window"),
"window-new", 0,
1316 this, TQ_SLOT(slotNewMailReader()),
1317 actionCollection(),
"open_mailreader");
1319 if ( !mClassicalRecipients ) {
1320 new TDEAction( i18n(
"Select &Recipients..."), CTRL + Key_L, mRecipientsEditor,
1321 TQ_SLOT( selectRecipients() ), actionCollection(),
"select_recipients" );
1322 new TDEAction( i18n(
"Save &Distribution List..."), 0, mRecipientsEditor,
1323 TQ_SLOT( saveDistributionList() ), actionCollection(),
1324 "save_distribution_list" );
1328 KStdAction::print (
this, TQ_SLOT(slotPrint()), actionCollection());
1329 KStdAction::close (
this, TQ_SLOT(slotClose()), actionCollection());
1331 KStdAction::undo (
this, TQ_SLOT(slotUndo()), actionCollection());
1332 KStdAction::redo (
this, TQ_SLOT(slotRedo()), actionCollection());
1333 KStdAction::cut (
this, TQ_SLOT(slotCut()), actionCollection());
1334 KStdAction::copy (
this, TQ_SLOT(slotCopy()), actionCollection());
1335 KStdAction::pasteText (
this, TQ_SLOT(slotPasteClipboard()), actionCollection());
1336 KStdAction::selectAll (
this, TQ_SLOT(slotMarkAll()), actionCollection());
1338 KStdAction::find (
this, TQ_SLOT(slotFind()), actionCollection());
1339 KStdAction::findNext(
this, TQ_SLOT(slotSearchAgain()), actionCollection());
1341 KStdAction::replace (
this, TQ_SLOT(slotReplace()), actionCollection());
1342 KStdAction::spelling (
this, TQ_SLOT(slotSpellcheck()), actionCollection(),
"tools-check-spelling");
1344 mPasteQuotation =
new TDEAction (i18n(
"Pa&ste as Quotation"),0,
this,TQ_SLOT( slotPasteClipboardAsQuotation()),
1345 actionCollection(),
"paste_quoted");
1347 (void)
new TDEAction (i18n(
"Paste as Attac&hment"),0,
this,TQ_SLOT( slotPasteClipboardAsAttachment()),
1348 actionCollection(),
"paste_att");
1350 TDEAction * addq =
new TDEAction(i18n(
"Add &Quote Characters"), 0,
this,
1351 TQ_SLOT(slotAddQuotes()), actionCollection(),
"tools_quote");
1352 connect( mEditor, TQ_SIGNAL(selectionAvailable(
bool)),
1353 addq, TQ_SLOT(setEnabled(
bool)) );
1355 TDEAction * remq =
new TDEAction(i18n(
"Re&move Quote Characters"), 0,
this,
1356 TQ_SLOT(slotRemoveQuotes()), actionCollection(),
"tools_unquote");
1357 connect( mEditor, TQ_SIGNAL(selectionAvailable(
bool)),
1358 remq, TQ_SLOT(setEnabled(
bool)) );
1361 (void)
new TDEAction (i18n(
"Cl&ean Spaces"), 0,
this, TQ_SLOT(slotCleanSpace()),
1362 actionCollection(),
"clean_spaces");
1364 mFixedFontAction =
new TDEToggleAction( i18n(
"Use Fi&xed Font"), 0,
this,
1365 TQ_SLOT(slotUpdateFont()), actionCollection(),
"toggle_fixedfont" );
1366 mFixedFontAction->setChecked( GlobalSettings::self()->useFixedFont() );
1369 mUrgentAction =
new TDEToggleAction (i18n(
"&Urgent"), 0,
1372 mRequestMDNAction =
new TDEToggleAction ( i18n(
"&Request Disposition Notification"), 0,
1374 "options_request_mdn");
1375 mRequestMDNAction->setChecked(GlobalSettings::self()->requestMDN());
1377 mEncodingAction =
new TDESelectAction( i18n(
"Se&t Encoding" ),
"charset",
1378 0,
this, TQ_SLOT(slotSetCharset() ),
1379 actionCollection(),
"charsets" );
1380 mWordWrapAction =
new TDEToggleAction (i18n(
"&Wordwrap"), 0,
1381 actionCollection(),
"wordwrap");
1382 mWordWrapAction->setChecked(GlobalSettings::self()->wordWrap());
1383 connect(mWordWrapAction, TQ_SIGNAL(toggled(
bool)), TQ_SLOT(slotWordWrapToggled(
bool)));
1385 mSnippetAction =
new TDEToggleAction ( i18n(
"&Snippets"), 0,
1386 actionCollection(),
"snippets");
1387 connect(mSnippetAction, TQ_SIGNAL(toggled(
bool)), mSnippetWidget, TQ_SLOT(setShown(
bool)) );
1388 mSnippetAction->setChecked( GlobalSettings::self()->showSnippetManager() );
1390 mAutoSpellCheckingAction =
1391 new TDEToggleAction( i18n(
"&Automatic Spellchecking" ),
"tools-check-spelling", 0,
1392 actionCollection(),
"options_auto_spellchecking" );
1393 const bool spellChecking = GlobalSettings::self()->autoSpellChecking();
1394 mAutoSpellCheckingAction->setEnabled( !GlobalSettings::self()->useExternalEditor() );
1395 mAutoSpellCheckingAction->setChecked( !GlobalSettings::self()->useExternalEditor() && spellChecking );
1396 slotAutoSpellCheckingToggled( !GlobalSettings::self()->useExternalEditor() && spellChecking );
1397 connect( mAutoSpellCheckingAction, TQ_SIGNAL( toggled(
bool ) ),
1398 this, TQ_SLOT( slotAutoSpellCheckingToggled(
bool ) ) );
1400 TQStringList encodings = KMMsgBase::supportedEncodings(
true);
1401 encodings.prepend( i18n(
"Auto-Detect"));
1402 mEncodingAction->setItems( encodings );
1403 mEncodingAction->setCurrentItem( -1 );
1406 markupAction =
new TDEToggleAction (i18n(
"Formatting (HTML)"), 0,
this,
1407 TQ_SLOT(slotToggleMarkup()),
1408 actionCollection(),
"html");
1410 mAllFieldsAction =
new TDEToggleAction (i18n(
"&All Fields"), 0,
this,
1411 TQ_SLOT(slotView()),
1412 actionCollection(),
"show_all_fields");
1413 mIdentityAction =
new TDEToggleAction (i18n(
"&Identity"), 0,
this,
1414 TQ_SLOT(slotView()),
1415 actionCollection(),
"show_identity");
1416 mDictionaryAction =
new TDEToggleAction (i18n(
"&Dictionary"), 0,
this,
1417 TQ_SLOT(slotView()),
1418 actionCollection(),
"show_dictionary");
1419 mFccAction =
new TDEToggleAction (i18n(
"&Sent-Mail Folder"), 0,
this,
1420 TQ_SLOT(slotView()),
1421 actionCollection(),
"show_fcc");
1422 mTransportAction =
new TDEToggleAction (i18n(
"&Mail Transport"), 0,
this,
1423 TQ_SLOT(slotView()),
1424 actionCollection(),
"show_transport");
1425 mFromAction =
new TDEToggleAction (i18n(
"&From"), 0,
this,
1426 TQ_SLOT(slotView()),
1427 actionCollection(),
"show_from");
1428 mReplyToAction =
new TDEToggleAction (i18n(
"&Reply To"), 0,
this,
1429 TQ_SLOT(slotView()),
1430 actionCollection(),
"show_reply_to");
1431 if ( mClassicalRecipients ) {
1432 mToAction =
new TDEToggleAction (i18n(
"&To"), 0,
this,
1433 TQ_SLOT(slotView()),
1434 actionCollection(),
"show_to");
1435 mCcAction =
new TDEToggleAction (i18n(
"&CC"), 0,
this,
1436 TQ_SLOT(slotView()),
1437 actionCollection(),
"show_cc");
1438 mBccAction =
new TDEToggleAction (i18n(
"&BCC"), 0,
this,
1439 TQ_SLOT(slotView()),
1440 actionCollection(),
"show_bcc");
1442 mSubjectAction =
new TDEToggleAction (i18n(
"S&ubject"), 0,
this,
1443 TQ_SLOT(slotView()),
1444 actionCollection(),
"show_subject");
1447 mAppendSignatureAction =
new TDEAction (i18n(
"Append S&ignature"), 0,
this,
1448 TQ_SLOT(slotAppendSignature()),
1449 actionCollection(),
"append_signature");
1450 mPrependSignatureAction =
new TDEAction (i18n(
"Prepend S&ignature"), 0,
this,
1451 TQ_SLOT(slotPrependSignature()),
1452 actionCollection(),
"prepend_signature");
1454 mInsertSignatureAction =
new TDEAction (i18n(
"Insert Signature At C&ursor Position"),
"edit", 0,
this,
1455 TQ_SLOT(slotInsertSignatureAtCursor()),
1456 actionCollection(),
"insert_signature_at_cursor_position");
1458 mAttachPK =
new TDEAction (i18n(
"Attach &Public Key..."), 0,
this,
1459 TQ_SLOT(slotInsertPublicKey()),
1460 actionCollection(),
"attach_public_key");
1461 mAttachMPK =
new TDEAction (i18n(
"Attach &My Public Key"), 0,
this,
1462 TQ_SLOT(slotInsertMyPublicKey()),
1463 actionCollection(),
"attach_my_public_key");
1464 (void)
new TDEAction (i18n(
"&Attach File..."),
"attach",
1465 0,
this, TQ_SLOT(slotAttachFile()),
1466 actionCollection(),
"attach");
1467 mAttachRemoveAction =
new TDEAction (i18n(
"&Remove Attachment"), 0,
this,
1468 TQ_SLOT(slotAttachRemove()),
1469 actionCollection(),
"remove");
1470 mAttachSaveAction =
new TDEAction (i18n(
"&Save Attachment As..."),
"document-save",0,
1471 this, TQ_SLOT(slotAttachSave()),
1472 actionCollection(),
"attach_save");
1473 mAttachPropertiesAction =
new TDEAction (i18n(
"Attachment Pr&operties"), 0,
this,
1474 TQ_SLOT(slotAttachProperties()),
1475 actionCollection(),
"attach_properties");
1477 setStandardToolBarMenuEnabled(
true);
1479 KStdAction::keyBindings(
this, TQ_SLOT(slotEditKeys()), actionCollection());
1480 KStdAction::configureToolbars(
this, TQ_SLOT(slotEditToolbars()), actionCollection());
1481 KStdAction::preferences(kmkernel, TQ_SLOT(slotShowConfigurationDialog()), actionCollection());
1483 (void)
new TDEAction (i18n(
"&Spellchecker..."), 0,
this, TQ_SLOT(slotSpellcheckConfig()),
1484 actionCollection(),
"setup_spellchecker");
1486 if ( Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" ) ) {
1487 TDEToggleAction * a =
new TDEToggleAction( i18n(
"Encrypt Message with Chiasmus..." ),
1488 "chidecrypted", 0, actionCollection(),
1489 "encrypt_message_chiasmus" );
1490 a->setCheckedState( KGuiItem( i18n(
"Encrypt Message with Chiasmus..." ),
"chiencrypted" ) );
1491 mEncryptChiasmusAction = a;
1492 connect( mEncryptChiasmusAction, TQ_SIGNAL(toggled(
bool)),
1493 this, TQ_SLOT(slotEncryptChiasmusToggled(
bool)) );
1495 mEncryptChiasmusAction = 0;
1498 mEncryptAction =
new TDEToggleAction (i18n(
"&Encrypt Message"),
1500 actionCollection(),
"encrypt_message");
1501 mSignAction =
new TDEToggleAction (i18n(
"&Sign Message"),
1503 actionCollection(),
"sign_message");
1505 const KPIM::Identity & ident =
1506 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
1509 mLastIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
1510 mLastIdentityHasEncryptionKey = !ident.pgpEncryptionKey().isEmpty() || !ident.smimeEncryptionKey().isEmpty();
1512 mLastEncryptActionState =
false;
1513 mLastSignActionState = GlobalSettings::self()->pgpAutoSign();
1516 mAttachPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() );
1520 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
1521 !ident.pgpEncryptionKey().isEmpty() );
1523 if ( !Kleo::CryptoBackendFactory::instance()->openpgp() && !Kleo::CryptoBackendFactory::instance()->smime() ) {
1525 mEncryptAction->setEnabled(
false );
1526 setEncryption(
false );
1527 mSignAction->setEnabled(
false );
1528 setSigning(
false );
1530 const bool canOpenPGPSign = Kleo::CryptoBackendFactory::instance()->openpgp()
1531 && !ident.pgpSigningKey().isEmpty();
1532 const bool canSMIMESign = Kleo::CryptoBackendFactory::instance()->smime()
1533 && !ident.smimeSigningKey().isEmpty();
1535 setEncryption(
false );
1536 setSigning( ( canOpenPGPSign || canSMIMESign ) && GlobalSettings::self()->pgpAutoSign() );
1539 connect(mEncryptAction, TQ_SIGNAL(toggled(
bool)),
1540 TQ_SLOT(slotEncryptToggled(
bool )));
1541 connect(mSignAction, TQ_SIGNAL(toggled(
bool)),
1542 TQ_SLOT(slotSignToggled(
bool )));
1545 for (
int i = 0 ; i < numCryptoMessageFormats ; ++i )
1546 l.push_back( Kleo::cryptoMessageFormatToLabel( cryptoMessageFormats[i] ) );
1548 mCryptoModuleAction =
new TDESelectAction( i18n(
"&Cryptographic Message Format" ), 0,
1549 this, TQ_SLOT(slotSelectCryptoModule()),
1550 actionCollection(),
"options_select_crypto" );
1551 mCryptoModuleAction->setItems( l );
1552 mCryptoModuleAction->setCurrentItem( format2cb( ident.preferredCryptoMessageFormat() ) );
1553 mCryptoModuleAction->setToolTip( i18n(
"Select a cryptographic format for this message" ) );
1554 slotSelectCryptoModule(
true );
1556 TQStringList styleItems;
1557 styleItems << i18n(
"Standard" );
1558 styleItems << i18n(
"Bulleted List (Disc)" );
1559 styleItems << i18n(
"Bulleted List (Circle)" );
1560 styleItems << i18n(
"Bulleted List (Square)" );
1561 styleItems << i18n(
"Ordered List (Decimal)" );
1562 styleItems << i18n(
"Ordered List (Alpha lower)" );
1563 styleItems << i18n(
"Ordered List (Alpha upper)" );
1565 listAction =
new TDESelectAction( i18n(
"Select Style" ), 0, actionCollection(),
1567 listAction->setItems( styleItems );
1568 listAction->setToolTip( i18n(
"Select a list style" ) );
1569 connect( listAction, TQ_SIGNAL( activated(
const TQString& ) ),
1570 TQ_SLOT( slotListAction(
const TQString& ) ) );
1571 fontAction =
new TDEFontAction(
"Select Font", 0, actionCollection(),
1573 fontAction->setToolTip( i18n(
"Select a font" ) );
1574 connect( fontAction, TQ_SIGNAL( activated(
const TQString& ) ),
1575 TQ_SLOT( slotFontAction(
const TQString& ) ) );
1576 fontSizeAction =
new TDEFontSizeAction(
"Select Size", 0, actionCollection(),
1578 fontSizeAction->setToolTip( i18n(
"Select a font size" ) );
1579 connect( fontSizeAction, TQ_SIGNAL( fontSizeChanged(
int ) ),
1580 TQ_SLOT( slotSizeAction(
int ) ) );
1582 alignLeftAction =
new TDEToggleAction (i18n(
"Align Left"),
"format-text-direction-ltr", 0,
1583 this, TQ_SLOT(slotAlignLeft()), actionCollection(),
1585 alignLeftAction->setChecked(
true );
1586 alignRightAction =
new TDEToggleAction (i18n(
"Align Right"),
"format-text-direction-rtl", 0,
1587 this, TQ_SLOT(slotAlignRight()), actionCollection(),
1589 alignCenterAction =
new TDEToggleAction (i18n(
"Align Center"),
"text_center", 0,
1590 this, TQ_SLOT(slotAlignCenter()), actionCollection(),
1592 textBoldAction =
new TDEToggleAction( i18n(
"&Bold"),
"format-text-bold", CTRL+Key_B,
1593 this, TQ_SLOT(slotTextBold()),
1594 actionCollection(),
"format-text-bold");
1595 textItalicAction =
new TDEToggleAction( i18n(
"&Italic"),
"format-text-italic", CTRL+Key_I,
1596 this, TQ_SLOT(slotTextItalic()),
1597 actionCollection(),
"format-text-italic");
1598 textUnderAction =
new TDEToggleAction( i18n(
"&Underline"),
"format-text-underline", CTRL+Key_U,
1599 this, TQ_SLOT(slotTextUnder()),
1600 actionCollection(),
"format-text-underline");
1601 actionFormatReset =
new TDEAction( i18n(
"Reset Font Settings" ),
"eraser", 0,
1602 this, TQ_SLOT( slotFormatReset() ),
1603 actionCollection(),
"format_reset");
1604 actionFormatColor =
new TDEAction( i18n(
"Text Color..." ),
"colorize", 0,
1605 this, TQ_SLOT( slotTextColor() ),
1606 actionCollection(),
"format_color");
1609 createGUI(
"kmcomposerui.rc");
1611 connect( toolBar(
"htmlToolBar"), TQ_SIGNAL( visibilityChanged(
bool) ),
1612 this, TQ_SLOT( htmlToolBarVisibilityChanged(
bool) ) );
1616 TDEAction* configureAction = actionCollection()->action(
"options_configure" );
1617 if ( configureAction )
1618 configureAction->setText( i18n(
"Configure KMail..." ) );
1622 void KMComposeWin::setupStatusBar(
void)
1624 statusBar()->insertItem(
"", 0, 1);
1625 statusBar()->setItemAlignment(0, AlignLeft | AlignVCenter);
1627 statusBar()->insertItem(i18n(
" Spellcheck: %1 ").arg(
" " ), 3, 0,
true );
1628 statusBar()->insertItem(i18n(
" Column: %1 ").arg(
" "), 2, 0,
true);
1629 statusBar()->insertItem(i18n(
" Line: %1 ").arg(
" "), 1, 0,
true);
1634 void KMComposeWin::updateCursorPosition()
1638 line = mEditor->currentLine();
1639 col = mEditor->currentColumn();
1640 temp = i18n(
" Line: %1 ").arg(line+1);
1641 statusBar()->changeItem(temp,1);
1642 temp = i18n(
" Column: %1 ").arg(col+1);
1643 statusBar()->changeItem(temp,2);
1648 void KMComposeWin::setupEditor(
void)
1651 mEditor->setModified(
false);
1652 TQFontMetrics fm(mBodyFont);
1653 mEditor->setTabStopWidth(fm.width(TQChar(
' ')) * 8);
1656 slotWordWrapToggled( GlobalSettings::self()->wordWrap() );
1682 updateCursorPosition();
1683 connect(mEditor,TQ_SIGNAL(CursorPositionChanged()),TQ_SLOT(updateCursorPosition()));
1684 connect( mEditor, TQ_SIGNAL( currentFontChanged(
const TQFont & ) ),
1685 this, TQ_SLOT( fontChanged(
const TQFont & ) ) );
1686 connect( mEditor, TQ_SIGNAL( currentAlignmentChanged(
int ) ),
1687 this, TQ_SLOT( alignmentChanged(
int ) ) );
1693 static TQString cleanedUpHeaderString(
const TQString & s )
1697 res.replace(
'\r',
"" );
1698 res.replace(
'\n',
" " );
1699 return res.stripWhiteSpace();
1703 TQString KMComposeWin::subject()
const
1705 return cleanedUpHeaderString( mEdtSubject->text() );
1709 TQString KMComposeWin::to()
const
1712 return cleanedUpHeaderString( mEdtTo->text() );
1713 }
else if ( mRecipientsEditor ) {
1714 return mRecipientsEditor->recipientString( Recipient::To );
1721 TQString KMComposeWin::cc()
const
1723 if ( mEdtCc && !mEdtCc->isHidden() ) {
1724 return cleanedUpHeaderString( mEdtCc->text() );
1725 }
else if ( mRecipientsEditor ) {
1726 return mRecipientsEditor->recipientString( Recipient::Cc );
1733 TQString KMComposeWin::bcc()
const
1735 if ( mEdtBcc && !mEdtBcc->isHidden() ) {
1736 return cleanedUpHeaderString( mEdtBcc->text() );
1737 }
else if ( mRecipientsEditor ) {
1738 return mRecipientsEditor->recipientString( Recipient::Bcc );
1745 TQString KMComposeWin::from()
const
1747 return cleanedUpHeaderString( mEdtFrom->text() );
1751 TQString KMComposeWin::replyTo()
const
1753 if ( mEdtReplyTo ) {
1754 return cleanedUpHeaderString( mEdtReplyTo->text() );
1761 void KMComposeWin::verifyWordWrapLengthIsAdequate(
const TQString &body)
1763 int maxLineLength = 0;
1766 if (mEditor->TQTextEdit::wordWrap() == TQTextEdit::FixedColumnWidth) {
1767 for (curPos = 0; curPos < (int)body.length(); ++curPos)
1768 if (body[curPos] ==
'\n') {
1769 if ((curPos - oldPos) > maxLineLength)
1770 maxLineLength = curPos - oldPos;
1773 if ((curPos - oldPos) > maxLineLength)
1774 maxLineLength = curPos - oldPos;
1775 if (mEditor->wrapColumnOrWidth() < maxLineLength)
1776 mEditor->setWrapColumnOrWidth(maxLineLength);
1781 void KMComposeWin::decryptOrStripOffCleartextSignature( TQCString& body )
1783 TQPtrList<Kpgp::Block> pgpBlocks;
1784 TQStrList nonPgpBlocks;
1785 if( Kpgp::Module::prepareMessageForDecryption( body,
1786 pgpBlocks, nonPgpBlocks ) )
1790 if( pgpBlocks.count() == 1 )
1792 Kpgp::Block* block = pgpBlocks.first();
1793 if( ( block->type() == Kpgp::PgpMessageBlock ) ||
1794 ( block->type() == Kpgp::ClearsignedBlock ) )
1796 if( block->type() == Kpgp::PgpMessageBlock )
1803 body = nonPgpBlocks.first()
1805 + nonPgpBlocks.last();
1812 void KMComposeWin::setTransport(
const TQString & transport )
1814 kdDebug(5006) <<
"KMComposeWin::setTransport( \"" << transport <<
"\" )" << endl;
1816 if ( transport.isEmpty() )
1819 bool transportFound =
false;
1820 for (
int i = 0; i < mTransport->count(); ++i ) {
1821 if ( mTransport->text(i) == transport ) {
1822 transportFound =
true;
1823 mTransport->setCurrentItem(i);
1824 kdDebug(5006) <<
"transport found, it's no. " << i <<
" in the list" << endl;
1828 if ( !transportFound ) {
1829 kdDebug(5006) <<
"unknown transport \"" << transport <<
"\"" << endl;
1830 if ( transport.startsWith(
"smtp://") || transport.startsWith(
"smtps://") ||
1831 transport.startsWith(
"file://") ) {
1833 mTransport->setEditText( transport );
1837 mTransport->setCurrentText( GlobalSettings::self()->defaultTransport() );
1843 void KMComposeWin::setMsg(
KMMessage* newMsg,
bool mayAutoSign,
1844 bool allowDecryption,
bool isModified)
1849 kdDebug(5006) <<
"KMComposeWin::setMsg() : newMsg == 0!" << endl;
1853 KPIM::IdentityManager * im = kmkernel->identityManager();
1855 mEdtFrom->setText(mMsg->from());
1856 mEdtReplyTo->setText(mMsg->replyTo());
1857 if ( mClassicalRecipients ) {
1858 mEdtTo->setText(mMsg->to());
1859 mEdtCc->setText(mMsg->cc());
1860 mEdtBcc->setText(mMsg->bcc());
1862 mRecipientsEditor->setRecipientString( mMsg->to(), Recipient::To );
1863 mRecipientsEditor->setRecipientString( mMsg->cc(), Recipient::Cc );
1864 mRecipientsEditor->setRecipientString( mMsg->bcc(), Recipient::Bcc );
1865 mRecipientsEditor->setFocusBottom();
1867 mEdtSubject->setText(mMsg->subject());
1869 const bool stickyIdentity = mBtnIdentity->isChecked() && !mIgnoreStickyFields;
1870 const bool messageHasIdentity = !newMsg->
headerField(
"X-KMail-Identity").isEmpty();
1871 if (!stickyIdentity && messageHasIdentity)
1872 mId = newMsg->
headerField(
"X-KMail-Identity").stripWhiteSpace().toUInt();
1876 if ( !stickyIdentity ) {
1877 disconnect(mIdentity,TQ_SIGNAL(identityChanged(uint)),
1878 this, TQ_SLOT(slotIdentityChanged(uint)));
1881 mIdentity->setCurrentIdentity( mId );
1882 const uint idToApply = mId;
1883 if ( !stickyIdentity ) {
1884 connect(mIdentity,TQ_SIGNAL(identityChanged(uint)),
1885 this, TQ_SLOT(slotIdentityChanged(uint)));
1890 if ( messageHasIdentity )
1891 mId = newMsg->
headerField(
"X-KMail-Identity").stripWhiteSpace().toUInt();
1893 mId = im->defaultIdentity().uoid();
1898 slotIdentityChanged( idToApply );
1900 const KPIM::Identity & ident = im->identityForUoid( mIdentity->currentIdentity() );
1904 TQString mdnAddr = newMsg->
headerField(
"Disposition-Notification-To");
1905 mRequestMDNAction->setChecked( ( !mdnAddr.isEmpty() &&
1906 im->thatIsMe( mdnAddr ) ) ||
1907 GlobalSettings::self()->requestMDN() );
1910 mUrgentAction->setChecked( newMsg->
isUrgent() );
1912 if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
1913 mMsg->removeHeaderField(
"X-Face");
1916 TQString xface = ident.xface();
1917 if (!xface.isEmpty())
1919 int numNL = ( xface.length() - 1 ) / 70;
1920 for (
int i = numNL; i > 0; --i )
1921 xface.insert( i*70,
"\n\t" );
1922 mMsg->setHeaderField(
"X-Face", xface);
1927 switch ( mMsg->encryptionState() ) {
1928 case KMMsgFullyEncrypted:
1929 case KMMsgPartiallyEncrypted:
1930 mLastEncryptActionState =
true;
1932 case KMMsgNotEncrypted:
1933 mLastEncryptActionState =
false;
1940 switch ( mMsg->signatureState() ) {
1941 case KMMsgFullySigned:
1942 case KMMsgPartiallySigned:
1943 mLastSignActionState =
true;
1945 case KMMsgNotSigned:
1946 mLastSignActionState =
false;
1953 if ( mMsg->headers().FindField(
"X-KMail-SignatureActionEnabled" ) )
1954 mLastSignActionState = (mMsg->headerField(
"X-KMail-SignatureActionEnabled" ) ==
"true");
1955 if ( mMsg->headers().FindField(
"X-KMail-EncryptActionEnabled" ) )
1956 mLastEncryptActionState = (mMsg->headerField(
"X-KMail-EncryptActionEnabled" ) ==
"true");
1957 if ( mMsg->headers().FindField(
"X-KMail-CryptoMessageFormat" ) )
1958 mCryptoModuleAction->setCurrentItem( format2cb(
static_cast<Kleo::CryptoMessageFormat
>(
1959 mMsg->headerField(
"X-KMail-CryptoMessageFormat" ).toInt() ) ) );
1961 mLastIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
1962 mLastIdentityHasEncryptionKey = !ident.pgpEncryptionKey().isEmpty() || !ident.smimeEncryptionKey().isEmpty();
1964 if ( Kleo::CryptoBackendFactory::instance()->openpgp() || Kleo::CryptoBackendFactory::instance()->smime() ) {
1965 const bool canOpenPGPSign = Kleo::CryptoBackendFactory::instance()->openpgp()
1966 && !ident.pgpSigningKey().isEmpty();
1967 const bool canSMIMESign = Kleo::CryptoBackendFactory::instance()->smime()
1968 && !ident.smimeSigningKey().isEmpty();
1970 setEncryption( mLastEncryptActionState );
1971 setSigning( ( canOpenPGPSign || canSMIMESign ) && mLastSignActionState );
1973 slotUpdateSignatureAndEncrypionStateIndicators();
1977 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
1978 !ident.pgpEncryptionKey().isEmpty() );
1980 TQString transport = newMsg->
headerField(
"X-KMail-Transport");
1981 const bool stickyTransport = mBtnTransport->isChecked() && !mIgnoreStickyFields;
1982 if (!stickyTransport && !transport.isEmpty()) {
1983 setTransport( transport );
1988 if (transport.isEmpty() && !mMsg->originatingAccountName().isEmpty()) {
1989 TQString transportCandidate = mMsg->originatingAccountName();
1990 bool transportFound =
false;
1991 for (
int i = 0; i < mTransport->count(); ++i ) {
1992 if ( mTransport->text(i) == transportCandidate ) {
1993 transportFound =
true;
1994 setTransport(transportCandidate);
2000 if (!mBtnFcc->isChecked())
2002 if (!mMsg->fcc().isEmpty())
2003 setFcc(mMsg->fcc());
2005 setFcc(ident.fcc());
2008 const bool stickyDictionary = mBtnDictionary->isChecked() && !mIgnoreStickyFields;
2009 if ( !stickyDictionary ) {
2010 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
2013 partNode * root = partNode::fromMessage( mMsg );
2015 KMail::ObjectTreeParser otp;
2016 otp.parseObjectTree( root );
2018 KMail::AttachmentCollector ac;
2019 ac.collectAttachmentsFrom( root );
2021 for ( std::vector<partNode*>::const_iterator it = ac.attachments().begin() ; it != ac.attachments().end() ; ++it )
2022 addAttach(
new KMMessagePart( (*it)->msgPart() ) );
2024 mEditor->setText( otp.textualContent() );
2025 mCharset = otp.textualContentCharset();
2026 if ( partNode * n = root->findType( DwMime::kTypeText, DwMime::kSubtypeHtml ) )
2027 if ( partNode * p = n->parentNode() )
2028 if ( p->hasType( DwMime::kTypeMultipart ) &&
2029 p->hasSubType( DwMime::kSubtypeAlternative ) )
2030 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" ) {
2031 toggleMarkup(
true );
2034 mCharset = n->msgPart().charset();
2035 TQCString bodyDecoded = n->msgPart().bodyDecoded();
2038 const TQTextCodec *codec = KMMsgBase::codecForName( mCharset );
2040 mEditor->setText( codec->toUnicode( bodyDecoded ) );
2042 mEditor->setText( TQString::fromLocal8Bit( bodyDecoded ) );
2046 if ( mCharset.isEmpty() )
2047 mCharset = mMsg->charset();
2048 if ( mCharset.isEmpty() )
2049 mCharset = mDefCharset;
2050 setCharset( mCharset );
2053 if ( mMsg->numBodyParts() == 0 && otp.textualContent().isEmpty() ) {
2054 mCharset=mMsg->charset();
2055 if ( mCharset.isEmpty() || mCharset ==
"default" )
2056 mCharset = mDefCharset;
2058 TQCString bodyDecoded = mMsg->bodyDecoded();
2060 if( allowDecryption )
2061 decryptOrStripOffCleartextSignature( bodyDecoded );
2063 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2065 mEditor->setText(codec->toUnicode(bodyDecoded));
2067 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2069 #ifdef BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
2070 const int num = mMsg->numBodyParts();
2071 kdDebug(5006) <<
"KMComposeWin::setMsg() mMsg->numBodyParts="
2072 << mMsg->numBodyParts() << endl;
2075 KMMessagePart bodyPart;
2076 int firstAttachment = 0;
2078 mMsg->bodyPart(1, &bodyPart);
2079 if ( bodyPart.typeStr().lower() ==
"text" &&
2080 bodyPart.subtypeStr().lower() ==
"html" ) {
2082 partNode *root = partNode::fromMessage( mMsg );
2083 partNode *node = root->findType( DwMime::kTypeText,
2084 DwMime::kSubtypeHtml );
2085 if ( node && node->parentNode() &&
2086 node->parentNode()->hasType( DwMime::kTypeMultipart ) &&
2087 node->parentNode()->hasSubType( DwMime::kSubtypeAlternative ) ) {
2089 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/html found" << endl;
2090 firstAttachment = 2;
2091 if ( mMsg->headerField(
"X-KMail-Markup" ) ==
"true" )
2092 toggleMarkup(
true );
2094 delete root; root = 0;
2096 if ( firstAttachment == 0 ) {
2097 mMsg->bodyPart(0, &bodyPart);
2098 if ( bodyPart.typeStr().lower() ==
"text" ) {
2100 kdDebug(5006) <<
"KMComposeWin::setMsg() : text/* found" << endl;
2101 firstAttachment = 1;
2105 if ( firstAttachment != 0 )
2107 mCharset = bodyPart.charset();
2108 if ( mCharset.isEmpty() || mCharset ==
"default" )
2109 mCharset = mDefCharset;
2111 TQCString bodyDecoded = bodyPart.bodyDecoded();
2113 if( allowDecryption )
2114 decryptOrStripOffCleartextSignature( bodyDecoded );
2122 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2124 mEditor->setText(codec->toUnicode(bodyDecoded));
2126 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2128 }
else mEditor->setText(
"");
2129 for(
int i = firstAttachment; i < num; ++i )
2131 KMMessagePart *msgPart =
new KMMessagePart;
2132 mMsg->bodyPart(i, msgPart);
2133 TQCString mimeType = msgPart->typeStr().lower() +
'/'
2134 + msgPart->subtypeStr().lower();
2137 if( mimeType !=
"application/pgp-signature" ) {
2142 mCharset=mMsg->charset();
2143 if ( mCharset.isEmpty() || mCharset ==
"default" )
2144 mCharset = mDefCharset;
2146 TQCString bodyDecoded = mMsg->bodyDecoded();
2148 if( allowDecryption )
2149 decryptOrStripOffCleartextSignature( bodyDecoded );
2151 const TQTextCodec *codec = KMMsgBase::codecForName(mCharset);
2153 mEditor->setText(codec->toUnicode(bodyDecoded));
2155 mEditor->setText(TQString::fromLocal8Bit(bodyDecoded));
2158 setCharset(mCharset);
2159 #endif // BROKEN_FOR_OPAQUE_SIGNED_OR_ENCRYPTED_MAILS
2161 if( (GlobalSettings::self()->autoTextSignature()==
"auto") && mayAutoSign ) {
2169 if ( GlobalSettings::self()->prependSignature() ) {
2170 TQTimer::singleShot( 0,
this, TQ_SLOT(slotPrependSignature()) );
2172 TQTimer::singleShot( 0,
this, TQ_SLOT(slotAppendSignature()) );
2176 if ( mMsg->getCursorPos() > 0 ) {
2179 mPreserveUserCursorPosition =
true;
2181 setModified( isModified );
2184 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
2187 mPreventFccOverwrite = ( !newMsg->
fcc().isEmpty() && ident.fcc() != newMsg->
fcc() );
2192 void KMComposeWin::setFcc(
const TQString &idString )
2195 if ( ! idString.isEmpty() && kmkernel->findFolderById( idString ) ) {
2196 mFcc->setFolder( idString );
2198 mFcc->setFolder( kmkernel->sentFolder() );
2204 bool KMComposeWin::isModified()
const
2206 return ( mEditor->isModified() ||
2207 mEdtFrom->edited() ||
2208 ( mEdtReplyTo && mEdtReplyTo->edited() ) ||
2209 ( mEdtTo && mEdtTo->edited() ) ||
2210 ( mEdtCc && mEdtCc->edited() ) ||
2211 ( mEdtBcc && mEdtBcc->edited() ) ||
2212 ( mRecipientsEditor && mRecipientsEditor->isModified() ) ||
2213 mEdtSubject->edited() ||
2215 ( mTransport->lineEdit() && mTransport->lineEdit()->edited() ) );
2220 void KMComposeWin::setModified(
bool modified )
2222 mEditor->setModified( modified );
2224 mEdtFrom->setEdited(
false );
2225 if ( mEdtReplyTo ) mEdtReplyTo->setEdited(
false );
2226 if ( mEdtTo ) mEdtTo->setEdited(
false );
2227 if ( mEdtCc ) mEdtCc->setEdited(
false );
2228 if ( mEdtBcc ) mEdtBcc->setEdited(
false );
2229 if ( mRecipientsEditor ) mRecipientsEditor->clearModified();
2230 mEdtSubject->setEdited(
false );
2231 mAtmModified = false ;
2232 if ( mTransport->lineEdit() )
2233 mTransport->lineEdit()->setEdited(
false );
2239 bool KMComposeWin::queryClose ()
2241 if ( !mEditor->checkExternalEditorFinished() )
2243 if ( kmkernel->shuttingDown() || kapp->sessionSaving() )
2245 if ( mComposer && mComposer->isPerformingSignOperation() )
2248 if ( isModified() ) {
2249 bool istemplate = ( mFolder!=0 && mFolder->isTemplates() );
2250 const TQString savebut = ( istemplate ?
2251 i18n(
"Re&save as Template") :
2252 i18n(
"&Save as Draft") );
2253 const TQString savetext = ( istemplate ?
2254 i18n(
"Resave this message in the Templates folder. "
2255 "It can then be used at a later time.") :
2256 i18n(
"Save this message in the Drafts folder. "
2257 "It can then be edited and sent at a later time.") );
2259 const int rc = KMessageBox::warningYesNoCancel(
this,
2260 i18n(
"Do you want to save the message for later or discard it?"),
2261 i18n(
"Close Composer"),
2262 KGuiItem(savebut,
"document-save", TQString(), savetext),
2263 KStdGuiItem::discard() );
2264 if ( rc == KMessageBox::Cancel )
2266 else if ( rc == KMessageBox::Yes ) {
2281 bool KMComposeWin::userForgotAttachment()
2283 bool checkForForgottenAttachments =
2284 mCheckForForgottenAttachments && GlobalSettings::self()->showForgottenAttachmentWarning();
2286 if ( !checkForForgottenAttachments || ( mAtmList.count() > 0 ) )
2290 TQStringList attachWordsList = GlobalSettings::self()->attachmentKeywords();
2292 if ( attachWordsList.isEmpty() ) {
2294 attachWordsList << TQString::fromLatin1(
"attachment")
2295 << TQString::fromLatin1(
"attached");
2296 if ( TQString::fromLatin1(
"attachment") != i18n(
"attachment") )
2297 attachWordsList << i18n(
"attachment");
2298 if ( TQString::fromLatin1(
"attached") != i18n(
"attached") )
2299 attachWordsList << i18n(
"attached");
2302 TQRegExp rx ( TQString::fromLatin1(
"\\b") +
2303 attachWordsList.join(
"\\b|\\b") +
2304 TQString::fromLatin1(
"\\b") );
2305 rx.setCaseSensitive(
false );
2307 bool gotMatch =
false;
2311 TQString subj = subject();
2312 gotMatch = ( KMMessage::stripOffPrefixes( subj ) == subj )
2313 && ( rx.search( subj ) >= 0 );
2318 TQRegExp quotationRx (
"^([ \\t]*([|>:}#]|[A-Za-z]+>))+");
2319 for (
int i = 0; i < mEditor->numLines(); ++i ) {
2320 TQString line = mEditor->textLine( i );
2321 gotMatch = ( quotationRx.search( line ) < 0 )
2322 && ( rx.search( line ) >= 0 );
2331 int rc = KMessageBox::warningYesNoCancel(
this,
2332 i18n(
"The message you have composed seems to refer to an "
2333 "attached file but you have not attached anything.\n"
2334 "Do you want to attach a file to your message?"),
2335 i18n(
"File Attachment Reminder"),
2336 i18n(
"&Attach File..."),
2337 i18n(
"&Send as Is") );
2338 if ( rc == KMessageBox::Cancel )
2340 if ( rc == KMessageBox::Yes ) {
2349 void KMComposeWin::applyChanges(
bool dontSignNorEncrypt,
bool dontDisable )
2351 kdDebug(5006) <<
"entering KMComposeWin::applyChanges" << endl;
2353 if(!mMsg || mComposer) {
2354 kdDebug(5006) <<
"KMComposeWin::applyChanges() : mMsg == 0!\n" << endl;
2355 emit applyChangesDone(
false );
2360 mComposer =
new MessageComposer(
this );
2361 connect( mComposer, TQ_SIGNAL( done(
bool ) ),
2362 this, TQ_SLOT( slotComposerDone(
bool ) ) );
2367 if ( !dontDisable ) setEnabled(
false );
2369 mComposer->setDisableBreaking( mDisableBreaking );
2370 mComposer->applyChanges( dontSignNorEncrypt );
2373 void KMComposeWin::slotComposerDone(
bool rc )
2375 deleteAll( mComposedMessages );
2376 mComposedMessages = mComposer->composedMessageList();
2377 emit applyChangesDone( rc );
2385 const KPIM::Identity & KMComposeWin::identity()
const {
2386 return kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
2389 uint KMComposeWin::identityUid()
const {
2390 return mIdentity->currentIdentity();
2393 Kleo::CryptoMessageFormat KMComposeWin::cryptoMessageFormat()
const {
2394 if ( !mCryptoModuleAction )
2395 return Kleo::AutoFormat;
2396 return cb2format( mCryptoModuleAction->currentItem() );
2399 bool KMComposeWin::encryptToSelf()
const {
2401 TDEConfigGroup group( KMKernel::config(),
"Composer" );
2402 return group.readBoolEntry(
"crypto-encrypt-to-self",
true );
2405 bool KMComposeWin::queryExit ()
2411 bool KMComposeWin::addAttach(
const KURL aUrl)
2413 if ( !aUrl.isValid() ) {
2414 KMessageBox::sorry(
this, i18n(
"<qt><p>KMail could not recognize the location of the attachment (%1);</p>"
2415 "<p>you have to specify the full path if you wish to attach a file.</p></qt>" )
2416 .arg( aUrl.prettyURL() ) );
2420 const int maxAttachmentSize = GlobalSettings::maximumAttachmentSize();
2421 const uint maximumAttachmentSizeInByte = maxAttachmentSize*1024*1024;
2422 if ( aUrl.isLocalFile() && TQFileInfo( aUrl.pathOrURL() ).size() > maximumAttachmentSizeInByte ) {
2423 KMessageBox::sorry(
this, i18n(
"<qt><p>Your administrator has disallowed attaching files bigger than %1 MB.</p>" ).arg( maxAttachmentSize ) );
2427 TDEIO::TransferJob *job = TDEIO::get(aUrl);
2428 TDEIO::Scheduler::scheduleJob( job );
2431 ld.data = TQByteArray();
2433 if( !aUrl.fileEncoding().isEmpty() )
2434 ld.encoding = aUrl.fileEncoding().latin1();
2436 mMapAtmLoadData.insert(job, ld);
2437 mAttachJobs[job] = aUrl;
2438 connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
2439 this, TQ_SLOT(slotAttachFileResult(TDEIO::Job *)));
2440 connect(job, TQ_SIGNAL(data(TDEIO::Job *,
const TQByteArray &)),
2441 this, TQ_SLOT(slotAttachFileData(TDEIO::Job *,
const TQByteArray &)));
2447 void KMComposeWin::addAttach(
const KMMessagePart* msgPart)
2449 mAtmList.append(msgPart);
2452 if (mAtmList.count()==1)
2454 mAtmListView->resize(mAtmListView->width(), 50);
2455 mAtmListView->show();
2460 KMAtmListViewItem *lvi =
new KMAtmListViewItem( mAtmListView );
2461 msgPartToItem(msgPart, lvi);
2462 mAtmItemList.append(lvi);
2465 if ( mTempDir != 0 ) {
2470 connect( lvi, TQ_SIGNAL( compress(
int ) ),
2471 this, TQ_SLOT( compressAttach(
int ) ) );
2472 connect( lvi, TQ_SIGNAL( uncompress(
int ) ),
2473 this, TQ_SLOT( uncompressAttach(
int ) ) );
2475 slotUpdateAttachActions();
2480 void KMComposeWin::slotUpdateAttachActions()
2482 int selectedCount = 0;
2483 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
2484 if ( (*it)->isSelected() ) {
2489 mAttachRemoveAction->setEnabled( selectedCount >= 1 );
2490 mAttachSaveAction->setEnabled( selectedCount == 1 );
2491 mAttachPropertiesAction->setEnabled( selectedCount == 1 );
2497 TQString KMComposeWin::prettyMimeType(
const TQString& type )
2499 TQString t = type.lower();
2500 KServiceType::Ptr st = KServiceType::serviceType( t );
2501 return st ? st->comment() : t;
2504 void KMComposeWin::msgPartToItem(
const KMMessagePart* msgPart,
2505 KMAtmListViewItem *lvi,
bool loadDefaults)
2507 assert(msgPart != 0);
2509 if (!msgPart->fileName().isEmpty())
2510 lvi->setText(0, msgPart->fileName());
2512 lvi->setText(0, msgPart->name());
2513 lvi->setText(1, TDEIO::convertSize( msgPart->decodedSize()));
2514 lvi->setText(2, msgPart->contentTransferEncodingStr());
2515 lvi->setText(3, prettyMimeType(msgPart->typeStr() +
"/" + msgPart->subtypeStr()));
2516 lvi->setAttachmentSize(msgPart->decodedSize());
2518 if ( loadDefaults ) {
2519 if( canSignEncryptAttachments() ) {
2520 lvi->enableCryptoCBs(
true );
2521 lvi->setEncrypt( mEncryptAction->isChecked() );
2522 lvi->setSign( mSignAction->isChecked() );
2524 lvi->enableCryptoCBs(
false );
2531 void KMComposeWin::removeAttach(
const TQString &aUrl)
2534 KMMessagePart* msgPart;
2535 for(idx=0,msgPart=mAtmList.first(); msgPart;
2536 msgPart=mAtmList.next(),idx++) {
2537 if (msgPart->name() == aUrl) {
2546 void KMComposeWin::removeAttach(
int idx)
2548 mAtmModified =
true;
2550 KMAtmListViewItem *item =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( idx ) );
2551 if ( item->itemBelow() )
2552 mAtmSelectNew = item->itemBelow();
2553 else if ( item->itemAbove() )
2554 mAtmSelectNew = item->itemAbove();
2556 mAtmList.remove(idx);
2557 delete mAtmItemList.take(idx);
2559 if( mAtmList.isEmpty() )
2561 mAtmListView->hide();
2562 mAtmListView->setMinimumSize(0, 0);
2569 bool KMComposeWin::encryptFlagOfAttachment(
int idx)
2571 return (
int)(mAtmItemList.count()) > idx
2572 ?
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( idx ) )->isEncrypt()
2578 bool KMComposeWin::signFlagOfAttachment(
int idx)
2580 return (
int)(mAtmItemList.count()) > idx
2581 ? ((KMAtmListViewItem*)(mAtmItemList.at( idx )))->isSign()
2587 void KMComposeWin::addrBookSelInto()
2589 if ( mClassicalRecipients ) {
2590 if ( GlobalSettings::self()->addresseeSelectorType() ==
2591 GlobalSettings::EnumAddresseeSelectorType::New ) {
2592 addrBookSelIntoNew();
2594 addrBookSelIntoOld();
2597 kdWarning() <<
"To be implemented: call recipients picker." << endl;
2601 void KMComposeWin::addrBookSelIntoOld()
2603 AddressesDialog dlg(
this );
2608 if ( !txt.isEmpty() ) {
2609 lst = KPIM::splitEmailAddrList( txt );
2610 dlg.setSelectedTo( lst );
2613 txt = mEdtCc->text();
2614 if ( !txt.isEmpty() ) {
2615 lst = KPIM::splitEmailAddrList( txt );
2616 dlg.setSelectedCC( lst );
2619 txt = mEdtBcc->text();
2620 if ( !txt.isEmpty() ) {
2621 lst = KPIM::splitEmailAddrList( txt );
2622 dlg.setSelectedBCC( lst );
2625 dlg.setRecentAddresses( RecentAddresses::self( KMKernel::config() )->tdeabcAddresses() );
2627 if (dlg.exec()==TQDialog::Rejected)
return;
2629 mEdtTo->setText( dlg.to().join(
", ") );
2630 mEdtTo->setEdited(
true );
2632 mEdtCc->setText( dlg.cc().join(
", ") );
2633 mEdtCc->setEdited(
true );
2635 mEdtBcc->setText( dlg.bcc().join(
", ") );
2636 mEdtBcc->setEdited(
true );
2639 if ( !mEdtBcc->text().isEmpty() ) {
2640 mShowHeaders |= HDR_BCC;
2641 rethinkFields(
false );
2645 void KMComposeWin::addrBookSelIntoNew()
2647 AddresseeEmailSelection selection;
2649 AddresseeSelectorDialog dlg( &selection );
2655 if ( !txt.isEmpty() ) {
2656 lst = KPIM::splitEmailAddrList( txt );
2657 selection.setSelectedTo( lst );
2660 txt = mEdtCc->text();
2661 if ( !txt.isEmpty() ) {
2662 lst = KPIM::splitEmailAddrList( txt );
2663 selection.setSelectedCC( lst );
2666 txt = mEdtBcc->text();
2667 if ( !txt.isEmpty() ) {
2668 lst = KPIM::splitEmailAddrList( txt );
2669 selection.setSelectedBCC( lst );
2672 if (dlg.exec()==TQDialog::Rejected)
return;
2674 TQStringList list = selection.to() + selection.toDistributionLists();
2675 mEdtTo->setText( list.join(
", ") );
2676 mEdtTo->setEdited(
true );
2678 list = selection.cc() + selection.ccDistributionLists();
2679 mEdtCc->setText( list.join(
", ") );
2680 mEdtCc->setEdited(
true );
2682 list = selection.bcc() + selection.bccDistributionLists();
2683 mEdtBcc->setText( list.join(
", ") );
2684 mEdtBcc->setEdited(
true );
2687 if ( !mEdtBcc->text().isEmpty() ) {
2688 mShowHeaders |= HDR_BCC;
2689 rethinkFields(
false );
2695 void KMComposeWin::setCharset(
const TQCString& aCharset,
bool forceDefault)
2697 if ((forceDefault && GlobalSettings::self()->forceReplyCharset()) || aCharset.isEmpty())
2698 mCharset = mDefCharset;
2700 mCharset = aCharset.lower();
2702 if ( mCharset.isEmpty() || mCharset ==
"default" )
2703 mCharset = mDefCharset;
2707 mEncodingAction->setCurrentItem( 0 );
2711 TQStringList encodings = mEncodingAction->items();
2713 bool charsetFound =
false;
2714 for ( TQStringList::Iterator it = encodings.begin(); it != encodings.end();
2717 if (i > 0 && ((mCharset ==
"us-ascii" && i == 1) ||
2718 (i != 1 && TDEGlobal::charsets()->codecForName(
2719 TDEGlobal::charsets()->encodingForName(*it))
2720 == TDEGlobal::charsets()->codecForName(mCharset))))
2722 mEncodingAction->setCurrentItem( i );
2724 charsetFound =
true;
2728 if (!aCharset.isEmpty() && !charsetFound) setCharset(
"",
true);
2733 void KMComposeWin::slotAddrBook()
2735 KAddrBookExternal::openAddressBook(
this);
2740 void KMComposeWin::slotAddrBookFrom()
2747 void KMComposeWin::slotAddrBookReplyTo()
2754 void KMComposeWin::slotAddrBookTo()
2760 void KMComposeWin::slotAttachFile()
2768 KURL recentURL = KFileDialog::getStartURL( TQString(), recent );
2769 if ( !recentURL.url().isEmpty() &&
2770 !TDEIO::NetAccess::exists( recentURL,
true,
this ) ) {
2771 recentURL = KURL( TQDir::homeDirPath() );
2774 KFileDialog fdlg( recentURL.url(), TQString(),
this, 0,
true );
2775 fdlg.setOperationMode( KFileDialog::Other );
2776 fdlg.setCaption( i18n(
"Attach File" ) );
2777 fdlg.okButton()->setGuiItem( KGuiItem( i18n(
"&Attach" ),
"document-open" ) );
2778 fdlg.setMode( KFile::Files );
2780 KURL::List files = fdlg.selectedURLs();
2782 for (KURL::List::Iterator it = files.begin(); it != files.end(); ++it)
2788 void KMComposeWin::slotAttachFileData(TDEIO::Job *job,
const TQByteArray &data)
2790 TQMap<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2791 assert(it != mMapAtmLoadData.end());
2792 TQBuffer buff((*it).data);
2793 buff.open(IO_WriteOnly | IO_Append);
2794 buff.writeBlock(data.data(), data.size());
2800 void KMComposeWin::slotAttachFileResult(TDEIO::Job *job)
2802 TQMap<TDEIO::Job*, atmLoadData>::Iterator it = mMapAtmLoadData.find(job);
2803 assert(it != mMapAtmLoadData.end());
2805 TQMap<TDEIO::Job*, KURL>::iterator jit = mAttachJobs.find(job);
2806 bool attachURLfound = (jit != mAttachJobs.end());
2809 attachURL = jit.data();
2810 mAttachJobs.remove(jit);
2814 mMapAtmLoadData.remove(it);
2815 job->showErrorDialog();
2817 emit attachmentAdded(attachURL,
false);
2822 (*it).data.resize((*it).data.size() + 1);
2823 (*it).data[(*it).data.size() - 1] =
'\0';
2824 if (
const TQTextCodec * codec = TDEGlobal::charsets()->codecForName((*it).encoding) )
2825 mEditor->insert( codec->toUnicode( (*it).data ) );
2827 mEditor->insert( TQString::fromLocal8Bit( (*it).data ) );
2828 mMapAtmLoadData.remove(it);
2830 emit attachmentAdded(attachURL,
true);
2833 TQCString partCharset;
2834 if ( !( *it ).url.fileEncoding().isEmpty() ) {
2835 partCharset = TQCString( ( *it ).url.fileEncoding().latin1() );
2838 TDELocale *loc = TDEGlobal::locale();
2839 ed.setAutoDetectLanguage( EncodingDetector::scriptForLanguageCode ( loc->language() ) );
2842 if ( partCharset.isEmpty() )
2843 partCharset = mCharset;
2846 KMMessagePart* msgPart;
2849 TQString name( (*it).url.fileName() );
2851 TQString mimeType =
static_cast<TDEIO::MimetypeJob*
>(job)->mimetype();
2853 if ( name.isEmpty() ) {
2856 if( mimeType ==
"text/html" )
2857 name =
"index.html";
2860 TQStringList patterns( KMimeType::mimeType( mimeType )->patterns() );
2862 if( !patterns.isEmpty() ) {
2864 int i = ext.findRev(
'.' );
2870 name = TQString(
"unknown") += ext;
2874 name.truncate( 256 );
2876 TQCString encoding = KMMsgBase::autoDetectCharset(partCharset,
2878 if ( encoding.isEmpty() )
2882 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
2883 encName = KMMsgBase::encodeRFC2047String( name, encoding );
2885 encName = KMMsgBase::encodeRFC2231String( name, encoding );
2886 bool RFC2231encoded =
false;
2887 if ( !GlobalSettings::self()->outlookCompatibleAttachments() )
2888 RFC2231encoded = name != TQString( encName );
2891 msgPart =
new KMMessagePart;
2892 msgPart->setName(name);
2893 TQValueList<int> allowedCTEs;
2894 if ( mimeType ==
"message/rfc822" ) {
2895 msgPart->setMessageBody( (*it).data );
2896 allowedCTEs << DwMime::kCte7bit;
2897 allowedCTEs << DwMime::kCte8bit;
2899 msgPart->setBodyAndGuessCte((*it).data, allowedCTEs,
2900 !kmkernel->msgSender()->sendQuotedPrintable());
2901 kdDebug(5006) <<
"autodetected cte: " << msgPart->cteStr() << endl;
2903 int slash = mimeType.find(
'/' );
2905 slash = mimeType.length();
2906 msgPart->setTypeStr( mimeType.left( slash ).latin1() );
2907 msgPart->setSubtypeStr( mimeType.mid( slash + 1 ).latin1() );
2908 msgPart->setContentDisposition(TQCString(
"attachment;\n\tfilename")
2909 + ( RFC2231encoded ?
"*=" + encName :
"=\"" + encName +
'"' ) );
2911 mMapAtmLoadData.remove(it);
2913 if ( msgPart->typeStr().lower() ==
"text" ) {
2914 msgPart->setCharset(partCharset);
2918 TDEConfigGroup composer(KMKernel::config(),
"Composer");
2919 if ( GlobalSettings::self()->showMessagePartDialogOnAttach() ) {
2923 for ( TQValueListConstIterator<int> it = allowedCTEs.begin() ;
2924 it != allowedCTEs.end() ; ++it )
2926 case DwMime::kCteBase64: encodings |= KMMsgPartDialog::Base64;
break;
2927 case DwMime::kCteQp: encodings |= KMMsgPartDialog::QuotedPrintable;
break;
2928 case DwMime::kCte7bit: encodings |= KMMsgPartDialog::SevenBit;
break;
2929 case DwMime::kCte8bit: encodings |= KMMsgPartDialog::EightBit;
break;
2932 dlg.setShownEncodings( encodings );
2933 dlg.setMsgPart(msgPart);
2938 emit attachmentAdded(attachURL,
false);
2942 mAtmModified =
true;
2948 emit attachmentAdded(attachURL,
true);
2953 void KMComposeWin::slotInsertFile()
2955 KFileDialog fdlg(TQString(), TQString(),
this, 0,
true);
2956 fdlg.setOperationMode( KFileDialog::Opening );
2957 fdlg.okButton()->setText(i18n(
"&Insert"));
2958 fdlg.setCaption(i18n(
"Insert File"));
2959 fdlg.toolBar()->insertCombo(KMMsgBase::supportedEncodings(
false), 4711,
2961 KComboBox *combo = fdlg.toolBar()->getCombo(4711);
2962 for (
int i = 0; i < combo->count(); i++)
2963 if (TDEGlobal::charsets()->codecForName(TDEGlobal::charsets()->
2964 encodingForName(combo->text(i)))
2965 == TQTextCodec::codecForLocale()) combo->setCurrentItem(i);
2966 if (!fdlg.exec())
return;
2968 KURL u = fdlg.selectedURL();
2969 mRecentAction->addURL(u);
2972 TDEConfig *config = KMKernel::config();
2973 TDEConfigGroupSaver saver( config,
"Composer" );
2974 TQString encoding = TDEGlobal::charsets()->encodingForName(combo->currentText()).latin1();
2975 TQStringList urls = config->readListEntry(
"recent-urls" );
2976 TQStringList encodings = config->readListEntry(
"recent-encodings" );
2979 uint mMaxRecentFiles = 30;
2980 while (urls.count() > mMaxRecentFiles)
2981 urls.erase( urls.fromLast() );
2982 while (encodings.count() > mMaxRecentFiles)
2983 encodings.erase( encodings.fromLast() );
2985 if (urls.count() != encodings.count()) {
2989 urls.prepend( u.prettyURL() );
2990 encodings.prepend( encoding );
2991 config->writeEntry(
"recent-urls", urls );
2992 config->writeEntry(
"recent-encodings", encodings );
2993 mRecentAction->saveEntries( config );
2995 slotInsertRecentFile(u);
3000 void KMComposeWin::slotInsertRecentFile(
const KURL& u)
3002 if (u.fileName().isEmpty())
return;
3004 TDEIO::Job *job = TDEIO::get(u);
3007 ld.data = TQByteArray();
3011 TDEConfig *config = KMKernel::config();
3012 TDEConfigGroupSaver saver( config,
"Composer" );
3013 TQStringList urls = config->readListEntry(
"recent-urls" );
3014 TQStringList encodings = config->readListEntry(
"recent-encodings" );
3015 int index = urls.findIndex( u.prettyURL() );
3017 TQString encoding = encodings[ index ];
3018 ld.encoding = encoding.latin1();
3021 mMapAtmLoadData.insert(job, ld);
3022 connect(job, TQ_SIGNAL(result(TDEIO::Job *)),
3023 this, TQ_SLOT(slotAttachFileResult(TDEIO::Job *)));
3024 connect(job, TQ_SIGNAL(data(TDEIO::Job *,
const TQByteArray &)),
3025 this, TQ_SLOT(slotAttachFileData(TDEIO::Job *,
const TQByteArray &)));
3030 void KMComposeWin::slotSetCharset()
3032 if (mEncodingAction->currentItem() == 0)
3034 mAutoCharset =
true;
3037 mAutoCharset =
false;
3039 mCharset = TDEGlobal::charsets()->encodingForName( mEncodingAction->
3040 currentText() ).latin1();
3045 void KMComposeWin::slotSelectCryptoModule(
bool init )
3048 setModified(
true );
3050 if( canSignEncryptAttachments() ) {
3052 if( 0 == mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3055 if( !mAtmList.isEmpty() ) {
3056 for( KMAtmListViewItem* lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.first() );
3058 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3059 lvi->setSign( mSignAction->isChecked() );
3060 lvi->setEncrypt( mEncryptAction->isChecked() );
3065 for(
int col=0; col < mAtmColEncrypt; col++ )
3066 totalWidth += mAtmListView->columnWidth( col );
3067 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3072 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3073 int newWidth = mAtmListView->columnWidth( col ) * reducedTotalWidth
3075 mAtmListView->setColumnWidth( col, newWidth );
3076 usedWidth += newWidth;
3081 mAtmListView->setColumnWidth( mAtmColEncrypt-1,
3082 reducedTotalWidth - usedWidth );
3083 mAtmListView->setColumnWidth( mAtmColEncrypt, mAtmEncryptColWidth );
3084 mAtmListView->setColumnWidth( mAtmColSign, mAtmSignColWidth );
3085 for( KMAtmListViewItem* lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.first() );
3087 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3088 lvi->enableCryptoCBs(
true );
3093 if( 0 != mAtmListView->columnWidth( mAtmColEncrypt ) ) {
3094 mAtmEncryptColWidth = mAtmListView->columnWidth( mAtmColEncrypt );
3095 mAtmSignColWidth = mAtmListView->columnWidth( mAtmColSign );
3098 for(
int col=0; col < mAtmListView->columns(); col++ )
3099 totalWidth += mAtmListView->columnWidth( col );
3100 int reducedTotalWidth = totalWidth - mAtmEncryptColWidth
3105 for(
int col=0; col < mAtmColEncrypt-1; col++ ) {
3106 int newWidth = mAtmListView->columnWidth( col ) * totalWidth
3107 / reducedTotalWidth;
3108 mAtmListView->setColumnWidth( col, newWidth );
3109 usedWidth += newWidth;
3114 mAtmListView->setColumnWidth( mAtmColEncrypt-1, totalWidth - usedWidth );
3115 mAtmListView->setColumnWidth( mAtmColEncrypt, 0 );
3116 mAtmListView->setColumnWidth( mAtmColSign, 0 );
3117 for( KMAtmListViewItem* lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.first() );
3119 lvi =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) ) {
3120 lvi->enableCryptoCBs(
false );
3126 static void showExportError( TQWidget * w,
const GpgME::Error & err ) {
3128 const TQString msg = i18n(
"<qt><p>An error occurred while trying to export "
3129 "the key from the backend:</p>"
3130 "<p><b>%1</b></p></qt>")
3131 .arg( TQString::fromLocal8Bit( err.asString() ) );
3132 KMessageBox::error( w, msg, i18n(
"Key Export Failed") );
3137 void KMComposeWin::slotInsertMyPublicKey()
3141 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() ).pgpEncryptionKey();
3142 if ( !mFingerprint.isEmpty() )
3143 startPublicKeyExport();
3146 void KMComposeWin::startPublicKeyExport() {
3147 if ( mFingerprint.isEmpty() || !Kleo::CryptoBackendFactory::instance()->openpgp() )
3149 Kleo::ExportJob * job = Kleo::CryptoBackendFactory::instance()->openpgp()->publicKeyExportJob(
true );
3152 connect( job, TQ_SIGNAL(result(
const GpgME::Error&,
const TQByteArray&)),
3153 this, TQ_SLOT(slotPublicKeyExportResult(
const GpgME::Error&,
const TQByteArray&)) );
3155 const GpgME::Error err = job->start( mFingerprint );
3157 showExportError(
this, err );
3159 (
void)
new Kleo::ProgressDialog( job, i18n(
"Exporting key..."),
this );
3162 void KMComposeWin::slotPublicKeyExportResult(
const GpgME::Error & err,
const TQByteArray & keydata ) {
3164 showExportError(
this, err );
3169 KMMessagePart * msgPart =
new KMMessagePart();
3170 msgPart->setName( i18n(
"OpenPGP key 0x%1").arg( mFingerprint ) );
3171 msgPart->setTypeStr(
"application");
3172 msgPart->setSubtypeStr(
"pgp-keys");
3173 TQValueList<int> dummy;
3174 msgPart->setBodyAndGuessCte(keydata, dummy,
false);
3175 msgPart->setContentDisposition(
"attachment;\n\tfilename=0x" + TQCString( mFingerprint.latin1() ) +
".asc" );
3183 void KMComposeWin::slotInsertPublicKey()
3185 Kleo::KeySelectionDialog dlg( i18n(
"Attach Public OpenPGP Key"),
3186 i18n(
"Select the public key which should "
3188 std::vector<GpgME::Key>(),
3189 Kleo::KeySelectionDialog::PublicKeys|Kleo::KeySelectionDialog::OpenPGPKeys,
3192 this,
"attach public key selection dialog" );
3193 if ( dlg.exec() != TQDialog::Accepted )
3196 mFingerprint = dlg.fingerprint();
3197 startPublicKeyExport();
3202 void KMComposeWin::slotAttachPopupMenu(TQListViewItem *,
const TQPoint &,
int)
3206 mAttachMenu =
new TQPopupMenu(
this);
3208 mOpenId = mAttachMenu->insertItem(i18n(
"to open",
"Open"),
this,
3209 TQ_SLOT(slotAttachOpen()));
3210 mOpenWithId = mAttachMenu->insertItem(i18n(
"Open With..."),
this,
3211 TQ_SLOT(slotAttachOpenWith()));
3212 mViewId = mAttachMenu->insertItem(i18n(
"to view",
"View"),
this,
3213 TQ_SLOT(slotAttachView()));
3214 mEditId = mAttachMenu->insertItem( i18n(
"Edit"),
this, TQ_SLOT(slotAttachEdit()) );
3215 mEditWithId = mAttachMenu->insertItem( i18n(
"Edit With..."),
this,
3216 TQ_SLOT(slotAttachEditWith()) );
3217 mRemoveId = mAttachMenu->insertItem(i18n(
"Remove"),
this, TQ_SLOT(slotAttachRemove()));
3218 mSaveAsId = mAttachMenu->insertItem( SmallIconSet(
"document-save-as"), i18n(
"Save As..."),
this,
3219 TQ_SLOT( slotAttachSave() ) );
3220 mPropertiesId = mAttachMenu->insertItem( i18n(
"Properties"),
this,
3221 TQ_SLOT( slotAttachProperties() ) );
3222 mAttachMenu->insertSeparator();
3223 mAttachMenu->insertItem(i18n(
"Add Attachment..."),
this, TQ_SLOT(slotAttachFile()));
3226 int selectedCount = 0;
3227 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it ) {
3228 if ( (*it)->isSelected() ) {
3233 mAttachMenu->setItemEnabled( mOpenId, selectedCount > 0 );
3234 mAttachMenu->setItemEnabled( mOpenWithId, selectedCount > 0 );
3235 mAttachMenu->setItemEnabled( mViewId, selectedCount > 0 );
3236 mAttachMenu->setItemEnabled( mEditId, selectedCount == 1 );
3237 mAttachMenu->setItemEnabled( mEditWithId, selectedCount == 1 );
3238 mAttachMenu->setItemEnabled( mRemoveId, selectedCount > 0 );
3239 mAttachMenu->setItemEnabled( mSaveAsId, selectedCount == 1 );
3240 mAttachMenu->setItemEnabled( mPropertiesId, selectedCount == 1 );
3242 mAttachMenu->popup(TQCursor::pos());
3246 int KMComposeWin::currentAttachmentNum()
3249 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i )
3250 if ( *it == mAtmListView->currentItem() )
3256 void KMComposeWin::slotAttachProperties()
3258 int idx = currentAttachmentNum();
3260 if (idx < 0)
return;
3262 KMMessagePart* msgPart = mAtmList.at(idx);
3265 dlg.setMsgPart(msgPart);
3266 KMAtmListViewItem* listItem = (KMAtmListViewItem*)(mAtmItemList.at(idx));
3267 if( canSignEncryptAttachments() && listItem ) {
3268 dlg.setCanSign(
true );
3269 dlg.setCanEncrypt(
true );
3270 dlg.setSigned( listItem->isSign() );
3271 dlg.setEncrypted( listItem->isEncrypt() );
3273 dlg.setCanSign(
false );
3274 dlg.setCanEncrypt(
false );
3278 mAtmModified =
true;
3281 msgPartToItem(msgPart, listItem);
3282 if( canSignEncryptAttachments() ) {
3283 listItem->setSign( dlg.isSigned() );
3284 listItem->setEncrypt( dlg.isEncrypted() );
3291 void KMComposeWin::compressAttach(
int idx )
3293 if (idx < 0)
return;
3296 for ( i = 0; i < mAtmItemList.count(); ++i )
3297 if ( mAtmItemList.at( i )->itemPos() == idx )
3300 if ( i > mAtmItemList.count() )
3303 KMMessagePart* msgPart;
3304 msgPart = mAtmList.at( i );
3306 TQBuffer dev( array );
3308 TQByteArray decoded = msgPart->bodyDecodedBinary();
3309 if ( ! zip.open( IO_WriteOnly ) ) {
3310 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3311 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3315 zip.setCompression( KZip::DeflateCompression );
3316 if ( ! zip.writeFile( msgPart->name(),
"",
"", decoded.size(),
3317 decoded.data() ) ) {
3318 KMessageBox::sorry(0, i18n(
"KMail could not compress the file.") );
3319 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3323 if ( array.size() >= decoded.size() ) {
3324 if ( KMessageBox::questionYesNo(
this, i18n(
"The compressed file is larger "
3325 "than the original. Do you want to keep the original one?" ), TQString(), i18n(
"Keep"), i18n(
"Compress") )
3326 == KMessageBox::Yes ) {
3327 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setCompress(
false );
3331 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedCodec(
3332 msgPart->cteStr() );
3334 msgPart->setCteStr(
"base64" );
3335 msgPart->setBodyEncodedBinary( array );
3336 TQString name = msgPart->name() +
".zip";
3338 msgPart->setName( name );
3340 TQCString cDisp =
"attachment;";
3341 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3343 kdDebug(5006) <<
"encoding: " << encoding << endl;
3344 if ( encoding.isEmpty() ) encoding =
"utf-8";
3345 kdDebug(5006) <<
"encoding after: " << encoding << endl;
3347 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3348 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3350 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3352 cDisp +=
"\n\tfilename";
3353 if ( name != TQString( encName ) )
3354 cDisp +=
"*=" + encName;
3356 cDisp +=
"=\"" + encName +
'"';
3357 msgPart->setContentDisposition( cDisp );
3359 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->setUncompressedMimeType(
3360 msgPart->typeStr(), msgPart->subtypeStr() );
3361 msgPart->setTypeStr(
"application" );
3362 msgPart->setSubtypeStr(
"x-zip" );
3364 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) );
3365 msgPartToItem( msgPart, listItem,
false );
3370 void KMComposeWin::uncompressAttach(
int idx )
3372 if (idx < 0)
return;
3375 for ( i = 0; i < mAtmItemList.count(); ++i )
3376 if ( mAtmItemList.at( i )->itemPos() == idx )
3379 if ( i > mAtmItemList.count() )
3382 KMMessagePart* msgPart;
3383 msgPart = mAtmList.at( i );
3385 TQBuffer dev( msgPart->bodyDecodedBinary() );
3387 TQByteArray decoded;
3389 decoded = msgPart->bodyDecodedBinary();
3390 if ( ! zip.open( IO_ReadOnly ) ) {
3391 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3392 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3395 const KArchiveDirectory *dir = zip.directory();
3397 KZipFileEntry *entry;
3398 if ( dir->entries().count() != 1 ) {
3399 KMessageBox::sorry(0, i18n(
"KMail could not uncompress the file.") );
3400 static_cast<KMAtmListViewItem *
>( mAtmItemList.at( i ) )->setCompress(
true );
3403 entry = (KZipFileEntry*)dir->entry( dir->entries()[0] );
3406 static_cast<KMAtmListViewItem*
>( mAtmItemList.at(i) )->uncompressedCodec() );
3408 msgPart->setBodyEncodedBinary( entry->data() );
3409 TQString name = entry->name();
3410 msgPart->setName( name );
3414 TQCString cDisp =
"attachment;";
3415 TQCString encoding = KMMsgBase::autoDetectCharset( msgPart->charset(),
3417 if ( encoding.isEmpty() ) encoding =
"utf-8";
3420 if ( GlobalSettings::self()->outlookCompatibleAttachments() )
3421 encName = KMMsgBase::encodeRFC2047String( name, encoding );
3423 encName = KMMsgBase::encodeRFC2231String( name, encoding );
3425 cDisp +=
"\n\tfilename";
3426 if ( name != TQString( encName ) )
3427 cDisp +=
"*=" + encName;
3429 cDisp +=
"=\"" + encName +
'"';
3430 msgPart->setContentDisposition( cDisp );
3432 TQCString type, subtype;
3433 static_cast<KMAtmListViewItem*
>( mAtmItemList.at( i ) )->uncompressedMimeType( type,
3436 msgPart->setTypeStr( type );
3437 msgPart->setSubtypeStr( subtype );
3439 KMAtmListViewItem* listItem =
static_cast<KMAtmListViewItem*
>(mAtmItemList.at( i ));
3440 msgPartToItem( msgPart, listItem,
false );
3445 void KMComposeWin::slotAttachView()
3448 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3449 if ( (*it)->isSelected() ) {
3455 void KMComposeWin::slotAttachOpen()
3458 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3459 if ( (*it)->isSelected() ) {
3460 openAttach( i,
false );
3466 void KMComposeWin::slotAttachOpenWith()
3469 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3470 if ( (*it)->isSelected() ) {
3471 openAttach( i,
true );
3476 void KMComposeWin::slotAttachEdit()
3479 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3480 if ( (*it)->isSelected() ) {
3481 editAttach( i,
false );
3486 void KMComposeWin::slotAttachEditWith()
3489 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++i ) {
3490 if ( (*it)->isSelected() ) {
3491 editAttach( i,
true );
3497 bool KMComposeWin::inlineSigningEncryptionSelected() {
3498 if ( !mSignAction->isChecked() && !mEncryptAction->isChecked() )
3500 return cryptoMessageFormat() == Kleo::InlineOpenPGPFormat;
3504 void KMComposeWin::viewAttach(
int index )
3507 KMMessagePart* msgPart;
3508 msgPart = mAtmList.at(index);
3509 pname = msgPart->name().stripWhiteSpace();
3510 if (pname.isEmpty()) pname=msgPart->contentDescription();
3511 if (pname.isEmpty()) pname=
"unnamed";
3513 KTempFile* atmTempFile =
new KTempFile();
3514 mAtmTempList.append( atmTempFile );
3515 atmTempFile->setAutoDelete(
true );
3516 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3518 KMReaderMainWin *win =
new KMReaderMainWin(msgPart,
false,
3519 atmTempFile->name(), pname, mCharset );
3524 void KMComposeWin::openAttach(
int index,
bool with )
3526 KMMessagePart* msgPart = mAtmList.at(index);
3527 const TQString contentTypeStr =
3528 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3530 KMimeType::Ptr mimetype;
3531 mimetype = KMimeType::mimeType( contentTypeStr );
3533 KTempFile* atmTempFile =
new KTempFile();
3534 mAtmTempList.append( atmTempFile );
3535 const bool autoDelete =
true;
3536 atmTempFile->setAutoDelete( autoDelete );
3539 url.setPath( atmTempFile->name() );
3541 KPIM::kByteArrayToFile( msgPart->bodyDecodedBinary(), atmTempFile->name(),
false,
false,
3543 if ( ::chmod( TQFile::encodeName( atmTempFile->name() ), S_IRUSR ) != 0) {
3544 TQFile::remove(url.path());
3548 KService::Ptr offer =
3549 KServiceTypeProfile::preferredService( mimetype->name(),
"Application" );
3551 if ( with || !offer || mimetype->name() ==
"application/octet-stream" ) {
3552 if ( ( !KRun::displayOpenWithDialog( url, autoDelete ) ) && autoDelete ) {
3553 TQFile::remove(url.path());
3557 if ( ( !KRun::run( *offer, url, autoDelete ) ) && autoDelete ) {
3558 TQFile::remove( url.path() );
3563 void KMComposeWin::editAttach(
int index,
bool openWith)
3565 KMMessagePart* msgPart = mAtmList.at(index);
3566 const TQString contentTypeStr =
3567 ( msgPart->typeStr() +
'/' + msgPart->subtypeStr() ).lower();
3569 KTempFile* atmTempFile =
new KTempFile();
3570 mAtmTempList.append( atmTempFile );
3571 atmTempFile->setAutoDelete(
true );
3572 atmTempFile->file()->writeBlock( msgPart->bodyDecodedBinary() );
3573 atmTempFile->file()->flush();
3580 if ( watcher->start() ) {
3581 mEditorMap.insert( watcher, msgPart );
3582 mEditorTempFiles.insert( watcher, atmTempFile );
3587 void KMComposeWin::slotAttachSave()
3589 KMMessagePart* msgPart;
3590 TQString fileName, pname;
3591 int idx = currentAttachmentNum();
3593 if (idx < 0)
return;
3595 msgPart = mAtmList.at(idx);
3596 pname = msgPart->name();
3597 if (pname.isEmpty()) pname=
"unnamed";
3599 KURL url = KFileDialog::getSaveURL(pname, TQString(), 0, i18n(
"Save Attachment As"));
3604 kmkernel->byteArrayToRemoteFile(msgPart->bodyDecodedBinary(), url);
3609 void KMComposeWin::slotAttachRemove()
3612 bool attachmentRemoved =
false;
3614 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ) {
3615 if ( (*it)->isSelected() ) {
3617 attachmentRemoved =
true;
3625 if ( attachmentRemoved ) {
3626 setModified(
true );
3627 slotUpdateAttachActions();
3628 if ( mAtmSelectNew ) {
3629 mAtmListView->setSelected( mAtmSelectNew,
true );
3630 mAtmListView->setCurrentItem( mAtmSelectNew );
3636 void KMComposeWin::slotFind()
3641 void KMComposeWin::slotSearchAgain()
3643 mEditor->repeatSearch();
3647 void KMComposeWin::slotReplace()
3653 void KMComposeWin::slotUpdateFont()
3655 kdDebug() <<
"KMComposeWin::slotUpdateFont " << endl;
3656 if ( ! mFixedFontAction ) {
3659 mEditor->setFont( mFixedFontAction->isChecked() ? mFixedFont : mBodyFont );
3662 TQString KMComposeWin::quotePrefixName()
const
3667 int languageNr = GlobalSettings::self()->replyCurrentLanguage();
3668 ReplyPhrases replyPhrases( TQString::number(languageNr) );
3669 replyPhrases.readConfig();
3670 TQString quotePrefix = msg()->formatString(
3671 replyPhrases.indentPrefix() );
3673 quotePrefix = msg()->formatString(quotePrefix);
3677 void KMComposeWin::slotPasteClipboardAsQuotation()
3679 if( mEditor->hasFocus() && msg() )
3681 TQString s = TQApplication::clipboard()->text();
3683 mEditor->insert(addQuotesToText(s));
3687 void KMComposeWin::slotPasteClipboardAsAttachment()
3689 KURL url( TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3690 if ( url.isValid() ) {
3691 addAttach(TQApplication::clipboard()->text( TQClipboard::Clipboard ) );
3695 TQMimeSource *mimeSource = TQApplication::clipboard()->data();
3696 if ( TQImageDrag::canDecode(mimeSource) ) {
3697 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3701 TQString attName = KInputDialog::getText(
"KMail", i18n(
"Name of the attachment:"), TQString(), &ok,
this );
3704 KMMessagePart *msgPart =
new KMMessagePart;
3705 msgPart->setName(attName);
3706 TQValueList<int> dummy;
3707 msgPart->setBodyAndGuessCte(TQCString(TQApplication::clipboard()->text().latin1()), dummy,
3708 kmkernel->msgSender()->sendQuotedPrintable());
3713 void KMComposeWin::slotAddQuotes()
3715 if( mEditor->hasFocus() && msg() )
3721 if ( mEditor->hasMarkedText() ) {
3722 TQString s = mEditor->markedText();
3724 mEditor->insert(addQuotesToText(s));
3726 int l = mEditor->currentLine();
3727 int c = mEditor->currentColumn();
3728 TQString s = mEditor->textLine(l);
3729 s.prepend(quotePrefixName());
3730 mEditor->insertLine(s,l);
3731 mEditor->removeLine(l+1);
3732 mEditor->setCursorPosition(l,c+2);
3737 TQString KMComposeWin::addQuotesToText(
const TQString &inputText)
3739 TQString answer = TQString( inputText );
3740 TQString indentStr = quotePrefixName();
3741 answer.replace(
'\n',
'\n' + indentStr);
3742 answer.prepend( indentStr );
3747 TQString KMComposeWin::removeQuotesFromText(
const TQString &inputText)
3749 TQString s = inputText;
3752 TQString quotePrefix =
'^' + quotePrefixName();
3753 TQRegExp rx(quotePrefix);
3757 quotePrefix =
'\n' + quotePrefixName();
3759 s.replace(rx,
"\n");
3764 void KMComposeWin::slotRemoveQuotes()
3766 if( mEditor->hasFocus() && msg() )
3772 if ( mEditor->hasMarkedText() ) {
3773 TQString s = mEditor->markedText();
3774 mEditor->insert(removeQuotesFromText(s));
3776 int l = mEditor->currentLine();
3777 int c = mEditor->currentColumn();
3778 TQString s = mEditor->textLine(l);
3779 mEditor->insertLine(removeQuotesFromText(s),l);
3780 mEditor->removeLine(l+1);
3781 mEditor->setCursorPosition(l,c-2);
3787 void KMComposeWin::slotUndo()
3789 TQWidget* fw = focusWidget();
3792 if ( ::tqt_cast<KEdit*>(fw) )
3793 static_cast<TQTextEdit*
>(fw)->undo();
3794 else if (::tqt_cast<TQLineEdit*>(fw))
3795 static_cast<TQLineEdit*
>(fw)->undo();
3798 void KMComposeWin::slotRedo()
3800 TQWidget* fw = focusWidget();
3803 if (::tqt_cast<KEdit*>(fw))
3804 static_cast<KEdit*
>(fw)->redo();
3805 else if (::tqt_cast<TQLineEdit*>(fw))
3806 static_cast<TQLineEdit*
>(fw)->redo();
3810 void KMComposeWin::slotCut()
3812 TQWidget* fw = focusWidget();
3815 if (::tqt_cast<KEdit*>(fw))
3816 static_cast<KEdit*
>(fw)->cut();
3817 else if (::tqt_cast<TQLineEdit*>(fw))
3818 static_cast<TQLineEdit*
>(fw)->cut();
3823 void KMComposeWin::slotCopy()
3825 TQWidget* fw = focusWidget();
3832 TQKeyEvent k(TQEvent::KeyPress, Key_C, 0, ControlButton);
3833 kapp->notify(fw, &k);
3838 void KMComposeWin::slotPasteClipboard()
3840 paste( TQClipboard::Clipboard );
3843 void KMComposeWin::paste( TQClipboard::Mode mode )
3845 TQWidget* fw = focusWidget();
3848 TQMimeSource *mimeSource = TQApplication::clipboard()->data( mode );
3849 if ( mimeSource->provides(
"image/png") ) {
3850 slotAttachPNGImageData(mimeSource->encodedData(
"image/png"));
3851 }
else if ( KURLDrag::canDecode( mimeSource ) ) {
3853 if( KURLDrag::decode( mimeSource, urlList ) ) {
3854 const TQString asText = i18n(
"Add as Text");
3855 const TQString asAttachment = i18n(
"Add as Attachment");
3856 const TQString text = i18n(
"Please select whether you want to insert the content as text into the editor, "
3857 "or append the referenced file as an attachment.");
3858 const TQString caption = i18n(
"Paste as text or attachment?");
3860 int id = KMessageBox::questionYesNoCancel(
this, text, caption,
3861 KGuiItem( asText ), KGuiItem( asAttachment) );
3863 case KMessageBox::Yes:
3864 for ( KURL::List::Iterator it = urlList.begin();
3865 it != urlList.end(); ++it ) {
3866 mEditor->insert( (*it).url() );
3869 case KMessageBox::No:
3870 for ( KURL::List::Iterator it = urlList.begin();
3871 it != urlList.end(); ++it ) {
3877 }
else if ( TQTextDrag::canDecode( mimeSource ) ) {
3879 if ( TQTextDrag::decode( mimeSource, s ) )
3880 mEditor->insert( s );
3886 void KMComposeWin::slotMarkAll()
3888 TQWidget* fw = focusWidget();
3891 if (::tqt_cast<TQLineEdit*>(fw))
3892 static_cast<TQLineEdit*
>(fw)->selectAll();
3893 else if (::tqt_cast<KEdit*>(fw))
3894 static_cast<KEdit*
>(fw)->selectAll();
3899 void KMComposeWin::slotClose()
3906 void KMComposeWin::slotNewComposer()
3912 win =
new KMComposeWin(msg);
3918 void KMComposeWin::slotNewMailReader()
3920 KMMainWin *kmmwin =
new KMMainWin(0);
3927 void KMComposeWin::slotUpdWinTitle(
const TQString& text)
3933 setCaption(
"("+i18n(
"unnamed")+
")");
3934 else setCaption( s.replace( TQChar(
'\n'),
' ' ) );
3939 void KMComposeWin::slotEncryptToggled(
bool on)
3941 setEncryption( on,
true );
3942 slotUpdateSignatureAndEncrypionStateIndicators();
3947 void KMComposeWin::setEncryption(
bool encrypt,
bool setByUser )
3949 bool wasModified = isModified();
3951 setModified(
true );
3952 if ( !mEncryptAction->isEnabled() )
3956 else if ( encrypt && encryptToSelf() && !mLastIdentityHasEncryptionKey ) {
3958 KMessageBox::sorry(
this,
3959 i18n(
"<qt><p>You have requested that messages be "
3960 "encrypted to yourself, but the currently selected "
3961 "identity does not define an (OpenPGP or S/MIME) "
3962 "encryption key to use for this.</p>"
3963 "<p>Please select the key(s) to use "
3964 "in the identity configuration.</p>"
3966 i18n(
"Undefined Encryption Key") );
3967 setModified( wasModified );
3973 mEncryptAction->setChecked( encrypt );
3977 mEncryptAction->setIcon(
"encrypted");
3979 mEncryptAction->setIcon(
"decrypted");
3982 if ( canSignEncryptAttachments() ) {
3983 for ( KMAtmListViewItem* entry =
3984 static_cast<KMAtmListViewItem*
>( mAtmItemList.first() );
3986 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
3987 entry->setEncrypt( encrypt );
3993 void KMComposeWin::slotSignToggled(
bool on)
3995 setSigning( on,
true );
3996 slotUpdateSignatureAndEncrypionStateIndicators();
4001 void KMComposeWin::setSigning(
bool sign,
bool setByUser )
4003 bool wasModified = isModified();
4005 setModified(
true );
4006 if ( !mSignAction->isEnabled() )
4010 if ( sign && !mLastIdentityHasSigningKey ) {
4012 KMessageBox::sorry(
this,
4013 i18n(
"<qt><p>In order to be able to sign "
4014 "this message you first have to "
4015 "define the (OpenPGP or S/MIME) signing key "
4017 "<p>Please select the key to use "
4018 "in the identity configuration.</p>"
4020 i18n(
"Undefined Signing Key") );
4021 setModified( wasModified );
4027 mSignAction->setChecked( sign );
4030 if ( canSignEncryptAttachments() ) {
4031 for ( KMAtmListViewItem* entry =
4032 static_cast<KMAtmListViewItem*
>( mAtmItemList.first() );
4034 entry =
static_cast<KMAtmListViewItem*
>( mAtmItemList.next() ) )
4035 entry->setSign( sign );
4041 void KMComposeWin::slotWordWrapToggled(
bool on)
4045 mEditor->setWordWrap( TQTextEdit::FixedColumnWidth );
4046 mEditor->setWrapColumnOrWidth( GlobalSettings::self()->lineWrapWidth() );
4050 mEditor->setWordWrap( TQTextEdit::WidgetWidth );
4055 void KMComposeWin::disableWordWrap()
4057 mEditor->setWordWrap( TQTextEdit::NoWrap );
4060 void KMComposeWin::disableRecipientNumberCheck()
4062 mCheckForRecipients =
false;
4065 void KMComposeWin::disableForgottenAttachmentsCheck()
4067 mCheckForForgottenAttachments =
false;
4070 void KMComposeWin::ignoreStickyFields()
4072 mIgnoreStickyFields =
true;
4073 mBtnTransport->setChecked(
false );
4074 mBtnDictionary->setChecked(
false );
4075 mBtnIdentity->setChecked(
false );
4076 mBtnTransport->setEnabled(
false );
4077 mBtnDictionary->setEnabled(
false );
4078 mBtnIdentity->setEnabled(
false );
4082 void KMComposeWin::slotPrint()
4084 mMessageWasModified = isModified();
4085 connect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
4086 this, TQ_SLOT( slotContinuePrint(
bool ) ) );
4087 applyChanges(
true );
4090 void KMComposeWin::slotContinuePrint(
bool rc )
4092 disconnect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
4093 this, TQ_SLOT( slotContinuePrint(
bool ) ) );
4096 if ( mComposedMessages.isEmpty() ) {
4097 kdDebug(5006) <<
"Composing the message failed." << endl;
4100 KMCommand *command =
new KMPrintCommand(
this, mComposedMessages.first() );
4102 setModified( mMessageWasModified );
4107 bool KMComposeWin::validateAddresses( TQWidget * parent,
const TQString & addresses )
4109 TQString brokenAddress;
4111 if ( !( errorCode == KPIM::AddressOk || errorCode == KPIM::AddressEmpty ) ) {
4112 TQString errorMsg(
"<qt><p><b>" + brokenAddress +
4113 "</b></p><p>" + KPIM::emailParseResultToString( errorCode ) +
4115 KMessageBox::sorry( parent, errorMsg, i18n(
"Invalid Email Address") );
4122 void KMComposeWin::doSend( KMail::MessageSender::SendMethod method,
4123 KMComposeWin::SaveIn saveIn )
4125 if ( method != KMail::MessageSender::SendLater && kmkernel->isOffline() ) {
4126 KMessageBox::information(
this,
4127 i18n(
"KMail is currently in offline mode,"
4128 "your messages will be kept in the outbox until you go online."),
4129 i18n(
"Online/Offline"),
"kmailIsOffline" );
4130 mSendMethod = KMail::MessageSender::SendLater;
4132 mSendMethod = method;
4136 if ( saveIn == KMComposeWin::None ) {
4137 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() ) {
4138 if ( !( mShowHeaders & HDR_FROM ) ) {
4139 mShowHeaders |= HDR_FROM;
4140 rethinkFields(
false );
4142 mEdtFrom->setFocus();
4143 KMessageBox::sorry(
this,
4144 i18n(
"You must enter your email address in the "
4145 "From: field. You should also set your email "
4146 "address for all identities, so that you do "
4147 "not have to enter it for each message.") );
4150 if ( to().isEmpty() )
4152 if ( cc().isEmpty() && bcc().isEmpty()) {
4153 if ( mEdtTo ) mEdtTo->setFocus();
4154 KMessageBox::information(
this,
4155 i18n(
"You must specify at least one receiver,"
4156 "either in the To: field or as CC or as BCC.") );
4160 if ( mEdtTo ) mEdtTo->setFocus();
4162 KMessageBox::questionYesNo(
this,
4163 i18n(
"To field is missing."
4164 "Send message anyway?"),
4165 i18n(
"No To: specified") );
4166 if ( rc == KMessageBox::No ){
4173 if ( !validateAddresses(
this, to().stripWhiteSpace() ) ) {
4177 if ( !validateAddresses(
this, cc().stripWhiteSpace() ) ) {
4181 if ( !validateAddresses(
this, bcc().stripWhiteSpace() ) ) {
4185 if (subject().isEmpty())
4187 mEdtSubject->setFocus();
4189 KMessageBox::questionYesNo(
this,
4190 i18n(
"You did not specify a subject. "
4191 "Send message anyway?"),
4192 i18n(
"No Subject Specified"),
4193 i18n(
"S&end as Is"),
4194 i18n(
"&Specify the Subject"),
4195 "no_subject_specified" );
4196 if( rc == KMessageBox::No )
4202 if ( userForgotAttachment() )
4207 mMsg->setDateToday();
4214 TQString hf = mMsg->headerField(
"X-KMail-Transport");
4215 if ((mTransport->currentText() != mTransport->text(0)) ||
4216 (!hf.isEmpty() && (hf != mTransport->text(0))))
4217 mMsg->setHeaderField(
"X-KMail-Transport", mTransport->currentText());
4219 mDisableBreaking = ( saveIn != KMComposeWin::None );
4221 const bool neverEncrypt = ( mDisableBreaking && GlobalSettings::self()->neverEncryptDrafts() )
4222 || mSigningAndEncryptionExplicitlyDisabled;
4223 connect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
4224 TQ_SLOT( slotContinueDoSend(
bool ) ) );
4226 if ( mEditor->textFormat() == TQt::RichText )
4227 mMsg->setHeaderField(
"X-KMail-Markup",
"true" );
4229 mMsg->removeHeaderField(
"X-KMail-Markup" );
4230 if ( mEditor->textFormat() == TQt::RichText && inlineSigningEncryptionSelected() ) {
4231 TQString keepBtnText = mEncryptAction->isChecked() ?
4232 mSignAction->isChecked() ? i18n(
"&Keep markup, do not sign/encrypt" )
4233 : i18n(
"&Keep markup, do not encrypt" )
4234 : i18n(
"&Keep markup, do not sign" );
4235 TQString yesBtnText = mEncryptAction->isChecked() ?
4236 mSignAction->isChecked() ? i18n(
"Sign/Encrypt (delete markup)")
4237 : i18n(
"Encrypt (delete markup)" )
4238 : i18n(
"Sign (delete markup)" );
4239 int ret = KMessageBox::warningYesNoCancel(
this,
4240 i18n(
"<qt><p>Inline signing/encrypting of HTML messages is not possible;</p>"
4241 "<p>do you want to delete your markup?</p></qt>"),
4242 i18n(
"Sign/Encrypt Message?"),
4243 KGuiItem( yesBtnText ),
4244 KGuiItem( keepBtnText ) );
4245 if ( KMessageBox::Cancel == ret )
4247 if ( KMessageBox::No == ret ) {
4248 mEncryptAction->setChecked(
false);
4249 mSignAction->setChecked(
false);
4252 toggleMarkup(
false);
4256 if (neverEncrypt && saveIn != KMComposeWin::None ) {
4259 mMsg->setHeaderField(
"X-KMail-SignatureActionEnabled", mSignAction->isChecked()?
"true":
"false" );
4260 mMsg->setHeaderField(
"X-KMail-EncryptActionEnabled", mEncryptAction->isChecked()?
"true":
"false" );
4261 mMsg->setHeaderField(
"X-KMail-CryptoMessageFormat", TQString::number( cryptoMessageFormat() ) );
4263 mMsg->removeHeaderField(
"X-KMail-SignatureActionEnabled" );
4264 mMsg->removeHeaderField(
"X-KMail-EncryptActionEnabled" );
4265 mMsg->removeHeaderField(
"X-KMail-CryptoMessageFormat" );
4269 kdDebug(5006) <<
"KMComposeWin::doSend() - calling applyChanges()"
4271 applyChanges( neverEncrypt );
4274 bool KMComposeWin::saveDraftOrTemplate(
const TQString &folderName,
4277 KMFolder *theFolder = 0, *imapTheFolder = 0;
4279 if ( !folderName.isEmpty() ) {
4280 theFolder = kmkernel->folderMgr()->findIdString( folderName );
4281 if ( theFolder == 0 )
4284 theFolder = kmkernel->dimapFolderMgr()->findIdString( folderName );
4285 if ( theFolder == 0 )
4286 imapTheFolder = kmkernel->imapFolderMgr()->findIdString( folderName );
4287 if ( !theFolder && !imapTheFolder ) {
4288 const KPIM::Identity &
id = kmkernel->identityManager()
4289 ->identityForUoidOrDefault( msg->
headerField(
"X-KMail-Identity" ).stripWhiteSpace().toUInt() );
4290 KMessageBox::information( 0,
4291 i18n(
"The custom drafts or templates folder for "
4292 "identify \"%1\" does not exist (anymore); "
4293 "therefore, the default drafts or templates "
4294 "folder will be used.")
4295 .arg(
id.identityName() ) );
4298 if ( imapTheFolder && imapTheFolder->noContent() )
4301 bool didOpen =
false;
4302 if ( theFolder == 0 ) {
4303 theFolder = ( mSaveIn==KMComposeWin::Drafts ?
4304 kmkernel->draftsFolder() : kmkernel->templatesFolder() );
4307 theFolder->
open(
"composer" );
4310 kdDebug(5006) << k_funcinfo <<
"theFolder=" << theFolder->name() << endl;
4311 if ( imapTheFolder )
4312 kdDebug(5006) << k_funcinfo <<
"imapTheFolder=" << imapTheFolder->name() << endl;
4314 bool sentOk = !( theFolder->
addMsg( msg ) );
4318 msg = theFolder->
getMsg( theFolder->
count() - 1 );
4321 if ( imapTheFolder ) {
4323 imapTheFolder->moveMsg( msg );
4324 (
static_cast<KMFolderImap*
>( imapTheFolder->storage() ))->getFolder();
4328 theFolder->
close(
"composer" );
4332 void KMComposeWin::slotContinueDoSend(
bool sentOk )
4334 kdDebug(5006) <<
"KMComposeWin::slotContinueDoSend( " << sentOk <<
" )"
4336 disconnect(
this, TQ_SIGNAL( applyChangesDone(
bool ) ),
4337 this, TQ_SLOT( slotContinueDoSend(
bool ) ) );
4340 mDisableBreaking =
false;
4344 for ( TQValueVector<KMMessage*>::iterator it = mComposedMessages.begin() ; it != mComposedMessages.end() ; ++it ) {
4347 (*it)->cleanupHeader();
4350 (*it)->setComplete(
true );
4352 if ( mSaveIn==KMComposeWin::Drafts ) {
4353 sentOk = saveDraftOrTemplate( (*it)->drafts(), (*it) );
4354 }
else if ( mSaveIn==KMComposeWin::Templates ) {
4355 sentOk = saveDraftOrTemplate( (*it)->templates(), (*it) );
4359 if( !mComposer->originalBCC().isEmpty() )
4361 TQString recips = (*it)->headerField(
"X-KMail-Recipients" );
4362 if( !recips.isEmpty() ) {
4365 (*it)->cleanupHeader();
4366 sentOk = kmkernel->msgSender()->send((*it), mSendMethod);
4375 RecentAddresses::self( KMKernel::config() )->add( bcc() );
4376 RecentAddresses::self( KMKernel::config() )->add( cc() );
4377 RecentAddresses::self( KMKernel::config() )->add( to() );
4379 setModified(
false );
4380 mAutoDeleteMsg =
false;
4387 bool KMComposeWin::checkTransport()
const
4390 KMessageBox::information( mMainWidget,
4391 i18n(
"Please create an account for sending and try again.") );
4399 void KMComposeWin::slotSendLater()
4401 if ( !checkTransport() )
4403 if ( !checkRecipientNumber() )
4405 if ( mEditor->checkExternalEditorFinished() )
4406 doSend( KMail::MessageSender::SendLater );
4411 void KMComposeWin::slotSaveDraft() {
4412 if ( mEditor->checkExternalEditorFinished() )
4413 doSend( KMail::MessageSender::SendLater, KMComposeWin::Drafts );
4417 void KMComposeWin::slotSaveTemplate() {
4418 if ( mEditor->checkExternalEditorFinished() )
4419 doSend( KMail::MessageSender::SendLater, KMComposeWin::Templates );
4423 void KMComposeWin::slotSendNowVia(
int item )
4426 TQString customTransport = availTransports[ item ];
4428 mTransport->setCurrentText( customTransport );
4433 void KMComposeWin::slotSendLaterVia(
int item )
4436 TQString customTransport = availTransports[ item ];
4438 mTransport->setCurrentText( customTransport );
4444 void KMComposeWin::slotSendNow() {
4445 if ( !mEditor->checkExternalEditorFinished() )
4447 if ( !checkTransport() )
4449 if ( !checkRecipientNumber() )
4451 if ( GlobalSettings::self()->confirmBeforeSend() )
4453 int rc = KMessageBox::warningYesNoCancel( mMainWidget,
4454 i18n(
"About to send email..."),
4455 i18n(
"Send Confirmation"),
4457 i18n(
"Send &Later") );
4459 if ( rc == KMessageBox::Yes )
4460 doSend( KMail::MessageSender::SendImmediate );
4461 else if ( rc == KMessageBox::No )
4462 doSend( KMail::MessageSender::SendLater );
4465 doSend( KMail::MessageSender::SendImmediate );
4470 bool KMComposeWin::checkRecipientNumber()
const
4472 uint thresHold = GlobalSettings::self()->recipientThreshold();
4473 if ( mCheckForRecipients &&
4474 GlobalSettings::self()->tooManyRecipients() &&
4475 mRecipientsEditor->recipients().count() > thresHold ) {
4476 if ( KMessageBox::questionYesNo( mMainWidget,
4477 i18n(
"You are trying to send the mail to more than %1 recipients. Send message anyway?").arg(thresHold),
4478 i18n(
"Too many receipients"),
4479 i18n(
"&Send as Is"),
4480 i18n(
"&Edit Recipients")) == KMessageBox::No ) {
4489 void KMComposeWin::slotAppendSignature()
4495 void KMComposeWin::slotPrependSignature()
4497 insertSignature( Prepend );
4501 void KMComposeWin::slotInsertSignatureAtCursor()
4503 insertSignature( AtCursor );
4507 void KMComposeWin::insertSignature( SignaturePlacement placement )
4509 bool mod = mEditor->isModified();
4511 const KPIM::Identity &ident =
4512 kmkernel->identityManager()->
4513 identityForUoidOrDefault( mIdentity->currentIdentity() );
4515 mOldSigText = GlobalSettings::self()->prependSignature()? ident.signature().rawText() : ident.signatureText();
4517 if( !mOldSigText.isEmpty() )
4520 int paragraph, index;
4521 mEditor->getCursorPosition( ¶graph, &index );
4522 index = mEditor->indexOfCurrentLineStart( paragraph, index );
4524 switch( placement ) {
4526 mEditor->setText( mEditor->text() + mOldSigText );
4529 mOldSigText =
"\n\n" + mOldSigText +
"\n";
4530 mEditor->insertAt( mOldSigText, paragraph, index );
4537 if ( mEditor->paragraphLength( paragraph ) > 0 )
4538 mOldSigText = mOldSigText +
"\n";
4539 if ( mOldSigText.startsWith(
"\n" ) )
4540 mOldSigText = mOldSigText.remove( 0, 1 );
4545 mOldSigText =
"\n" + mOldSigText;
4547 mEditor->insertAt( mOldSigText, paragraph, index );
4551 mEditor->setModified(mod);
4553 if ( mPreserveUserCursorPosition ) {
4554 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
4559 mPreserveUserCursorPosition =
false;
4564 mEditor->setCursorPosition( paragraph, 0 );
4567 mEditor->setCursorPosition( paragraph + 1, 0 );
4569 if ( placement == Prepend || placement == Append )
4570 mEditor->setContentsPos( 0, 0 );
4577 void KMComposeWin::slotHelp()
4583 void KMComposeWin::slotCleanSpace()
4594 if ( mEditor->hasMarkedText() ) {
4595 s = mEditor->markedText();
4599 s = mEditor->text();
4604 bool restore =
false;
4605 const KPIM::Identity & ident =
4606 kmkernel->identityManager()->identityForUoid( mId );
4607 if ( !ident.isNull() ) {
4608 sig = ident.signatureText();
4609 if( !sig.isEmpty() ) {
4610 if( s.endsWith( sig ) ) {
4611 s.truncate( s.length() - sig.length() );
4618 TQRegExp squeeze(
"[\t ]+" );
4619 s.replace( squeeze, TQChar(
' ' ) );
4622 TQRegExp trailing(
"\\s+$" );
4623 s.replace( trailing, TQChar(
'\n' ) );
4626 TQRegExp singleSpace(
"[\n]{2,}" );
4627 s.replace( singleSpace, TQChar(
'\n' ) );
4640 if ( !mEditor->hasMarkedText() )
4642 mEditor->insert( s );
4646 void KMComposeWin::slotToggleMarkup()
4648 if ( markupAction->isChecked() ) {
4650 toolBar(
"htmlToolBar")->show();
4652 fontChanged( mEditor->currentFont() );
4653 mSaveFont = mEditor->currentFont();
4656 toggleMarkup(
false);
4660 void KMComposeWin::toggleMarkup(
bool markup)
4663 if ( !mUseHTMLEditor ) {
4664 kdDebug(5006) <<
"setting RichText editor" << endl;
4665 mUseHTMLEditor =
true;
4669 int paraFrom, indexFrom, paraTo, indexTo;
4670 mEditor->getSelection ( ¶From, &indexFrom, ¶To, &indexTo);
4671 mEditor->selectAll();
4673 bool _bold = textBoldAction->isChecked();
4674 bool _italic = textItalicAction->isChecked();
4675 mEditor->setColor(TQColor(0,0,0));
4676 textBoldAction->setChecked(_bold);
4677 textItalicAction->setChecked(_italic);
4678 mEditor->setSelection ( paraFrom, indexFrom, paraTo, indexTo);
4680 mEditor->setTextFormat(TQt::RichText);
4681 mEditor->setModified(
true);
4682 markupAction->setChecked(
true);
4683 toolBar(
"htmlToolBar" )->show();
4684 mEditor->deleteAutoSpellChecking();
4685 mAutoSpellCheckingAction->setChecked(
false);
4686 slotAutoSpellCheckingToggled(
false);
4689 kdDebug(5006) <<
"setting PlainText editor" << endl;
4690 mHtmlMarkup =
false;
4691 toolBar(
"htmlToolBar")->hide();
4692 if ( mUseHTMLEditor ) {
4693 mUseHTMLEditor =
false;
4694 mEditor->setTextFormat(TQt::PlainText);
4695 TQString text = mEditor->text();
4696 mEditor->setText(text);
4697 mEditor->setModified(
true);
4698 slotAutoSpellCheckingToggled(
true);
4703 void KMComposeWin::htmlToolBarVisibilityChanged(
bool visible )
4707 markupAction->setChecked(
false );
4708 toggleMarkup(
false );
4712 void KMComposeWin::slotSubjectTextSpellChecked()
4714 mSubjectTextWasSpellChecked =
true;
4718 void KMComposeWin::slotAutoSpellCheckingToggled(
bool on )
4720 if ( mEditor->autoSpellChecking(on) == -1 ) {
4721 mAutoSpellCheckingAction->setChecked(
false);
4726 temp = i18n(
"Spellcheck: on" );
4728 temp = i18n(
"Spellcheck: off" );
4729 statusBar()->changeItem( temp, 3 );
4732 void KMComposeWin::slotSpellcheck()
4734 if (mSpellCheckInProgress)
return;
4735 mSubjectTextWasSpellChecked =
false;
4736 mSpellCheckInProgress=
true;
4742 mEditor->spellcheck();
4745 void KMComposeWin::slotUpdateSignatureActions()
4749 const KPIM::Identity & ident =
4750 kmkernel->identityManager()->identityForUoidOrDefault( mIdentity->currentIdentity() );
4751 TQString sig = ident.signatureText();
4753 if ( sig.isEmpty() ) {
4754 mAppendSignatureAction->setEnabled(
false );
4755 mPrependSignatureAction->setEnabled(
false );
4756 mInsertSignatureAction->setEnabled(
false );
4759 mAppendSignatureAction->setEnabled(
true );
4760 mPrependSignatureAction->setEnabled(
true );
4761 mInsertSignatureAction->setEnabled(
true );
4765 void KMComposeWin::polish()
4768 markupAction->setChecked(mHtmlMarkup);
4770 toolBar(
"htmlToolBar")->show();
4772 toolBar(
"htmlToolBar")->hide();
4773 KMail::Composer::polish();
4777 void KMComposeWin::slotSpellcheckDone(
int result)
4779 kdDebug(5006) <<
"spell check complete: result = " << result << endl;
4780 mSpellCheckInProgress=
false;
4785 statusBar()->changeItem(i18n(
" Spell check canceled."),0);
4788 statusBar()->changeItem(i18n(
" Spell check stopped."),0);
4791 statusBar()->changeItem(i18n(
" Spell check complete."),0);
4794 TQTimer::singleShot( 2000,
this, TQ_SLOT(slotSpellcheckDoneClearStatus()) );
4797 void KMComposeWin::slotSpellcheckDoneClearStatus()
4799 statusBar()->changeItem(
"", 0);
4804 void KMComposeWin::slotIdentityChanged( uint uoid )
4806 const KPIM::Identity & ident =
4807 kmkernel->identityManager()->identityForUoid( uoid );
4808 if( ident.isNull() )
return;
4811 slotUpdateSignatureActions();
4813 if( !ident.fullEmailAddr().isNull() )
4814 mEdtFrom->setText(ident.fullEmailAddr());
4816 if ( KPIM::getFirstEmailAddress( from() ).isEmpty() )
4817 mShowHeaders |= HDR_FROM;
4818 if ( mEdtReplyTo ) mEdtReplyTo->setText(ident.replyToAddr());
4820 if ( mRecipientsEditor ) {
4822 const KPIM::Identity & oldIdentity =
4823 kmkernel->identityManager()->identityForUoidOrDefault( mId );
4824 if ( oldIdentity.bcc() != ident.bcc() ) {
4825 mRecipientsEditor->removeRecipient( oldIdentity.bcc(), Recipient::Bcc );
4826 mRecipientsEditor->addRecipient( ident.bcc(), Recipient::Bcc );
4827 mRecipientsEditor->setFocusBottom();
4833 if( mEdtBcc && !mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4836 if( !mEdtBcc->text().isEmpty() && mEdtBcc->text() != ident.bcc() && !mEdtBcc->edited() ) {
4837 mEdtBcc->setText( ident.bcc() );
4842 if ( mEdtBcc->text() != ident.bcc() && !mEdtBcc->text().isEmpty() ) {
4843 TQString temp_string( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4844 mEdtBcc->setText( temp_string );
4848 mEdtBcc->setText( ident.bcc() );
4855 if( mEdtBcc && mEdtBcc->edited() && !ident.bcc().isEmpty() ) {
4856 if( !mEdtBcc->text().isEmpty() ) {
4857 TQString temp_string ( mEdtBcc->text() + TQString::fromLatin1(
",") + ident.bcc() );
4858 mEdtBcc->setText( temp_string );
4860 mEdtBcc->setText( ident.bcc() );
4866 if( mEdtBcc && !mEdtBcc->edited() && ident.bcc().isEmpty() ) {
4867 mEdtBcc->setText( ident.bcc() );
4870 if ( !ident.bcc().isEmpty() ) {
4871 mShowHeaders |= HDR_BCC;
4874 if ( ident.organization().isEmpty() )
4875 mMsg->removeHeaderField(
"Organization");
4877 mMsg->setHeaderField(
"Organization", ident.organization());
4879 if (!ident.isXFaceEnabled() || ident.xface().isEmpty())
4880 mMsg->removeHeaderField(
"X-Face");
4883 TQString xface = ident.xface();
4884 if (!xface.isEmpty())
4886 int numNL = ( xface.length() - 1 ) / 70;
4887 for (
int i = numNL; i > 0; --i )
4888 xface.insert( i*70,
"\n\t" );
4889 mMsg->setHeaderField(
"X-Face", xface);
4893 if ( !mBtnTransport->isChecked() && !mIgnoreStickyFields ) {
4894 TQString transp = ident.transport();
4895 if ( transp.isEmpty() )
4897 mMsg->removeHeaderField(
"X-KMail-Transport");
4898 transp = GlobalSettings::self()->defaultTransport();
4901 mMsg->setHeaderField(
"X-KMail-Transport", transp);
4902 setTransport( transp );
4905 if ( !mBtnDictionary->isChecked() && !mIgnoreStickyFields ) {
4906 mDictionaryCombo->setCurrentByDictionary( ident.dictionary() );
4909 if ( !mBtnFcc->isChecked() && !mPreventFccOverwrite ) {
4910 setFcc( ident.fcc() );
4913 TQString edtText = mEditor->text();
4915 if ( mOldSigText.isEmpty() ) {
4916 const KPIM::Identity &
id =
4919 identityForUoidOrDefault( mMsg->headerField(
"X-KMail-Identity" ).
4920 stripWhiteSpace().toUInt() );
4921 mOldSigText = GlobalSettings::self()->prependSignature() ?
id.signature().rawText() :
id.signatureText();
4925 if ( !GlobalSettings::prependSignature() ) {
4928 while ( !edtText.isEmpty() && edtText[edtText.length()-1].isSpace() )
4929 edtText.truncate( edtText.length() - 1 );
4931 while ( !mOldSigText.isEmpty() && mOldSigText[mOldSigText.length()-1].isSpace() )
4932 mOldSigText.truncate( mOldSigText.length() - 1 );
4934 if ( edtText.endsWith( mOldSigText ) )
4935 edtText.truncate( edtText.length() - mOldSigText.length() );
4938 mOldSigText = ident.signatureText();
4939 if( ( !mOldSigText.isEmpty() ) &&
4940 ( GlobalSettings::self()->autoTextSignature() ==
"auto" ) ) {
4941 edtText.append( mOldSigText );
4943 mEditor->setText( edtText );
4945 const int pos = edtText.find( mOldSigText );
4946 if ( pos >= 0 && !mOldSigText.isEmpty() ) {
4947 const int oldLength = mOldSigText.length();
4948 mOldSigText =
"\n\n"+ ident.signature().rawText() +
"\n";
4949 edtText = edtText.replace( pos, oldLength, mOldSigText );
4950 mEditor->setText( edtText );
4952 insertSignature( Append );
4958 bool bNewIdentityHasSigningKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4959 bool bNewIdentityHasEncryptionKey = !ident.pgpSigningKey().isEmpty() || !ident.smimeSigningKey().isEmpty();
4960 mAttachMPK->setEnabled( Kleo::CryptoBackendFactory::instance()->openpgp() &&
4961 !ident.pgpEncryptionKey().isEmpty() );
4963 if ( !bNewIdentityHasEncryptionKey && mLastIdentityHasEncryptionKey ) {
4964 mLastEncryptActionState = mEncryptAction->isChecked();
4965 setEncryption(
false );
4967 if ( !bNewIdentityHasSigningKey && mLastIdentityHasSigningKey ) {
4968 mLastSignActionState = mSignAction->isChecked();
4969 setSigning(
false );
4972 if ( bNewIdentityHasEncryptionKey && !mLastIdentityHasEncryptionKey )
4973 setEncryption( mLastEncryptActionState );
4974 if ( bNewIdentityHasSigningKey && !mLastIdentityHasSigningKey )
4975 setSigning( mLastSignActionState );
4977 mLastIdentityHasSigningKey = bNewIdentityHasSigningKey;
4978 mLastIdentityHasEncryptionKey = bNewIdentityHasEncryptionKey;
4980 setModified(
true );
4984 rethinkFields(
false );
4988 void KMComposeWin::slotSpellcheckConfig()
4990 KDialogBase dlg(KDialogBase::Plain, i18n(
"Spellchecker"),
4991 KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Ok,
4992 this, 0,
true,
true );
4994 TQTabDialog qtd (
this,
"tabdialog",
true);
4995 KSpellConfig mKSpellConfig (&qtd);
4996 mKSpellConfig.layout()->setMargin( KDialog::marginHint() );
4998 qtd.addTab (&mKSpellConfig, i18n(
"Spellchecker"));
4999 qtd.setCancelButton ();
5001 twin.setIcons (qtd.winId(), kapp->icon(), kapp->miniIcon());
5002 qtd.setCancelButton(KStdGuiItem::cancel().text());
5003 qtd.setOkButton(KStdGuiItem::ok().text());
5006 mKSpellConfig.writeGlobalSettings();
5010 void KMComposeWin::slotStatusMessage(
const TQString &message)
5012 statusBar()->changeItem( message, 0 );
5015 void KMComposeWin::slotEditToolbars()
5017 saveMainWindowSettings(KMKernel::config(),
"Composer");
5018 KEditToolbar dlg(guiFactory(),
this);
5020 connect( &dlg, TQ_SIGNAL(newToolbarConfig()),
5021 TQ_SLOT(slotUpdateToolbars()) );
5026 void KMComposeWin::slotUpdateToolbars()
5028 createGUI(
"kmcomposerui.rc");
5029 applyMainWindowSettings(KMKernel::config(),
"Composer");
5032 void KMComposeWin::slotEditKeys()
5034 KKeyDialog::configure( actionCollection(),
5039 void KMComposeWin::setReplyFocus(
bool hasMessage )
5041 mEditor->setFocus();
5043 if( mMsg->getCursorPos() ) {
5044 mEditor->setCursorPositionFromStart( (
unsigned int) mMsg->getCursorPos() );
5046 mEditor->setCursorPosition( 1, 0 );
5051 void KMComposeWin::setFocusToSubject()
5053 mEdtSubject->setFocus();
5056 int KMComposeWin::autoSaveInterval()
const
5058 return GlobalSettings::self()->autosaveInterval() * 1000 * 60;
5061 void KMComposeWin::initAutoSave()
5063 kdDebug(5006) << k_funcinfo << endl;
5066 if ( mAutoSaveFilename.isEmpty() ) {
5067 mAutoSaveFilename = KMFolderMaildir::constructValidFileName();
5073 void KMComposeWin::updateAutoSave()
5075 if ( autoSaveInterval() == 0 ) {
5076 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5079 if ( !mAutoSaveTimer ) {
5080 mAutoSaveTimer =
new TQTimer(
this,
"mAutoSaveTimer" );
5081 connect( mAutoSaveTimer, TQ_SIGNAL( timeout() ),
5082 this, TQ_SLOT( autoSaveMessage() ) );
5084 mAutoSaveTimer->start( autoSaveInterval() );
5088 void KMComposeWin::setAutoSaveFilename(
const TQString & filename )
5090 mAutoSaveFilename = filename;
5093 void KMComposeWin::cleanupAutoSave()
5095 delete mAutoSaveTimer; mAutoSaveTimer = 0;
5096 if ( !mAutoSaveFilename.isEmpty() ) {
5097 kdDebug(5006) << k_funcinfo <<
"deleting autosave file "
5098 << mAutoSaveFilename << endl;
5100 mAutoSaveFilename );
5101 mAutoSaveFilename = TQString();
5105 void KMComposeWin::slotCompletionModeChanged( TDEGlobalSettings::Completion mode)
5107 GlobalSettings::self()->setCompletionMode( (
int) mode );
5110 mEdtFrom->setCompletionMode( mode );
5111 mEdtReplyTo->setCompletionMode( mode );
5112 if ( mClassicalRecipients ) {
5113 mEdtTo->setCompletionMode( mode );
5114 mEdtCc->setCompletionMode( mode );
5115 mEdtBcc->setCompletionMode( mode );
5117 mRecipientsEditor->setCompletionMode( mode );
5120 void KMComposeWin::slotConfigChanged()
5125 slotWordWrapToggled( mWordWrapAction->isChecked() );
5132 void KMComposeWin::slotFolderRemoved(
KMFolder* folder)
5135 if ( (mFolder) && (folder->
idString() == mFolder->idString()) )
5137 mFolder = kmkernel->draftsFolder();
5138 kdDebug(5006) <<
"restoring drafts to " << mFolder->idString() << endl;
5140 if (mMsg) mMsg->setParent(0);
5144 void KMComposeWin::editorFocusChanged(
bool gained)
5146 mPasteQuotation->setEnabled(gained);
5149 void KMComposeWin::slotSetAlwaysSend(
bool bAlways )
5151 mAlwaysSend = bAlways;
5154 void KMComposeWin::slotListAction(
const TQString& style )
5157 if ( style == i18n(
"Standard" ) )
5158 mEditor->setParagType( TQStyleSheetItem::DisplayBlock, TQStyleSheetItem::ListDisc );
5159 else if ( style == i18n(
"Bulleted List (Disc)" ) )
5160 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDisc );
5161 else if ( style == i18n(
"Bulleted List (Circle)" ) )
5162 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListCircle );
5163 else if ( style == i18n(
"Bulleted List (Square)" ) )
5164 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListSquare );
5165 else if ( style == i18n(
"Ordered List (Decimal)" ))
5166 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListDecimal );
5167 else if ( style == i18n(
"Ordered List (Alpha lower)" ) )
5168 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListLowerAlpha );
5169 else if ( style == i18n(
"Ordered List (Alpha upper)" ) )
5170 mEditor->setParagType( TQStyleSheetItem::DisplayListItem, TQStyleSheetItem::ListUpperAlpha );
5171 mEditor->viewport()->setFocus();
5174 void KMComposeWin::slotFontAction(
const TQString& font)
5177 mEditor->TQTextEdit::setFamily( font );
5178 mEditor->viewport()->setFocus();
5181 void KMComposeWin::slotSizeAction(
int size )
5184 mEditor->setPointSize( size );
5185 mEditor->viewport()->setFocus();
5188 void KMComposeWin::slotAlignLeft()
5191 mEditor->TQTextEdit::setAlignment( AlignLeft );
5194 void KMComposeWin::slotAlignCenter()
5197 mEditor->TQTextEdit::setAlignment( AlignHCenter );
5200 void KMComposeWin::slotAlignRight()
5203 mEditor->TQTextEdit::setAlignment( AlignRight );
5206 void KMComposeWin::slotTextBold()
5209 mEditor->TQTextEdit::setBold( textBoldAction->isChecked() );
5212 void KMComposeWin::slotTextItalic()
5215 mEditor->TQTextEdit::setItalic( textItalicAction->isChecked() );
5218 void KMComposeWin::slotTextUnder()
5221 mEditor->TQTextEdit::setUnderline( textUnderAction->isChecked() );
5224 void KMComposeWin::slotFormatReset()
5226 mEditor->setColor(mForeColor);
5227 mEditor->setCurrentFont( mSaveFont );
5229 void KMComposeWin::slotTextColor()
5231 TQColor color = mEditor->color();
5233 if ( KColorDialog::getColor( color,
this ) ) {
5235 mEditor->setColor( color );
5239 void KMComposeWin::fontChanged(
const TQFont &f )
5241 TQFont fontTemp = f;
5242 fontTemp.setBold(
true );
5243 fontTemp.setItalic(
true );
5244 TQFontInfo fontInfo( fontTemp );
5246 if ( fontInfo.bold() ) {
5247 textBoldAction->setChecked( f.bold() );
5248 textBoldAction->setEnabled(
true ) ;
5250 textBoldAction->setEnabled(
false );
5253 if ( fontInfo.italic() ) {
5254 textItalicAction->setChecked( f.italic() );
5255 textItalicAction->setEnabled(
true ) ;
5257 textItalicAction->setEnabled(
false );
5260 textUnderAction->setChecked( f.underline() );
5262 fontAction->setFont( f.family() );
5263 fontSizeAction->setFontSize( f.pointSize() );
5266 void KMComposeWin::alignmentChanged(
int a )
5269 alignLeftAction->setChecked( ( a == AlignAuto ) || ( a & AlignLeft ) );
5270 alignCenterAction->setChecked( ( a & AlignHCenter ) );
5271 alignRightAction->setChecked( ( a & AlignRight ) );
5275 class TDEToggleActionResetter {
5276 TDEToggleAction * mAction;
5279 TDEToggleActionResetter( TDEToggleAction * action,
bool on )
5280 : mAction( action ), mOn( on ) {}
5281 ~TDEToggleActionResetter() {
5283 mAction->setChecked( mOn );
5285 void disable() { mAction = 0; }
5289 void KMComposeWin::slotEncryptChiasmusToggled(
bool on ) {
5290 mEncryptWithChiasmus =
false;
5295 TDEToggleActionResetter resetter( mEncryptChiasmusAction,
false );
5297 const Kleo::CryptoBackend::Protocol * chiasmus =
5298 Kleo::CryptoBackendFactory::instance()->protocol(
"Chiasmus" );
5301 const TQString msg = Kleo::CryptoBackendFactory::instance()->knowsAboutProtocol(
"Chiasmus" )
5302 ? i18n(
"Please configure a Crypto Backend to use for "
5303 "Chiasmus encryption first.\n"
5304 "You can do this in the Crypto Backends tab of "
5305 "the configure dialog's Security page." )
5306 : i18n(
"It looks as though libkleopatra was compiled without "
5307 "Chiasmus support. You might want to recompile "
5308 "libkleopatra with --enable-chiasmus.");
5309 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Backend Configured" ) );
5313 STD_NAMESPACE_PREFIX unique_ptr<Kleo::SpecialJob> job( chiasmus->specialJob(
"x-obtain-keys", TQStringVariantMap() ) );
5315 const TQString msg = i18n(
"Chiasmus backend does not offer the "
5316 "\"x-obtain-keys\" function. Please report this bug." );
5317 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5321 if ( job->exec() ) {
5322 job->showErrorDialog(
this, i18n(
"Chiasmus Backend Error" ) );
5326 const TQVariant result = job->property(
"result" );
5327 if ( result.type() != TQVariant::StringList ) {
5328 const TQString msg = i18n(
"Unexpected return value from Chiasmus backend: "
5329 "The \"x-obtain-keys\" function did not return a "
5330 "string list. Please report this bug." );
5331 KMessageBox::error(
this, msg, i18n(
"Chiasmus Backend Error" ) );
5335 const TQStringList keys = result.toStringList();
5336 if ( keys.empty() ) {
5337 const TQString msg = i18n(
"No keys have been found. Please check that a "
5338 "valid key path has been set in the Chiasmus "
5340 KMessageBox::information(
this, msg, i18n(
"No Chiasmus Keys Found" ) );
5344 ChiasmusKeySelector selectorDlg(
this, i18n(
"Chiasmus Encryption Key Selection" ),
5345 keys, GlobalSettings::chiasmusKey(),
5346 GlobalSettings::chiasmusOptions() );
5347 if ( selectorDlg.exec() != TQDialog::Accepted )
5350 GlobalSettings::setChiasmusOptions( selectorDlg.options() );
5351 GlobalSettings::setChiasmusKey( selectorDlg.key() );
5352 assert( !GlobalSettings::chiasmusKey().isEmpty() );
5353 mEncryptWithChiasmus =
true;
5359 kdDebug(5006) << k_funcinfo << endl;
5360 KMMessagePart *part = mEditorMap[ watcher ];
5361 KTempFile *tf = mEditorTempFiles[ watcher ];
5362 mEditorMap.remove( watcher );
5363 mEditorTempFiles.remove( watcher );
5364 if ( !watcher->fileChanged() )
5367 tf->file()->reset();
5368 TQByteArray data = tf->file()->readAll();
5369 part->setBodyEncodedBinary( data );
5373 void KMComposeWin::slotUpdateSignatureAndEncrypionStateIndicators()
5375 const bool showIndicatorsAlways =
false;
5376 mSignatureStateIndicator->setText( mSignAction->isChecked()? i18n(
"Message will be signed") : i18n(
"Message will not be signed") );
5377 mEncryptionStateIndicator->setText( mEncryptAction->isChecked()? i18n(
"Message will be encrypted") : i18n(
"Message will not be encrypted") );
5378 if ( !showIndicatorsAlways ) {
5379 mSignatureStateIndicator->setShown( mSignAction->isChecked() );
5380 mEncryptionStateIndicator->setShown( mEncryptAction->isChecked() );
5384 void KMComposeWin::slotAttachmentDragStarted()
5386 kdDebug(5006) << k_funcinfo << endl;
5388 TQStringList filenames;
5389 for ( TQPtrListIterator<TQListViewItem> it(mAtmItemList); *it; ++it, ++idx ) {
5390 if ( (*it)->isSelected() ) {
5391 KMMessagePart* msgPart = mAtmList.at(idx);
5392 KTempDir * tempDir =
new KTempDir();
5393 tempDir->setAutoDelete(
true );
5394 mTempDirs.insert( tempDir );
5395 const TQString fileName = tempDir->name() +
"/" + msgPart->name();
5396 KPIM::kByteArrayToFile(msgPart->bodyDecodedBinary(),
5398 false,
false,
false);
5400 url.setPath( fileName );
5401 filenames << url.path();
5404 if ( filenames.isEmpty() )
return;
5406 TQUriDrag *drag =
new TQUriDrag( mAtmListView );
5407 drag->setFileNames( filenames );
5411 void KMComposeWin::recipientEditorSizeHintChanged()
5413 TQTimer::singleShot( 1,
this, TQ_SLOT(setMaximumHeaderSize()) );
5416 void KMComposeWin::setMaximumHeaderSize()
5418 mHeadersArea->setMaximumHeight( mHeadersArea->sizeHint().height() );