kmail

kmmessage.h

00001 // -*- mode: C++; c-file-style: "gnu" -*-
00002 /* kmmessage.h: Mime Message Class
00003  *
00004  */
00005 #ifndef kmmessage_h
00006 #define kmmessage_h
00007 
00010 // for large file support
00011 #include <config.h>
00012 #include <sys/types.h>
00013 
00014 #include <mimelib/string.h>
00015 #include "kmmsgbase.h"
00016 #include "isubject.h"
00017 
00018 #include <kmime_mdn.h>
00019 
00020 #include<libemailfunctions/email.h>
00021 
00022 template <typename T>
00023 class TQValueList;
00024 
00025 class TQStringList;
00026 class TQString;
00027 class TQTextCodec;
00028 class TQStrList;
00029 
00030 class KMFolder;
00031 class KMFolderIndex;
00032 class DwMessage;
00033 class KMMessagePart;
00034 class KMMsgInfo;
00035 class KMHeaders;
00036 class KMForwardDigestCommand;
00037 
00038 namespace KMime {
00039   class CharFreq;
00040   namespace Types {
00041     class AddrSpec;
00042     class Address;
00043     typedef TQValueList<Address> AddressList;
00044     typedef TQValueList<AddrSpec> AddrSpecList;
00045   }
00046 }
00047 
00048 namespace KMail {
00049   class HeaderStrategy;
00050 }
00051 
00052 class DwEntity;
00053 class DwBodyPart;
00054 class DwMediaType;
00055 class DwHeaders;
00056 
00057 class partNode;
00058 
00059 namespace KMail {
00060   enum ReplyStrategy { ReplySmart = 0,
00061                        ReplyAuthor,
00062                        ReplyList,
00063                        ReplyAll,
00064                        ReplyNone };
00065 }
00066 
00068 class KMMessage: public KMMsgBase, public KMail::ISubject
00069 {
00070   friend class ::KMForwardDigestCommand; // needed for MIME Digest forward
00071 
00072 public:
00073   // promote some of KMMsgBase's methods to public:
00074   using KMMsgBase::parent;
00075   using KMMsgBase::setParent;
00076   using KMMsgBase::enableUndo; // KMFolder
00077   using KMMsgBase::setEnableUndo; // dto.
00078   using KMMsgBase::isRead; // dto.
00079   using KMMsgBase::isUnread; // dto.
00080   using KMMsgBase::isNew; // dto.
00081   using KMMsgBase::isOld;
00082   using KMMsgBase::isWatched;
00083   using KMMsgBase::isIgnored;
00084   using KMMsgBase::setEncryptionStateChar; // KMAcct*
00085   using KMMsgBase::setSignatureStateChar; // dto.
00086 
00088   KMMessage(KMFolder* parent=0);
00089 
00093   KMMessage(DwMessage*);
00094 
00096   KMMessage(KMMsgInfo& msgInfo);
00097 
00099   KMMessage( const KMMessage& other );
00100 
00101 #if 0 // currently unused
00102 
00103   const KMMessage& operator=( const KMMessage& other ) {
00104     if( &other == this )
00105       return *this;
00106     assign( other );
00107     return *this;
00108   }
00109 #endif
00110 
00112   virtual ~KMMessage();
00113 
00115   KMMsgBase & toMsgBase() { return *this; }
00116   const KMMsgBase & toMsgBase() const { return *this; }
00117 
00119   bool isMessage() const;
00120 
00124   bool isUrgent() const;
00125 
00132   void setUnencryptedMsg( KMMessage* unencrypted );
00133 
00135   bool hasUnencryptedMsg() const { return 0 != mUnencryptedMsg; }
00136 
00138   KMMessage* unencryptedMsg() const { return mUnencryptedMsg; }
00139 
00145   KMMessage* takeUnencryptedMsg()
00146   {
00147     KMMessage* ret = mUnencryptedMsg;
00148     mUnencryptedMsg = 0;
00149     return ret;
00150   }
00151 
00153   void del() { setStatus(KMMsgStatusDeleted); }
00154 
00156   void undel() { setStatus(KMMsgStatusOld); }
00157 
00159   void touch() { setStatus(KMMsgStatusOld); }
00160 
00164   KMMessage* createReply( KMail::ReplyStrategy replyStrategy = KMail::ReplySmart,
00165                           TQString selection=TQString(), bool noQuote = false,
00166                           bool allowDecryption = true,
00167                           const TQString &tmpl = TQString(),
00168                           const TQString &originatingAccount = TQString() );
00169 
00177   KMMessage* createRedirect( const TQString &toStr );
00178 
00180   TQCString createForwardBody();
00181 
00185   KMMessage* createForward( const TQString &tmpl = TQString() );
00186 
00190   KMMessage* createDeliveryReceipt() const;
00191 
00205   KMMessage* createMDN( KMime::MDN::ActionMode a,
00206           KMime::MDN::DispositionType d,
00207           bool allowGUI=false,
00208           TQValueList<KMime::MDN::DispositionModifier> m=TQValueList<KMime::MDN::DispositionModifier>() );
00209 
00211   void sanitizeHeaders( const TQStringList& whiteList = TQStringList() );
00212 
00214   void fromDwString(const DwString& str, bool setStatus=false);
00215   void fromString(const TQCString& str, bool setStatus=false);
00216   void fromByteArray(const TQByteArray & ba, bool setStatus=false);
00217 
00222   const DwString& asDwString() const;
00223   const DwMessage *asDwMessage();
00224 
00232   TQCString asString() const;
00233 
00238   TQByteArray asSendableString() const;
00239 
00244   TQCString headerAsSendableString() const;
00245 
00249   void removePrivateHeaderFields();
00250 
00252   DwMediaType& dwContentType();
00253 
00255   TQString headerAsString() const;
00256 
00261   void parseTextStringFromDwPart( partNode * root,
00262                                           TQCString& parsedString,
00263                                           const TQTextCodec*& codec,
00264                                           bool& isHTML ) const;
00265 
00269   void initHeader(uint identity=0);
00270 
00273   void initFromMessage(const KMMessage *msg, bool idHeaders = true);
00274 
00280   uint identityUoid() const;
00281 
00284   void applyIdentity( uint id );
00285 
00288   void cleanupHeader();
00289 
00295   void setAutomaticFields(bool isMultipart=false);
00296 
00298   TQString dateStr() const;
00301   TQCString dateShortStr() const;
00302   TQString dateIsoStr() const;
00303   time_t date() const;
00304   void setDate(const TQCString& str);
00305   void setDate(time_t aUnixTime);
00306 
00308   void setDateToday();
00309 
00311   TQString to() const;
00312   void setTo(const TQString& aStr);
00313   TQString toStrip() const;
00314 
00316   TQString replyTo() const;
00317   void setReplyTo( const TQString &aStr );
00318   void setReplyTo(KMMessage*);
00319 
00321   TQString cc() const;
00322   void setCc( const TQString &aStr );
00323   TQString ccStrip() const;
00324 
00326   TQString bcc() const;
00327   void setBcc( const TQString &aStr );
00328 
00330   TQString fcc() const;
00331   void setFcc( const TQString &aStr );
00332 
00334   TQString drafts() const { return mDrafts; }
00335   void setDrafts( const TQString &aStr );
00336 
00338   TQString templates() const { return mTemplates; }
00339   void setTemplates( const TQString &aStr );
00340 
00342   TQString from() const;
00343   void setFrom(const TQString& aStr);
00344   TQString fromStrip() const;
00345 
00348   TQString sender() const;
00349 
00353   TQString who() const;
00354 
00356   TQString subject() const;
00357   void setSubject(const TQString& aStr);
00358 
00360   void initStrippedSubjectMD5() {};
00361 
00363   TQString xmark() const;
00364   void setXMark(const TQString& aStr);
00365 
00367   TQString replyToId() const;
00368   void setReplyToId(const TQString& aStr);
00369   TQString replyToIdMD5() const;
00370 
00385   TQString replyToAuxIdMD5() const;
00386 
00391   TQString strippedSubjectMD5() const;
00392 
00403   static KPIM::EmailParseResult isValidEmailAddressList( const TQString& aStr,
00404                                                          TQString& brokenAddress );
00405 
00410   TQString subjectMD5() const;
00411 
00413   bool subjectIsPrefixed() const;
00414 
00416   TQString msgId() const;
00417   void setMsgId(const TQString& aStr);
00418   TQString msgIdMD5() const;
00419 
00421   TQString references() const;
00422   void setReferences(const TQCString& aStr);
00423 
00425   TQCString id() const;
00426 
00431   void setMsgSerNum(unsigned long newMsgSerNum = 0);
00432 
00437   TQString headerField(const TQCString& name) const;
00438 
00439   enum HeaderFieldType { Unstructured, Structured, Address };
00440 
00445   void setHeaderField( const TQCString& name, const TQString& value,
00446                        HeaderFieldType type = Unstructured,
00447                        bool prepend = false );
00448 
00450   TQStringList headerFields( const TQCString& name ) const;
00451 
00456   TQCString rawHeaderField( const TQCString & name ) const;
00457 
00461   TQValueList<TQCString> rawHeaderFields( const TQCString & field ) const;
00462 
00464   static KMime::Types::AddressList splitAddrField( const TQCString & str );
00465 
00469   KMime::Types::AddressList headerAddrField(const TQCString& name) const;
00470   KMime::Types::AddrSpecList extractAddrSpecs( const TQCString & headerNames ) const;
00471 
00473   void removeHeaderField(const TQCString& name);
00474 
00476   void removeHeaderFields(const TQCString& name);
00477 
00481   TQCString typeStr() const;
00482   int type() const;
00483   void setTypeStr(const TQCString& aStr);
00484   void setType(int aType);
00486   TQCString subtypeStr() const;
00487   int subtype() const;
00488   void setSubtypeStr(const TQCString& aStr);
00489   void setSubtype(int aSubtype);
00491   static void setDwMediaTypeParam( DwMediaType &mType,
00492                                    const TQCString& attr,
00493                                    const TQCString& val );
00495   void setContentTypeParam(const TQCString& attr, const TQCString& val);
00496 
00500   DwHeaders& headers() const;
00501 
00506   void setNeedsAssembly();
00507 
00512   void assembleIfNeeded();
00513 
00522   TQCString contentTransferEncodingStr() const;
00523   int contentTransferEncoding( DwEntity *entity = 0 ) const;
00524   void setContentTransferEncodingStr( const TQCString& cteString, DwEntity *entity = 0 );
00525   void setContentTransferEncoding( int cte, DwEntity *entity = 0 );
00526 
00531   TQCString cteStr() const { return contentTransferEncodingStr(); }
00532   int cte( DwEntity *entity = 0 ) const { return contentTransferEncoding( entity ); }
00533   void setCteStr( const TQCString& aStr, DwEntity *entity = 0 ) {
00534     setContentTransferEncodingStr( aStr, entity );
00535   }
00536   void setCte( int aCte, DwEntity *entity = 0 ) {
00537     setContentTransferEncoding( aCte, entity );
00538   }
00539 
00547   void setBodyFromUnicode( const TQString & str, DwEntity *entity = 0 );
00548 
00551   TQString bodyToUnicode(const TQTextCodec* codec=0) const;
00552 
00554   TQCString body() const;
00555 
00557   void setBody(const TQCString& aStr);
00558   void setBody(const DwString& aStr);
00559   void setBody(const char* aStr); // avoid ambiguous calls
00560 
00562   void setMultiPartBody( const TQCString & aStr );
00563 
00573   void setBodyEncoded( const TQCString& aStr, DwEntity *entity = 0 );
00574   void setBodyEncodedBinary( const TQByteArray& aStr, DwEntity *entity = 0 );
00575 
00579   static TQValueList<int> determineAllowedCtes( const KMime::CharFreq& cf,
00580                                                bool allow8Bit,
00581                                                bool willBeSigned );
00582 
00596   void setBodyAndGuessCte( const TQByteArray& aBuf, TQValueList<int>& allowedCte,
00597                            bool allow8Bit = false,
00598                            bool willBeSigned = false,
00599                            DwEntity *entity = 0 );
00600 
00601   void setBodyAndGuessCte( const TQCString& aBuf,
00602                            TQValueList<int>& allowedCte,
00603                            bool allow8Bit = false,
00604                            bool willBeSigned = false,
00605                            DwEntity *entity = 0 );
00606 
00610   TQCString bodyDecoded() const;
00611   TQByteArray bodyDecodedBinary() const;
00612 
00615   int numBodyParts() const;
00616 
00619   DwBodyPart * findDwBodyPart( int type, int subtype ) const;
00620 
00623   DwBodyPart * findDwBodyPart( const TQCString& type, const TQCString&  subtype ) const;
00624 
00627   DwBodyPart* findDwBodyPart( DwBodyPart* part, const TQString & partSpecifier );
00628 
00631   DwBodyPart * dwBodyPart( int aIdx ) const;
00632 
00635   int partNumber( DwBodyPart * aDwBodyPart ) const;
00636 
00639   DwBodyPart * getFirstDwBodyPart() const;
00640   DwMessage * getTopLevelPart() const { return mMsg; }
00641 
00645   static void bodyPart(DwBodyPart* aDwBodyPart, KMMessagePart* aPart,
00646           bool withBody = true );
00647 
00651   void bodyPart(int aIdx, KMMessagePart* aPart) const;
00652 
00654   DwBodyPart* createDWBodyPart(const KMMessagePart* aPart);
00655 
00657   void addDwBodyPart(DwBodyPart * aDwPart);
00658 
00660   void addBodyPart(const KMMessagePart* aPart);
00661 
00663   void deleteBodyParts();
00664 
00669   bool deleteBodyPart( int partIndex );
00670 
00673   void setStatusFields();
00674 
00679   static TQString generateMessageId( const TQString& addr );
00680 
00686   static TQCString html2source( const TQCString & src );
00687 
00690   static TQString encodeMailtoUrl( const TQString& str );
00691 
00694   static TQString decodeMailtoUrl( const TQString& url );
00695 
00702   static TQCString stripEmailAddr(const TQCString& emailAddr);
00703 
00706   static TQString stripEmailAddr(const TQString& emailAddr);
00707 
00713   static TQString quoteHtmlChars( const TQString& str,
00714                                  bool removeLineBreaks = false );
00715 
00720   static TQString emailAddrAsAnchor(const TQString& emailAddr,
00721           bool stripped=true, const TQString& cssStyle = TQString(), bool link = true);
00722 
00726   static TQStringList stripAddressFromAddressList( const TQString& address,
00727                                                   const TQStringList& addresses );
00728 
00732   static TQStringList stripMyAddressesFromAddressList( const TQStringList& list );
00733 
00736   static bool addressIsInAddressList( const TQString& address,
00737                                       const TQStringList& addresses );
00738 
00742   static TQString expandAliases( const TQString& recipients );
00743 
00747   static TQString guessEmailAddressFromLoginName( const TQString& userName );
00748 
00755   static TQString smartQuote( const TQString &msg, int maxLineLength );
00756 
00758   static TQCString defaultCharset();
00759 
00761   static const TQStringList &preferredCharsets();
00762 
00764   TQString replaceHeadersInString( const TQString & s ) const;
00765 
00767   TQCString charset() const;
00768 
00777   void setCharset( const TQCString& charset, DwEntity *entity = 0 );
00778 
00780   const TQTextCodec * codec() const;
00781 
00783   void setOverrideCodec( const TQTextCodec* codec ) { mOverrideCodec = codec; }
00784 
00786   void setDecodeHTML(bool aDecodeHTML)
00787   { mDecodeHTML = aDecodeHTML; }
00788 
00791   static void readConfig();
00792 
00796   TQCString getRefStr() const;
00797 
00799   off_t folderOffset() const { return mFolderOffset; }
00800   void setFolderOffset(off_t offs) { if(mFolderOffset != offs) { mFolderOffset=offs; setDirty(true); } }
00801 
00803   TQString fileName() const { return mFileName; }
00804   void setFileName(const TQString& file) { if(mFileName != file) { mFileName=file; setDirty(true); } }
00805 
00807   TQString originatingAccountName() const { return mOriginatingAccountName; }
00808   void setOriginatingAccountName(const TQString& account) { if(mOriginatingAccountName != account) { mOriginatingAccountName=account; setDirty(true); } }
00809 
00813   size_t msgSize() const { return mMsgSize; }
00814   void setMsgSize(size_t sz) { if(mMsgSize != sz) { mMsgSize = sz; setDirty(true); } }
00815 
00818   size_t msgLength() const
00819     { return (mMsgLength) ? mMsgLength : mMsgSize; }
00820   void setMsgLength(size_t sz) { mMsgLength = sz; }
00821 
00823   size_t msgSizeServer() const;
00824   void setMsgSizeServer(size_t sz);
00825 
00827   ulong UID() const;
00828   void setUID(ulong uid);
00829 
00831   KMMsgStatus status() const { return mStatus; }
00833   void setStatus(const KMMsgStatus status, int idx = -1);
00834   void setStatus(const char* s1, const char* s2=0) { KMMsgBase::setStatus(s1, s2); }
00835 
00837   void setEncryptionState(const KMMsgEncryptionState, int idx = -1);
00838 
00840   void setSignatureState(const KMMsgSignatureState, int idx = -1);
00841 
00842   void setMDNSentState( KMMsgMDNSentState status, int idx=-1 );
00843 
00845   KMMsgEncryptionState encryptionState() const { return mEncryptionState; }
00846 
00848   KMMsgSignatureState signatureState() const { return mSignatureState; }
00849 
00850   KMMsgMDNSentState mdnSentState() const { return mMDNSentState; }
00851 
00853   void link(const KMMessage *aMsg, KMMsgStatus aStatus);
00856   void getLink(int n, ulong *retMsgSerNum, KMMsgStatus *reStatus) const;
00857 
00859   TQString formatString(const TQString&) const;
00860 
00862   void updateBodyPart(const TQString partSpecifier, const TQByteArray & data);
00863 
00865   DwBodyPart* lastUpdatedPart() { return mLastUpdated; }
00866 
00868   bool isComplete() const { return mComplete; }
00870   void setComplete( bool v ) { mComplete = v; }
00871 
00873   bool readyToShow() const { return mReadyToShow; }
00875   void setReadyToShow( bool v ) { mReadyToShow = v; }
00876 
00877   void updateAttachmentState( DwBodyPart *part = 0 );
00878   void updateInvitationState();
00879 
00881   bool transferInProgress() const;
00883   void setTransferInProgress(bool value, bool force = false);
00884 
00889   TQCString mboxMessageSeparator();
00890 
00906   TQString asQuotedString( const TQString & headerStr,
00907           const TQString & indentStr,
00908           const TQString & selection=TQString(),
00909           bool aStripSignature=true,
00910           bool allowDecryption=true) const;
00911 
00914   TQString asPlainText( bool stripSignature, bool allowDecryption ) const;
00915 
00922   TQString asPlainTextFromObjectTree( partNode *root, bool stripSignature,
00923                                      bool allowDecryption ) const;
00924 
00926   int getCursorPos() { return mCursorPos; };
00928   void setCursorPos(int pos) { mCursorPos = pos; };
00929 
00931   KMMsgInfo* msgInfo() { return mMsgInfo; }
00933   void setMsgInfo( KMMsgInfo* msgInfo ) { mMsgInfo = msgInfo; }
00934 
00935   /* This is set in kmreaderwin if a message is being parsed to avoid
00936      other parts of kmail (e.g. kmheaders) destroying the message.
00937      Parsing can take longer and can be async (in case of gpg mails) */
00938   bool isBeingParsed() const { return mIsParsed; }
00939   void setIsBeingParsed( bool t ) { mIsParsed = t; }
00940 
00942   void deleteWhenUnused();
00943 
00944   DwBodyPart* findPart( int index );
00945 
00946 private:
00947 
00949   void init( DwMessage* aMsg = 0 );
00951   void assign( const KMMessage& other );
00952 
00953   DwBodyPart* findPartInternal( DwEntity* root, int index, int &accu );
00954 
00955   TQString mDrafts;
00956   TQString mTemplates;
00957   mutable DwMessage* mMsg;
00958   mutable bool mNeedsAssembly :1;
00959   bool mDecodeHTML :1;
00960   bool mReadyToShow :1;
00961   bool mComplete :1;
00962   bool mIsParsed : 1;
00963   static const KMail::HeaderStrategy * sHeaderStrategy;
00964   static TQString sForwardStr;
00965   const TQTextCodec * mOverrideCodec;
00966 
00967   TQString mFileName;
00968   TQString mOriginatingAccountName;
00969   off_t mFolderOffset;
00970   size_t mMsgSize, mMsgLength;
00971   time_t mDate;
00972   KMMsgEncryptionState mEncryptionState;
00973   KMMsgSignatureState mSignatureState;
00974   KMMsgMDNSentState mMDNSentState;
00975   KMMessage* mUnencryptedMsg;
00976   DwBodyPart* mLastUpdated;
00977   int mCursorPos;
00978   KMMsgInfo* mMsgInfo; // used to remember the KMMsgInfo object this KMMessage replaced in the KMMsgList
00979   static TQValueList<KMMessage*> sPendingDeletes;
00980 };
00981 
00982 
00983 #endif /*kmmessage_h*/