/* -*- mode: C++; c-file-style: "gnu" -*- This file is part of KMail, the KDE mail client. Copyright (c) 1997 Markus Wuebben This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef __KMComposeWin #define __KMComposeWin // KMail includes #include "composer.h" #include "messagesender.h" // Qt includes #include #include #include #include // KDE includes #include // LIBKDEPIM includes #include // Other includes #include "kleo/enum.h" class QByteArray; class QCheckBox; class QComboBox; class QEvent; class QGridLayout; class QLabel; class QPushButton; class QSplitter; class QTreeWidgetItem; class KLineEdit; class KMComposeWin; class KMComposerEditor; class KMFolderComboBox; class KMFolder; class KMMessage; class KMMessagePart; class KSelectAction; class KFontAction; class KFontSizeAction; class KSelectAction; class KAction; class KJob; class KToggleAction; class KTemporaryFile; class KTempDir; class KToggleAction; class KUrl; class KRecentFilesAction; class MessageComposer; class RecipientsEditor; class KMLineEdit; class KMAtmListViewItem; class SnippetWidget; namespace KPIM { class KMStyleListSelectAction; } namespace Sonnet { class DictionaryComboBox; } namespace KPIMIdentities { class IdentityCombo; class Identity; } namespace MailTransport { class TransportComboBox; } namespace KMail { class AttachmentListView; class EditorWatcher; } namespace KIO { class Job; } namespace GpgME { class Error; } //----------------------------------------------------------------------------- class KMComposeWin : public KMail::Composer { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.kde.kmail.mailcomposer") friend class ::KMComposerEditor; friend class ::MessageComposer; private: // mailserviceimpl, kmkernel, kmcommands, callback, kmmainwidget explicit KMComposeWin( KMMessage *msg=0, uint identity=0 ); ~KMComposeWin(); public: static Composer *create( KMMessage *msg = 0, uint identity = 0 ); QString dbusObjectPath() const; QString smartQuote( const QString & msg ); /** * Start of D-Bus callable stuff. The D-Bus methods need to be public slots, * otherwise they can't be accessed. */ public slots: Q_SCRIPTABLE void send( int how ); Q_SCRIPTABLE void addAttachmentsAndSend( const KUrl::List & urls, const QString & comment, int how ); Q_SCRIPTABLE void addAttachment( const KUrl & url, const QString & comment ); Q_SCRIPTABLE void addAttachment( const QString & name, const QByteArray & cte, const QByteArray & data, const QByteArray & type, const QByteArray & subType, const QByteArray & paramAttr, const QString & paramValue, const QByteArray & contDisp ); /** * End of D-Bus callable stuff */ private: /** * Write settings to app's config file. */ void writeConfig( void ); public: // kmkernel, kmcommands, callback /** * Set the message the composer shall work with. This discards * previous messages without calling applyChanges() on them before. */ void setMsg( KMMessage *newMsg, bool mayAutoSign=true, bool allowDecryption=false, bool isModified=false ); /** * Disables word wrap completely. No wrapping at all will occur, not even * at the right end of the editor. */ void disableWordWrap(); /** * Returns @c true while the message composing is in progress. */ bool isComposing() const { return mComposer != 0; } private: // kmedit /** * Returns message of the composer. To apply the user changes to the * message, call applyChanges() first. */ KMMessage *msg() const { return mMsg; } public: // kmkernel /** * Set the filename which is used for autosaving. */ void setAutoSaveFilename( const QString & filename ); private: /** * Returns true if the message was modified by the user. */ bool isModified() const; /** * Set whether the message should be treated as modified or not. */ void setModified( bool modified ); public: // kmkernel, callback /** * If this flag is set the message of the composer is deleted when * the composer is closed and the message was not sent. Default: false */ inline void setAutoDelete( bool f ) { mAutoDeleteMsg = f; } public: // kmcommand /** * If this folder is set, the original message is inserted back after * canceling */ void setFolder( KMFolder *aFolder ) { mFolder = aFolder; } public: // kmkernel, kmcommand, mailserviceimpl /** * Reimplemented */ virtual void setCharset( const QByteArray &aCharset, bool forceDefault = false ); public: // kmcommand /** * Sets the focus to the edit-widget. */ void setReplyFocus( bool hasMessage = true ); /** * Sets the focus to the subject line edit. For use when creating a * message to a known recipient. */ void setFocusToSubject(); private: /** * determines whether inline signing/encryption is selected */ bool inlineSigningEncryptionSelected(); /** * Enables HTML mode, by showing the HTML toolbar and checking the * "Formatting" action */ void enableHtml(); /** * Disables the HTML mode, by hiding the HTML toolbar and unchecking the * "Formatting" action. Also, removes all rich-text formatting. */ void disableHtml(); /** * Tries to find the given mimetype @p type in the KDE Mimetype registry. * If found, returns its localized description, otherwise the @p type * in lowercase. */ static QString prettyMimeType( const QString &type ); public: // callback /** Disabled signing and encryption completely for this composer window. */ void setSigningAndEncryptionDisabled( bool v ) { mSigningAndEncryptionExplicitlyDisabled = v; } private slots: /** * Actions: */ void slotPrint(); void slotAttachFile(); void slotInsertRecentFile( const KUrl & ); void slotAttachedFile( const KUrl & ); public slots: // kmkernel, callback void slotSendNow(); private slots: void slotSendNowVia( QAction * ); void slotSendLater(); void slotSendLaterVia( QAction * ); void getTransportMenu(); /** * Returns true when saving was successful. */ void slotSaveDraft(); void slotSaveTemplate(); void slotNewComposer(); void slotNewMailReader(); void slotClose(); void slotHelp(); void slotUndo(); void slotRedo(); void slotCut(); void slotCopy(); void slotPaste(); void slotPasteAsAttachment(); void slotAttachPNGImageData( const QByteArray &image ); void slotFormatReset(); void slotMarkAll(); void slotFolderRemoved( KMFolder * ); void slotEditDone( KMail::EditorWatcher* watcher ); void slotLanguageChanged( const QString &language ); public slots: // kmkernel /** Tell the composer to always send the message, even if the user hasn't changed the next. This is useful if a message is autogenerated (e.g., via a D-Bus call), and the user should simply be able to confirm the message and send it. */ void slotSetAlwaysSend( bool bAlwaysSend ); private slots: /** * toggle fixed width font. */ void slotUpdateFont(); /** * Open addressbook editor dialog. */ void slotAddrBook(); /** * Insert a file to the end of the text in the editor. */ void slotInsertFile(); void slotSetCharset(); /** * Check spelling of text. */ void slotSpellcheckConfig(); /** * Change crypto plugin to be used for signing/encrypting messages, * or switch to built-in OpenPGP code. */ void slotSelectCryptoModule( bool init = false ); /** * XML-GUI stuff */ void slotEditToolbars(); void slotUpdateToolbars(); void slotEditKeys(); /** * Read settings from app's config file. */ void readConfig( bool reload = false ); /** * Change window title to given string. */ void slotUpdWinTitle( const QString & ); /** * Switch the icon to lock or unlock respectivly. * Change states of all encrypt check boxes in the attachments listview */ void slotEncryptToggled( bool ); /** * Change states of all sign check boxes in the attachments listview */ void slotSignToggled( bool ); public slots: // kmkernel, callback /** * Switch wordWrap on/off */ void slotWordWrapToggled( bool ); private slots: /** * Append signature to the end of the text in the editor. */ void slotAppendSignature(); /** * Prepend signature at the beginning of the text in the editor. */ void slotPrependSignature(); /** * Insert signature at the cursor position of the text in the editor. */ void slotInsertSignatureAtCursor(); /** * Attach sender's public key. */ void slotInsertMyPublicKey(); /** * Insert arbitrary public key from public keyring in the editor. */ void slotInsertPublicKey(); /** * Enable/disable some actions in the Attach menu */ void slotUpdateAttachActions(); void slotAttachEdit(); void slotAttachEditWith(); /** * Open a popup-menu in the attachments-listbox. */ void slotAttachPopupMenu( QTreeWidgetItem* ); /** * Attachment operations. */ void slotAttachOpen(); void slotAttachView(); void slotAttachRemove(); void slotAttachSave(); void slotAttachProperties(); void slotAttachmentDragStarted(); void slotCleanSpace(); void slotToggleMarkup(); void slotTextModeChanged( KRichTextEdit::Mode ); void htmlToolBarVisibilityChanged( bool visible ); void slotSpellcheckDoneClearStatus(); public slots: // kmkernel void autoSaveMessage(); private slots: void slotView(); /** * Update composer field to reflect new identity */ void slotIdentityChanged( uint ); /** * KIO slots for attachment insertion */ void slotAttachFileData( KIO::Job *, const QByteArray & ); void slotAttachFileResult( KJob * ); void slotCursorPositionChanged(); void slotSpellCheckingStatus( const QString & status ); public: // kmkernel, attachmentlistview bool addAttach( const KUrl &url ); public: // kmcommand /** * Add an attachment to the list. */ void addAttach( KMMessagePart *msgPart ); private: const KPIMIdentities::Identity & identity() const; uint identityUid() const; Kleo::CryptoMessageFormat cryptoMessageFormat() const; bool encryptToSelf() const; signals: void applyChangesDone( bool ); void attachmentAdded( const KUrl &, bool success ); private: /** * Applies the user changes to the message object of the composer * and signs/encrypts the message if activated. Returns false in * case of an error (e.g. if PGP encryption fails). * Disables the controls of the composer window unless @p dontDisable * is true. */ void applyChanges( bool dontSignNorEncrypt, bool dontDisable=false ); /** * Install grid management and header fields. If fields exist that * should not be there they are removed. Those that are needed are * created if necessary. */ void rethinkFields( bool fromslot=false ); /** Connect signals for moving focus by arrow keys. Returns next edit. */ QWidget *connectFocusMoving( QWidget *prev, QWidget *next ); /** * Show or hide header lines */ void rethinkHeaderLine( int aValue, int aMask, int &aRow, QLabel *aLbl, KLineEdit *aEdt, QPushButton *aBtn = 0 ); void rethinkHeaderLine( int value, int mask, int &row, QLabel *lbl, QComboBox *cbx, QCheckBox *chk ); // krazy:exclude=qclasses /** * Initialization methods */ void setupActions(); void setupStatusBar(); void setupEditor(); /** * Header fields. */ QString subject() const; QString to() const; QString cc() const; QString bcc() const; QString from() const; QString replyTo() const; /** * Use the given folder as sent-mail folder if the given folder exists. * Else show an error message and use the default sent-mail folder as * sent-mail folder. */ void setFcc( const QString &idString ); /** * Ask for confirmation if the message was changed before close. */ virtual bool queryClose(); /** * prevent kmail from exiting when last window is deleted (kernel rules) */ virtual bool queryExit(); /** * Open the attachment with the given index. */ void openAttach( int index ); /** * View the attachment with the given index. */ void viewAttach( int index ); /** * Remove an attachment from the list. */ void removeAttach( const QString &url ); void removeAttach( int idx ); /** * Updates an item in the QListView to represnet a given message part */ void msgPartToItem( const KMMessagePart *msgPart, KMAtmListViewItem *lvi, bool loadDefaults = true ); private: /** * Turn encryption on/off. If setByUser is true then a message box is shown * in case encryption isn't possible. */ void setEncryption( bool encrypt, bool setByUser = false ); /** Edit the attachment with the given index. */ void editAttach( int index, bool openWith ); /** * Turn signing on/off. If setByUser is true then a message box is shown * in case signing isn't possible. */ void setSigning( bool sign, bool setByUser = false ); /** Returns true if the user forgot to attach something. */ bool userForgotAttachment(); /** * Retrieve encrypt flag of an attachment * ( == state of it's check box in the attachments list view ) */ bool encryptFlagOfAttachment( int idx ); /** * Retrieve sign flag of an attachment * ( == state of it's check box in the attachments list view ) */ bool signFlagOfAttachment( int idx ); /** * Decrypt an OpenPGP block or strip off the OpenPGP envelope of a text * block with a clear text signature. This is only done if the given * string contains exactly one OpenPGP block. * This function is for example used to restore the unencrypted/unsigned * message text for editting. */ static void decryptOrStripOffCleartextSignature( QByteArray & ); /** * Save the message into the Drafts or Templates folder. */ bool saveDraftOrTemplate( const QString &folderName, KMMessage *msg ); enum SaveIn { None, Drafts, Templates }; /** * Send the message. Returns true if the message was sent successfully. */ void doSend( KMail::MessageSender::SendMethod method=KMail::MessageSender::SendDefault, KMComposeWin::SaveIn saveIn = KMComposeWin::None ); /** * Returns the autosave interval in milliseconds (as needed for QTimer). */ int autoSaveInterval() const; /** * Initialize autosaving (timer and filename). */ void initAutoSave(); /** * Enables/disables autosaving depending on the value of the autosave * interval. */ void updateAutoSave(); /** * Stop autosaving and delete the autosaved message. */ void cleanupAutoSave(); /** * Validates a list of email addresses. * @return true if all addresses are valid. * @return false if one or several addresses are invalid. */ static bool validateAddresses( QWidget *parent, const QString &addresses ); /** * Helper to insert the signature of the current identity arbitrarily * in the editor, connecting slot functions to KMeditor::insertSignature(). * @param placement the position of the signature */ void insertSignatureHelper( KPIM::KMeditor::Placement = KPIM::KMeditor::End ); private slots: /** * Compress an attachemnt with the given index */ void compressAttach( KMAtmListViewItem *attachmentItem ); void uncompressAttach( KMAtmListViewItem *attachmentItem ); void recipientEditorSizeHintChanged(); void setMaximumHeaderSize(); private: QWidget *mMainWidget; MailTransport::TransportComboBox *mTransport; Sonnet::DictionaryComboBox *mDictionaryCombo; KPIMIdentities::IdentityCombo *mIdentity; KMFolderComboBox *mFcc; KMLineEdit *mEdtFrom, *mEdtReplyTo; KMLineEdit *mEdtSubject; QLabel *mLblIdentity, *mLblTransport, *mLblFcc; QLabel *mLblFrom, *mLblReplyTo; QLabel *mLblSubject; QLabel *mDictionaryLabel; QCheckBox *mBtnIdentity, *mBtnTransport, *mBtnFcc; bool mDone; bool mAtmModified; KMComposerEditor *mEditor; QGridLayout *mGrid; KMMessage *mMsg; QVector mComposedMessages; KMail::AttachmentListView *mAtmListView; QList mAtmItemList; QList mAtmList; QMenu *mAttachMenu; QAction *mOpenId, *mViewId, *mRemoveId, *mSaveAsId, *mPropertiesId, *mEditAction, *mEditWithAction; QAction *mCleanSpace; bool mAutoDeleteMsg; bool mSigningAndEncryptionExplicitlyDisabled; bool mLastSignActionState, mLastEncryptActionState; bool mLastIdentityHasSigningKey, mLastIdentityHasEncryptionKey; KMFolder *mFolder; long mShowHeaders; bool mConfirmSend; bool mDisableBreaking; // Move int mNumHeaders; QFont mBodyFont, mFixedFont; QList mAtmTempList; QPalette mPalette; uint mId; KAction *mAttachPK, *mAttachMPK, *mAttachRemoveAction, *mAttachSaveAction, *mAttachPropertiesAction, *mPasteQuotation, *mAddQuoteChars, *mRemQuoteChars; KRecentFilesAction *mRecentAction; KToggleAction *mSignAction, *mEncryptAction, *mRequestMDNAction; KToggleAction *mUrgentAction, *mAllFieldsAction, *mFromAction; KToggleAction *mReplyToAction; KToggleAction *mSubjectAction; KToggleAction *mIdentityAction, *mTransportAction, *mFccAction; KToggleAction *mWordWrapAction, *mFixedFontAction, *mAutoSpellCheckingAction; KToggleAction *mDictionaryAction, *mSnippetAction; KToggleAction *markupAction; KAction *actionFormatReset; KSelectAction *mEncodingAction; KSelectAction *mCryptoModuleAction; QByteArray mCharset; QByteArray mDefCharset; QStringList mCharsets; bool mAutoCharset; bool mAlwaysSend; QStringList mFolderNames; QList > mFolderList; QMap mAttachJobs; KUrl::List mAttachFilesPending; int mAttachFilesSend; private: // helper method for slotInsert(My)PublicKey() void startPublicKeyExport(); bool canSignEncryptAttachments() const { return cryptoMessageFormat() != Kleo::InlineOpenPGPFormat; } QString addQuotesToText( const QString &inputText ) const; // helper method for rethinkFields int calcColumnWidth( int which, long allShowing, int width ) const; private slots: void slotCompletionModeChanged( KGlobalSettings::Completion ); void slotConfigChanged(); void slotComposerDone( bool ); void slotContinueDoSend( bool ); void slotContinuePrint( bool ); void slotContinueAutoSave(); void slotEncryptChiasmusToggled( bool ); /** * Helper method (you could call is a bottom-half :) for * startPublicKeyExport() */ void slotPublicKeyExportResult( const GpgME::Error &err, const QByteArray &keydata ); /** * toggle automatic spellchecking */ void slotAutoSpellCheckingToggled( bool ); /** * Updates the visibility and text of the signature and encryption state indicators. */ void slotUpdateSignatureAndEncrypionStateIndicators(); private: QFont mSaveFont; QSplitter *mHeadersToEditorSplitter; QWidget* mHeadersArea; QSplitter *mSplitter; QSplitter *mSnippetSplitter; struct atmLoadData { KUrl url; QByteArray data; bool insert; QByteArray encoding; }; QMap mMapAtmLoadData; // These are for passing on methods over the applyChanges calls KMail::MessageSender::SendMethod mSendMethod; KMComposeWin::SaveIn mSaveIn; KToggleAction *mEncryptChiasmusAction; bool mEncryptWithChiasmus; // The temporary object that constructs the message out of the window MessageComposer *mComposer; // Temp var for slotPrint: bool mMessageWasModified; // Temp var for slotInsert(My)PublicKey(): QString mFingerprint; RecipientsEditor *mRecipientsEditor; int mLabelWidth; QTimer *mAutoSaveTimer; QString mAutoSaveFilename; int mLastAutoSaveErrno; // holds the errno of the last try to autosave QMenu *mActNowMenu; QMenu *mActLaterMenu; QString mdbusObjectPath; static int s_composerNumber; QMap mEditorMap; QMap mEditorTempFiles; SnippetWidget *mSnippetWidget; QList mTempDirs; QLabel *mSignatureStateIndicator; QLabel *mEncryptionStateIndicator; bool mPreventFccOverwrite; }; #endif