17 #include <KPIMUtils/Email>
18 #include <KPIMIdentities/Identity>
19 #include <KPIMIdentities/IdentityManager>
20 #include <QVBoxLayout>
22 #include <QtDBus/QtDBus>
23 #include <qgroupbox.h>
26 #include <akonadi/contact/emailaddressselectiondialog.h>
27 #include <kcharsets.h>
28 #include <kmessagebox.h>
29 #include <kactioncollection.h>
30 #include <kstandardaction.h>
31 #include <kshortcutsdialog.h>
32 #include <kedittoolbar.h>
35 #include <kcombobox.h>
36 #include <ktemporaryfile.h>
37 #include <libkpgp/kpgpblock.h>
38 #include <kcompletionbox.h>
39 #include <kxmlguifactory.h>
40 #include <kstatusbar.h>
42 #include <kselectaction.h>
43 #include <ktoggleaction.h>
54 using namespace KNode::Utilities;
55 using namespace KNode::Composer;
59 : KABC::AddressLineEdit( parent, useCompletion ),
60 composerView( parent )
65 : KABC::AddressLineEdit( parent, useCompletion ), composerView(0)
72 QMenu *popup = KLineEdit::createStandardContextMenu();
73 popup->addSeparator();
74 popup->addAction( i18n(
"Edit Recent Addresses..." ),
75 this, SLOT(editRecentAddresses()) );
76 popup->exec( e->globalPos() );
80 void KNLineEdit::editRecentAddresses()
83 dlg.setAddresses( RecentAddresses::self(
knGlobals.config() )->addresses() );
85 RecentAddresses::self(
knGlobals.config() )->clear();
86 QStringList addrList = dlg.addresses();
87 QStringList::Iterator it;
88 for ( it = addrList.begin(); it != addrList.end(); ++it )
89 RecentAddresses::self(
knGlobals.config() )->add( *it );
97 KABC::AddressLineEdit::loadAddresses();
99 QStringList recent = RecentAddresses::self(
knGlobals.config())->addresses();
100 QStringList::Iterator it = recent.begin();
101 for ( ; it != recent.end(); ++it )
108 if ((e->key() == Qt::Key_Enter || e->key() == Qt::Key_Return) &&
109 !completionBox()->isVisible())
114 if (e->key() == Qt::Key_Up)
119 if (e->key() == Qt::Key_Down)
125 KABC::AddressLineEdit::keyPressEvent(e);
141 setSelection ( pos, length );
159 setSelection ( pos, old.length() );
161 setSelection ( pos, corr.length() );
169 n_eeds8Bit(true), v_alidated(false), a_uthorDislikesMailCopies(dislikesCopies), e_xternalEdited(false), e_xternalEditor(0),
170 e_ditorTempfile(0), a_ttChanged(false),
171 mFirstEdit( firstEdit )
173 setObjectName(
"composerWindow" );
175 if(
knGlobals.componentData().isValid() )
176 setComponentData(
knGlobals.componentData() );
179 setAcceptDrops(
true);
183 setCentralWidget(
v_iew);
188 KStatusBar *sb=statusBar();
189 sb->insertItem( QString(), 1, 1 );
190 sb->setItemAlignment( 1, Qt::AlignLeft | Qt::AlignVCenter );
191 sb->insertItem( QString(), 2, 1 );
192 sb->setItemAlignment( 2, Qt::AlignLeft | Qt::AlignVCenter );
193 sb->insertItem( QString(), 3, 1 );
194 sb->setItemAlignment(3, Qt::AlignCenter | Qt::AlignVCenter );
195 sb->insertItem( QString(), 4, 1 );
196 sb->setItemAlignment(4, Qt::AlignCenter | Qt::AlignVCenter );
197 sb->insertItem( QString(), 5, 1 );
198 sb->setItemAlignment( 5, Qt::AlignCenter | Qt::AlignVCenter );
202 QDBusConnection::sessionBus().registerObject(
"/Composer",
this, QDBusConnection::ExportScriptableSlots );
206 KAction *action = actionCollection()->addAction(
"send_now");
207 action->setIcon(KIcon(
"mail-send"));
208 action->setText(i18n(
"&Send Now"));
209 connect(action, SIGNAL(triggered(
bool)), SLOT(
slotSendNow()));
210 action->setShortcut(QKeySequence(Qt::CTRL + Qt::Key_Return));
212 action = actionCollection()->addAction(
"send_later");
213 action->setIcon(KIcon(
"mail-queue"));
214 action->setText(i18n(
"Send &Later"));
215 connect(action, SIGNAL(triggered(
bool)), SLOT(
slotSendLater()));
217 action = actionCollection()->addAction(
"save_as_draft");
218 action->setIcon(KIcon(
"document-save"));
219 action->setText(i18n(
"Save as &Draft"));
222 action = actionCollection()->addAction(
"art_delete");
223 action->setIcon(KIcon(
"edit-delete"));
224 action->setText(i18n(
"D&elete"));
225 connect(action, SIGNAL(triggered(
bool)), SLOT(
slotArtDelete()));
227 KStandardAction::close(
this, SLOT(close()),actionCollection());
230 KStandardAction::undo(
this, SLOT(
slotUndo()), actionCollection());
231 KStandardAction::redo(
this, SLOT(
slotRedo()), actionCollection());
233 KStandardAction::cut(
this, SLOT(
slotCut()), actionCollection());
236 KStandardAction::copy(
this, SLOT(
slotCopy()), actionCollection());
238 KStandardAction::pasteText(
this, SLOT(
slotPaste()), actionCollection());
240 action = actionCollection()->addAction(
"paste_quoted");
241 action->setText(i18n(
"Paste as &Quotation"));
242 connect(action, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotPasteAsQuotation()));
244 KStandardAction::selectAll(
this, SLOT(
slotSelectAll()), actionCollection());
246 KStandardAction::find(
v_iew->
editor(), SLOT(slotFind()), actionCollection());
247 KStandardAction::findNext(
v_iew->
editor(), SLOT(slotFindNext()), actionCollection());
249 KStandardAction::replace(
v_iew->
editor(), SLOT(slotReplace()), actionCollection());
252 action = actionCollection()->addAction(
"append_signature");
253 action->setText(i18n(
"Append &Signature"));
254 connect( action, SIGNAL(triggered(
bool)),
v_iew, SLOT(appendSignature()) );
256 action = actionCollection()->addAction(
"insert_file");
257 action->setText(i18n(
"&Insert File..."));
260 action = actionCollection()->addAction(
"insert_file_boxed");
261 action->setText(i18n(
"Insert File (in a &box)..."));
264 action = actionCollection()->addAction(
"attach_file");
265 action->setIcon(KIcon(
"mail-attachment"));
266 action->setText(i18n(
"Attach &File..."));
269 a_ctPGPsign = actionCollection()->add<KToggleAction>(
"sign_article");
270 a_ctPGPsign->setText(i18n(
"Sign Article with &PGP"));
283 a_ctDoPost = actionCollection()->add<KToggleAction>(
"send_news");
285 a_ctDoPost->setText(i18n(
"Send &News Article"));
288 a_ctDoMail = actionCollection()->add<KToggleAction>(
"send_mail");
294 a_ctSetCharset = actionCollection()->add<KSelectAction>(
"set_charset");
307 a_ctWordWrap = actionCollection()->add<KToggleAction>(
"toggle_wordwrap");
311 a_ctAutoSpellChecking =
new KToggleAction( KIcon(
"tools-check-spelling" ), i18n(
"&Automatic Spellchecking"),
this );
322 action = actionCollection()->addAction(
"tools_quote");
323 action->setText(i18n(
"Add &Quote Characters"));
324 connect(action, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotAddQuotes()));
326 action = actionCollection()->addAction(
"tools_unquote");
327 action->setText(i18n(
"&Remove Quote Characters"));
328 connect(action, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotRemoveQuotes()));
330 action = actionCollection()->addAction(
"tools_box");
331 action->setText(i18n(
"Add &Box"));
332 connect(action, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotAddBox()));
334 action = actionCollection()->addAction(
"tools_unbox");
335 action->setText(i18n(
"Re&move Box"));
336 connect(action, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotRemoveBox()));
338 QAction *undoRewrap = actionCollection()->addAction(
"tools_undoRewrap");
339 undoRewrap->setText(i18n(
"Get &Original Text (not re-wrapped)"));
340 connect(undoRewrap, SIGNAL(triggered(
bool)), SLOT(
slotUndoRewrap()));
341 undoRewrap->setEnabled(!
u_nwraped.isNull());
343 QAction *rot13 = actionCollection()->addAction(
"tools_rot13");
344 rot13->setIcon(KIcon(
"document-encrypt"));
345 rot13->setText(i18n(
"S&cramble (Rot 13)"));
346 connect(rot13, SIGNAL(triggered(
bool)),
v_iew->
editor(), SLOT(slotRot13()));
347 rot13->setEnabled(
false);
348 connect(
v_iew->
editor(), SIGNAL(copyAvailable(
bool)), rot13, SLOT(setEnabled(
bool)));
351 a_ctExternalEditor->setIcon(KIcon(
"system-run"));
352 a_ctExternalEditor->setText(i18n(
"Start &External Editor"));
358 createStandardStatusBarAction();
359 setStandardToolBarMenuEnabled(
true);
361 KStandardAction::keyBindings(
this, SLOT(
slotConfKeys()), actionCollection());
363 KStandardAction::configureToolbars(
this, SLOT(
slotConfToolbar()), actionCollection());
365 KStandardAction::preferences(
knGlobals.top, SLOT(slotSettings()), actionCollection());
368 createGUI(
"kncomposerui.rc");
387 applyMainWindowSettings(
knGlobals.config()->group(
"composerWindow_options"));
390 if (
knGlobals.settings()->useExternalEditor() )
404 saveMainWindowSettings(
knGlobals.config()->group(
"composerWindow_options"));
421 if (fw->inherits(
"KTextEdit"))
423 else if (fw->inherits(
"QLineEdit"))
424 ((QLineEdit*)fw)->undo();
432 if (fw->inherits(
"KTextEdit"))
434 else if (fw->inherits(
"QLineEdit"))
435 ((QLineEdit*)fw)->redo();
443 if (fw->inherits(
"KTextEdit"))
445 else if (fw->inherits(
"QLineEdit"))
446 ((QLineEdit*)fw)->cut();
447 else kDebug(5003) <<
"wrong focus widget";
455 if (fw->inherits(
"KTextEdit"))
457 else if (fw->inherits(
"QLineEdit"))
458 ((QLineEdit*)fw)->copy();
459 else kDebug(5003) <<
"wrong focus widget";
469 if (fw->inherits(
"KTextEdit"))
471 else if (fw->inherits(
"QLineEdit"))
472 ((QLineEdit*)fw)->paste();
473 else kDebug(5003) <<
"wrong focus widget";
481 if (fw->inherits(
"QLineEdit"))
482 ((QLineEdit*)fw)->selectAll();
483 else if (fw->inherits(
"KTextEdit"))
495 Kpgp::Module *pgp = Kpgp::Module::getKpgp();
513 QString s =
v_iew->
editor()->document ()->begin().text ();
515 if (!s.contains(i18n(
"<posted & mailed>"))) {
516 QTextCursor cursor(
v_iew->
editor()->document ()->begin());
517 cursor.setPosition(0);
518 cursor.insertText(i18n(
"<posted & mailed>\n\n"));
522 if (s == i18n(
"<posted & mailed>")) {
539 if ( KPIMUtils::isValidAddress(
v_iew->
from() ) != KPIMUtils::AddressOk ) {
540 KMessageBox::sorry(
this, i18n(
"Your email address does not appears to be valid. Please modify it." ) );
545 KMessageBox::sorry(
this, i18n(
"Please enter a subject."));
554 if ( groupCount == 0 ) {
555 KMessageBox::sorry(
this, i18n(
"Please enter a newsgroup."));
560 KMessageBox::sorry(
this, i18n(
"You are crossposting to more than 12 newsgroups.\nPlease remove all newsgroups in which your article is off-topic."));
565 if ( KMessageBox::warningYesNo(
this, i18n(
"You are crossposting to more than five newsgroups.\nPlease reconsider whether this is really useful\nand remove groups in which your article is off-topic.\nDo you want to re-edit the article or send it anyway?"),
566 QString(), KGuiItem(i18n(
"&Send")), KGuiItem(i18nc(
"edit article",
"&Edit")) ) != KMessageBox::Yes )
570 if ( fupCount == 0 && groupCount > 2 ) {
571 if ( KMessageBox::warningYesNo(
this,
572 i18n(
"You are crossposting to more than two newsgroups.\n"
573 "Please use the \"Followup-To\" header to direct the replies "
574 "to your article into one group.\n"
575 "Do you want to re-edit the article or send it anyway?"),
576 QString(), KGuiItem(i18n(
"&Send")), KGuiItem(i18nc(
"edit article",
"&Edit")),
"missingFollowUpTo" )
577 != KMessageBox::Yes )
582 KMessageBox::sorry(
this, i18n(
"You are directing replies to more than 12 newsgroups.\nPlease remove some newsgroups from the \"Followup-To\" header."));
587 if ( KMessageBox::warningYesNo(
this, i18n(
"You are directing replies to more than five newsgroups.\nPlease reconsider whether this is really useful.\nDo you want to re-edit the article or send it anyway?"),
588 QString(), KGuiItem(i18n(
"&Send")),KGuiItem(i18nc(
"edit article",
"&Edit")) ) != KMessageBox::Yes )
594 KMessageBox::sorry(
this, i18n(
"Please enter the email address."));
603 bool firstLine =
true;
605 bool longLine =
false;
606 bool hasAttributionLine =
false;
612 for (QStringList::Iterator it = text.begin(); it != text.end(); ++it) {
618 for (++it; it != text.end(); ++it) {
624 if((*it).length()>80) {
631 if(!(*it).isEmpty()) {
636 if (firstLine) hasAttributionLine =
true;
639 if((*it).length()>80) {
646 if (
n_eeds8Bit && ( mCharset.toLower()==
"us-ascii" )) {
647 KMessageBox::sorry(
this, i18n(
"Your message contains characters which are not included\nin the \"us-ascii\" character set; please choose\na suitable character set from the \"Options\" menu."));
652 KMessageBox::sorry(
this, i18n(
"You cannot post an empty message."));
656 if ((textLines>1)&&(notQuoted==1)) {
657 if (hasAttributionLine)
658 if ( KMessageBox::warningYesNo(
this, i18n(
"Your article seems to consist entirely of quoted text;\ndo you want to re-edit the article or send it anyway?"),
659 QString(), KGuiItem(i18n(
"&Send")), KGuiItem(i18nc(
"edit article",
"&Edit")) ) != KMessageBox::Yes )
663 KMessageBox::sorry(
this, i18n(
"You cannot post an article consisting\n"
664 "entirely of quoted text."));
670 if ( KMessageBox::warningYesNo(
this,
671 i18n(
"Your article contains lines longer than 80 characters.\n"
672 "Do you want to re-edit the article or send it anyway?"),
673 QString(), KGuiItem(i18n(
"&Send")),
674 KGuiItem(i18nc(
"edit article",
"&Edit")) ) != KMessageBox::Yes )
678 if ( KMessageBox::warningYesNo(
this, i18n(
"Your signature is more than 8 lines long.\nYou should shorten it to match the widely accepted limit of 4 lines.\nDo you want to re-edit the article or send it anyway?"),
679 QString(), KGuiItem(i18n(
"&Send")), KGuiItem(i18nc(
"edit article",
"&Edit")) ) != KMessageBox::Yes )
683 KMessageBox::information(
this, i18n(
"Your signature exceeds the widely-accepted limit of 4 lines:\nplease consider shortening your signature;\notherwise, you will probably annoy your readers."),
684 QString(),
"longSignatureWarning" );
692 KMime::Headers::Newsgroups *grps =
a_rticle->newsgroups();
693 if ( !grps->isEmpty() ) {
695 if ( grp && !grp->identity().isNull() ) {
696 signingKey = grp->identity().pgpSigningKey();
697 }
else if ( !acc->identity().isNull() ) {
698 signingKey = acc->identity().pgpSigningKey();
704 if (signingKey.isEmpty()) {
705 if ( KMessageBox::warningContinueCancel(
this,
706 i18n(
"You have not configured your preferred "
708 "please specify it in the global "
709 "identity configuration,\n"
710 "in the account properties or in the "
711 "group properties.\n"
712 "The article will be sent unsigned." ),
713 QString(), KGuiItem(i18n(
"Send Unsigned" )),
714 KStandardGuiItem::cancel(),
"sendUnsignedDialog" )
715 == KMessageBox::Cancel )
727 KMime::Content *
text=0;
733 if ( !identity.isNull() ) {
734 KMime::Headers::Generic *xKnodeIdentity =
new KMime::Headers::Generic(
"X-KNode-Identity",
736 QByteArray::number( identity.uoid() ) );
737 a_rticle->setHeader( xKnodeIdentity );
741 if ( KPIMUtils::isValidAddress(
v_iew->
from() ) != KPIMUtils::AddressOk ) {
749 if ( KPIMUtils::isValidAddress( identity.replyToAddr() ) == KPIMUtils::AddressOk ) {
750 a_rticle->replyTo()->fromUnicodeString( identity.replyToAddr(), mCharset.toLatin1() );
752 a_rticle->removeHeader(
"Reply-To" );
756 if ( !identity.property(
"Mail-Copies-To" ).toString().trimmed().isEmpty() ) {
757 a_rticle->mailCopiesTo()->fromUnicodeString( identity.property(
"Mail-Copies-To" ).toString(), mCharset.toLatin1() );
759 a_rticle->removeHeader(
"Mail-Copies-To" );
763 if ( !identity.organization().trimmed().isEmpty() ) {
764 a_rticle->organization()->fromUnicodeString( identity.organization(), mCharset.toLatin1() );
766 a_rticle->removeHeader(
"Organization" );
770 a_rticle->date()->setDateTime( KDateTime::currentLocalDateTime() );
777 a_rticle->newsgroups()->fromUnicodeString(
v_iew->
groups().join( QString(
',' ) ), KMime::Headers::Latin1 );
781 a_rticle->removeHeader(
"Newsgroups" );
796 a_rticle->followUpTo()->fromUnicodeString(
v_iew->
followupTo().join( QString(
',' ) ), KMime::Headers::Latin1 );
798 a_rticle->removeHeader(
"Followup-To");
806 if(a->hasChanged()) {
808 a->updateContentInfo();
816 if ( (*it)->isAttached() )
822 text=
new KMime::Content();
823 KMime::Headers::ContentType *type=text->contentType();
824 KMime::Headers::ContentTransferEncoding *enc=text->contentTransferEncoding();
825 type->setMimeType(
"text/plain");
826 enc->setDecoded(
true);
834 text->contentType()->setCharset( mCharset.toLatin1() );
835 if (
knGlobals.settings()->allow8BitBody() )
836 text->contentTransferEncoding()->setEncoding(KMime::Headers::CE8Bit);
838 text->contentTransferEncoding()->setEncoding(KMime::Headers::CEquPr);
841 text->contentType()->setCharset( mCharset.toLatin1() );
842 text->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
845 text->contentType()->setCharset( mCharset.toLatin1() );
846 if ( mCharset.toLower()==
"us-ascii" ) {
847 text->contentTransferEncoding()->setEncoding(KMime::Headers::CE7Bit);
849 text->contentTransferEncoding()->setEncoding(
knGlobals.settings()->allow8BitBody()
850 ? KMime::Headers::CE8Bit : KMime::Headers::CEquPr );
854 QString tmp =
v_iew->
editor()->toWrappedPlainText();
858 QByteArray signingKey = identity.pgpSigningKey();
859 if (!signingKey.isEmpty()) {
860 QString tmpText = tmp;
863 QTextCodec *codec=KGlobal::charsets()->codecForName( mCharset, ok);
865 codec=KGlobal::locale()->codecForEncoding();
867 block.setText( codec->fromUnicode(tmpText) );
868 kDebug(5003) <<
"signing article from" <<
article()->from()->addresses();
869 if( block.clearsign( signingKey, codec->name() ) == Kpgp::Ok ) {
870 QByteArray result = block.text();
871 tmp = codec->toUnicode(result.data(), result.length() );
878 text->fromUnicodeString(tmp);
891 mCharset = Locale::toMimeCharset( charset );
905 switch ( KMessageBox::warningYesNoCancel(
this, i18n(
"Do you want to save this article in the draft folder?"),
906 QString(), KStandardGuiItem::save(), KStandardGuiItem::discard() ) ) {
907 case KMessageBox::Yes :
910 case KMessageBox::No :
930 KPIMIdentities::Identity identity = idManager->defaultIdentity();
931 KMime::Headers::Base* xKnodeIdentity =
a_rticle->headerByType(
"X-KNode-Identity" );
932 if ( xKnodeIdentity && !xKnodeIdentity->isEmpty() ) {
933 uint uoid = xKnodeIdentity->asUnicodeString().toUInt();
935 identity = idManager->identityForUoidOrDefault( uoid );
954 KMime::Headers::Newsgroups *hNewsgroup =
a_rticle->newsgroups(
false );
955 if ( hNewsgroup && !hNewsgroup->isEmpty() ) {
960 KMime::Headers::To *hTo =
a_rticle->to(
false );
961 if ( hTo && !hTo->isEmpty() ) {
966 KMime::Headers::FollowUpTo *fup2=
a_rticle->followUpTo(
false);
967 if( fup2 && !fup2->isEmpty() ) {
971 KMime::Content *textContent=
a_rticle->textContent();
976 s = textContent->decodedText();
984 setCharset( textContent->contentType()->charset() );
989 QString charsetDesc = KGlobal::charsets()->descriptionForEncoding( mCharset );
1002 if(
a_rticle->contentType()->isMultipart()) {
1004 const KMime::Content::List attList =
a_rticle->attachments();
1005 foreach ( KMime::Content *c, attList ) {
1018 QTextCodec *codec=KGlobal::charsets()->codecForName( mCharset, ok);
1019 QTextStream ts(file);
1023 temp = QString::fromLatin1(
",----[ %1 ]\n").arg(boxTitle);
1025 if (box && (
v_iew->
editor()->wordWrapMode()!=QTextOption::NoWrap)) {
1026 int wrapAt =
v_iew->
editor()->lineWrapColumnOrWidth();
1029 while(!ts.atEnd()) {
1037 while(!ts.atEnd()) {
1040 temp+=ts.readLine();
1046 temp += QString::fromLatin1(
"`----");
1059 QFile *file = helper.
getFile(i18n(
"Insert File"));
1066 if (url.isLocalFile())
1067 boxName = url.toLocalFile();
1069 boxName = url.prettyUrl();
1132 if (helper->
getFile(i18n(
"Attach File"))) {
1151 if ( attachment->isAttached() ) {
1193 if ( KMessageBox::warningContinueCancel(
this, i18n(
"The poster does not want a mail copy of your reply (Mail-Copies-To: nobody);\nplease respect their request."),
1194 QString(), KGuiItem(i18n(
"&Send Copy")) ) != KMessageBox::Continue ) {
1202 if (
knGlobals.settings()->useExternalMailer() ) {
1204 if (!s.contains(i18n(
"<posted & mailed>")))
1205 v_iew->
editor()->insertAt(i18n(
"<posted & mailed>\n\n"),0,0);
1207 QStringList textLines =
v_iew->
editor()->processedText();
1208 for (QStringList::Iterator it = textLines.begin(); it != textLines.end(); ++it) {
1240 QString charset = KGlobal::charsets()->encodingForName( s );
1250 QString charset = KGlobal::charsets()->encodingForName(
a_ctSetCharset->items()[ newCS ] );
1272 if (KMessageBox::warningContinueCancel(
this, i18n(
"This will replace all text you have written.")) == KMessageBox::Continue) {
1283 QString editorCommand =
knGlobals.settings()->externalEditor();
1285 if(editorCommand.isEmpty())
1286 KMessageBox::sorry(
this, i18n(
"No editor configured.\nPlease do this in the settings dialog."));
1299 QTextCodec *codec=KGlobal::charsets()->codecForName( mCharset, ok );
1301 QString tmp =
v_iew->
editor()->toWrappedPlainText();
1303 QByteArray local = codec->fromUnicode(tmp);
1317 QStringList command = editorCommand.split(
' ', QString::SkipEmptyParts);
1318 bool filenameAdded=
false;
1319 for ( QStringList::Iterator it = command.begin(); it != command.end(); ++it ) {
1320 if ((*it).contains(
"%f")) {
1324 (*e_xternalEditor) << (*it);
1332 KMessageBox::error(
this, i18n(
"Unable to start external editor.\nPlease check your configuration in the settings dialog."));
1349 case news: typeDesc = i18n(
"News Article");
1351 case mail: typeDesc = i18n(
"Email");
1353 default : typeDesc = i18n(
"News Article & Email");
1355 QString overwriteDesc;
1357 overwriteDesc = i18n(
" OVR ");
1359 overwriteDesc = i18n(
" INS ");
1361 statusBar()->changeItem(i18n(
" Type: %1 ", typeDesc), 1);
1362 statusBar()->changeItem(i18n(
" Charset: %1 ", mCharset ), 2);
1363 statusBar()->changeItem(overwriteDesc, 3);
1364 statusBar()->changeItem(i18n(
" Column: %1 ",
v_iew->
editor()->columnNumber () + 1), 4);
1365 statusBar()->changeItem(i18n(
" Line: %1 ",
v_iew->
editor()->linePosition() + 1), 5);
1371 statusBar()->changeItem(i18n(
" Column: %1 ",
v_iew->
editor()->columnNumber () + 1), 4);
1372 statusBar()->changeItem(i18n(
" Line: %1 ",
v_iew->
editor()->linePosition() + 1), 5);
1378 KShortcutsDialog::configure(actionCollection(), KShortcutsEditor::LetterShortcutsAllowed,
this,
true);
1384 saveMainWindowSettings(
knGlobals.config()->group(
"composerWindow_options") );
1385 KEditToolBar dlg(guiFactory(),
this);
1392 createGUI(
"kncomposerui.rc");
1394 applyMainWindowSettings(
knGlobals.config()->group(
"composerWindow_options"));
1404 subject.replace(
'\n',
' ' );
1405 subject.replace(
'\r',
' ' );
1409 if( !subject.isEmpty() )
1410 setCaption( subject );
1412 setCaption( i18n(
"No Subject") );
1418 Akonadi::EmailAddressSelectionDialog dlg(
this );
1419 dlg.view()->view()->setSelectionMode( QAbstractItemView::MultiSelection );
1424 QStringList addresses;
1425 foreach (
const Akonadi::EmailAddressSelection &selection, dlg.selectedAddresses() )
1426 addresses << selection.quotedEmail();
1429 if ( !to.isEmpty() )
1431 to += addresses.join(
", " );
1443 nntp=
knGlobals.accountManager()->account(
id);
1446 nntp=
knGlobals.accountManager()->first();
1449 KMessageBox::error(
this, i18n(
"You have no valid news accounts configured."));
1472 if(exitStatus == QProcess::NormalExit) {
1499 QMenu *menu =
static_cast<QMenu*
>( factory()->container(
"attachment_popup",
this ) );
1501 menu->popup( point );
1508 event->setDropAction( Qt::CopyAction );
1517 foreach (
const KUrl &url, urls ) {
1520 if (helper->
setURL(url)) {
1538 KDialog( parent ), a_ttachment(a),
1539 n_onTextAsText(false)
1542 setCaption( i18n(
"Attachment Properties") );
1543 setButtons( Help | Ok | Cancel );
1545 setMainWidget(page);
1546 QVBoxLayout *topL=
new QVBoxLayout(page);
1550 QGridLayout *fileL=
new QGridLayout(fileGB);
1551 fileL->setSpacing(5);
1552 fileL->setMargin(15);
1554 fileL->addItem(
new QSpacerItem( 0, fontMetrics().lineSpacing()-9), 0, 0 );
1555 fileL->addWidget(
new QLabel(i18n(
"Name:"), fileGB) ,1,0);
1556 fileL->addWidget(
new QLabel(QString(
"<b>%1</b>").arg(a->name()), fileGB), 1,1, Qt::AlignLeft);
1557 fileL->addWidget(
new QLabel(i18n(
"Size:"), fileGB), 2,0);
1558 fileL->addWidget(
new QLabel(a->contentSize(), fileGB), 2,1, Qt::AlignLeft);
1560 fileL->setColumnStretch(1,1);
1561 topL->addWidget(fileGB);
1565 QGridLayout *mimeL=
new QGridLayout(mimeGB);
1566 mimeL->setSpacing(5);
1567 mimeL->setMargin(15);
1569 mimeL->addItem(
new QSpacerItem( 0, fontMetrics().lineSpacing()-9), 0, 0 );
1573 QLabel *label =
new QLabel(i18n(
"&Mime-Type:"), mimeGB);
1575 mimeL->addWidget(label, 1,0);
1580 label=
new QLabel(i18n(
"&Description:"), mimeGB);
1582 mimeL->addWidget(label, 2,0);
1590 if(a->isFixedBase64()) {
1597 label=
new QLabel(i18n(
"&Encoding:"), mimeGB);
1599 mimeL->addWidget(label, 3,0);
1601 mimeL->setColumnStretch(1,1);
1602 topL->addWidget(mimeGB);
1605 connect(
m_imeType, SIGNAL(textChanged(QString)),
1609 setFixedHeight(sizeHint().height());
1611 setHelp(
"anc-knode-editor-advanced");
1623 a_ttachment->setDescription(d_escription->text());
1624 a_ttachment->setMimeType(m_imeType->text());
1625 a_ttachment->setCte(e_ncoding->currentIndex());
1631 if ( m_imeType->text().indexOf(
'/') == -1 ) {
1632 KMessageBox::sorry(
this, i18n(
"You have set an invalid mime-type.\nPlease change it."));
1635 else if ( n_onTextAsText && m_imeType->text().indexOf(
"text/", 0, Qt::CaseInsensitive ) != -1 &&
1636 KMessageBox::warningContinueCancel(
this,
1637 i18n(
"You have changed the mime-type of this non-textual attachment\nto text. This might cause an error while loading or encoding the file.\nProceed?")
1638 ) == KMessageBox::Cancel)
return;
1649 enableButtonOk( !text.isEmpty() );
1650 if(text.left(5)!=
"text/") {
1651 n_onTextAsText=a_ttachment->isFixedBase64();
1652 e_ncoding->setCurrentIndex(3);
1653 e_ncoding->setEnabled(
false);
1656 e_ncoding->setCurrentIndex(a_ttachment->cte());
1657 e_ncoding->setEnabled(
true);
1664 #include "kncomposer.moc"
const QString emailRecipient() const
Returns the email recipient of this message (as type by the user in the To: field).
void focusNextPrevEdit(const QWidget *aCur, bool aNext)
Gives the focus to the next/previous edition widget (group, to, subject, body, etc.)
composerResult result() const
QAction * a_ctExternalEditor
void spellCheckerCorrected(const QString &old, const QString &corr, unsigned int pos)
bool isAttachmentViewVisible() const
Indicates whether the attachment view is visible or not.
virtual void contextMenuEvent(QContextMenuEvent *e)
void setConfig(bool onlyFonts)
const QString from()
Returns the sender full name and email address to use in a From: header of a message.
void setIdentity(uint uoid)
Changes the selected identity and update related edit lines.
boost::shared_ptr< KNLocalArticle > Ptr
Shared pointer to a KNLocalArticle. To be used instead of raw KNLocalArticle*.
~AttachmentPropertiesDlg()
Destructor.
void appendSignature()
Appends the signature to the editor.
static void saveWindowSize(const QString &name, const QSize &s)
Q_SCRIPTABLE void initData(const QString &text)
KSelectAction * a_ctSetCharset
void apply()
Apply the change to the attachment passed to the constructor.
virtual QByteArray text(quint32 serialNumber) const =0
KToggleAction * a_ctPGPsign
boost::shared_ptr< KNGroupListData > Ptr
Shared pointer to a KNGroupListData.
void setEmailRecipient(const QString &to)
Sets the email recipient list as a string.
KToggleAction * a_ctAutoSpellChecking
void slotEditorFinished(int, QProcess::ExitStatus)
static void restoreWindowSize(const QString &name, QWidget *d, const QSize &defaultSize)
void slotAttachmentRemoved(KNAttachment::Ptr attachment, bool last)
Called by the View when an attachment was removed.
KToggleAction * a_ctWordWrap
static KNGlobals * self()
Return the KNGlobals instance.
void slotToggleWordWrap()
void slotGroupsBtnClicked()
KNAttachment represents a file that is or will be attached to an article.
void setMessageMode(KNComposer::MessageMode mode)
Set the message mode to.
boost::shared_ptr< KNNntpAccount > Ptr
Shared pointer to a KNNntpAccount.
File open helper (includes file open dialog and network download).
KProcess * e_xternalEditor
Line edit for addresses used in the composer.
void slotSetCharset(const QString &s)
void hideExternalNotification()
void setCharset(const QString &charset)
Sets the character set to used to encode this message.
void keyPressEvent(QKeyEvent *e)
static void displayTempFileError(QWidget *w=0)
use this for error on temporary files
void setFrom(const QString &from)
Set the name and email address of the sender of the message.
void slotMimeTypeTextChanged(const QString &text)
static MailList fromMimeData(const QMimeData *md)
KPIMIdentities::IdentityManager * identityManager()
Returns the identity manager.
KNLineEditSpell(View *parent, bool useCompletion=true)
Constructor.
const QStringList followupTo() const
Returns the followup-to list of groups (name are trimmed).
void slotNewToolbarConfig()
const QString subject() const
Returns the subject text.
virtual const KPIMIdentities::Identity & identity() const
Returns the global identity (or the default one when none is set yet).
QFile * getFile(const QString &dialogTitle)
opens a file dialog and returns a file open for reading
virtual void loadAddresses()
AttachmentPropertiesDlg(KNAttachment::Ptr a, QWidget *parent=0)
Create a dialog to edit attribute of a message attachment.
Message is to be sent by e-mail and to a newsgroup.
void slotExternalEditor()
QAction * a_ctAttachmentProperties
void highLightWord(unsigned int length, unsigned int pos)
void showAttachmentView()
KNode::Settings * settings()
Returns the KConfigXT generated settings object.
virtual void writeConfig()
Reimplemented to hide writeConfig() from SettingsContainerInterface and delegate call to SettingsBase...
static bool canDecode(const QMimeData *md)
void setComposingFont(const QFont &font)
Changes the font used in edition widget within this ComposerView.
KNLineEdit(View *parent, bool useCompletion=true)
Constructor.
KNLocalArticle::Ptr article() const
void setFollowupTo(const QString &followupTo)
Sets the followup-to list as a string (must be a coma separated list of groups).
Message is to be sent by e-mail.
void setMessageMode(MessageMode mode)
static QString rewrapStringList(const QStringList &text, int wrapAt, QChar quoteChar, bool stopAtSig, bool alwaysSpace)
used for rewarping a text when replying to a message or inserting a file into a box ...
void showExternalNotification()
const QStringList groups() const
Returns the followup-to list of groups (name are trimmed).
virtual void dropEvent(QDropEvent *event)
Reimplemented to add the dropped files as attachments.
const QList< KNAttachment::Ptr > attachments() const
Returns the list of attachments of this message.
QAction * a_ctSetCharsetKeyb
void slotAttachmentPopup(const QPoint &point)
Open a popup menu to do action on an attachment.
QList< KNAttachment::Ptr > mDeletedAttachments
void slotAutoSpellCheckingToggled()
void addAttachment(KNAttachment::Ptr attachment)
Adds an attachment to the message.
KNComposerEditor * editor() const
Returns the main text editor.
void hideAttachmentView()
void slotAttachmentChanged()
Called by the View to notify that an attachment was modified.
void composerDone(KNComposer *)
void spellCheckerMisspelling(const QString &text, const QStringList &, unsigned int pos)
void slotUpdateCursorPos()
bool applyChanges()
Applies changes from the editor into the article being edited.
void closeEvent(QCloseEvent *e)
void slotSubjectChanged(const QString &t)
void setAutoSpellChecking(bool v)
Set Automatic Spellchecking.
void slotSetCharsetKeyboard()
KToggleAction * a_ctDoMail
static int selectDialog(QWidget *parent, const QString &caption, const QStringList &options, int initialValue)
list selection dialog, used instead of a popup menu when a select action is called via the keyboard...
KTemporaryFile * e_ditorTempfile
void slotInsertFileBoxed()
void slotUpdateStatusBar()
QFile * setURL(const KUrl &url)
tries to access the file specified by the url and returns a file open for reading ...
virtual void dragEnterEvent(QDragEnterEvent *event)
Reimplemented to accept list of URI as drag content.
void setSubject(const QString &subject)
Sets the subject.
bool a_uthorDislikesMailCopies
#define knGlobals
Keep compatibility with the old way.
void insertFile(QFile *file, bool clear=false, bool box=false, const QString &boxTitle=QString())
Inserts at cursor position if clear is false, replaces content otherwise puts the file content into a...
boost::shared_ptr< KNAttachment > Ptr
Shared pointer to a KNAttachment.
Message is to be sent to a newsgroup.
void spellCheckDone(const QString &s)
void completeSetup(bool firstEdit, KNComposer::MessageMode mode)
Completes the setup of this view.
uint selectedIdentity() const
Return the UOID of the selected identity.
QAction * a_ctRemoveAttachment
KToggleAction * a_ctDoPost
QString selectedGroups() const
KNLocalArticle::Ptr a_rticle
void setGroups(const QString &groups)
Sets the group list as a string (must be coma separated).
Group selection dialog (used in the composer).
boost::shared_ptr< KNGroup > Ptr
Shared pointer to a KNGroup.
void slotUpdateCheckSpellChecking(bool _b)
KNComposer(KNLocalArticle::Ptr a, const QString &text=QString(), const QString &unwraped=QString(), bool firstEdit=false, bool dislikesCopies=false, bool createCopy=false, bool allowMail=true)
Create a composer for a message (e-mail or newsgroup post).