/******************************************************************************* ** ** Filename : headeritem.h ** Created on : 28 November, 2004 ** Copyright : (c) 2004 Till Adam ** Email : adam@kde.org ** *******************************************************************************/ /******************************************************************************* ** ** 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. ** ** In addition, as a special exception, the copyright holders give ** permission to link the code of this program with any edition of ** the TQt library by Trolltech AS, Norway (or with modified versions ** of TQt that use the same license as TQt), and distribute linked ** combinations including the two. You must obey the GNU General ** Public License in all respects for all of the code used other than ** TQt. If you modify this file, you may extend this exception to ** your version of the file, but you are not obligated to do so. If ** you do not wish to do so, delete this exception statement from ** your version. ** *******************************************************************************/ #ifndef HEADERITEM_H #define HEADERITEM_H #include #include // include for the base class class KMMsgBase; class KPaintInfo; class KMFolder; class KMHeaders; namespace KMail { class HeaderItem; // forward declaration /** * @short Represents an item in the set of mails to be displayed but only as far * as sorting, threading and reading/writing of the current sort order to * a disk cache is concerned. * * Each such item is paired with a KMail::HeaderItem, which holds the graphical * representation of each item (mail). This is what the threading trees are * built of. */ class SortCacheItem { public: SortCacheItem() : mItem(0), mParent(0), mId(-1), mSortOffset(-1), mUnsortedCount(0), mUnsortedSize(0), mUnsortedChildren(0), mImperfectlyThreaded (true), mSubjThreadingList(0) { } SortCacheItem(int i, TQString k, int o=-1) : mItem(0), mParent(0), mId(i), mSortOffset(o), mKey(k), mUnsortedCount(0), mUnsortedSize(0), mUnsortedChildren(0), mImperfectlyThreaded (true), mSubjThreadingList(0) { } ~SortCacheItem() { if(mUnsortedChildren) free(mUnsortedChildren); } /** The parent node of the item in the threading hierarchy. 0 if the item * is at top level, which is the default. Can only be set by parents. */ SortCacheItem *parent() const { return mParent; } /** * Returs whether the item is so far imperfectly threaded. * If an item is imperfectly threaded (by References or subject, not by * In-Reply-To) it will be reevalutated when a new mail comes in. It could be * the perfect parent. */ bool isImperfectlyThreaded() const { return mImperfectlyThreaded; } /** Set whether the item is currently imperfectly threaded (by References * or Subject, not by In-Reply-To). */ void setImperfectlyThreaded (bool val) { mImperfectlyThreaded = val; } /** Returns whether the item has other items below it. */ bool hasChildren() const { return mSortedChildren.count() || mUnsortedCount; } /** The sorted children are an array of sortcache items we know are below the * current one and are already properly sorted (as read from the cache ) */ const TQPtrList *sortedChildren() const { return &mSortedChildren; } /** The unsorted children are an array of sortcache items we know are below the * current one, but are yet to be threaded and sorted properly. */ SortCacheItem **unsortedChildren(int &count) const { count = mUnsortedCount; return mUnsortedChildren; } /** Add an item to this itme's list of already sorted children. */ void addSortedChild(SortCacheItem *i) { i->mParent = this; mSortedChildren.append(i); } /** Add an item to this itme's list of unsorted children. */ void addUnsortedChild(SortCacheItem *i) { i->mParent = this; if(!mUnsortedChildren) mUnsortedChildren = (SortCacheItem **)malloc((mUnsortedSize = 25) * sizeof(SortCacheItem *)); else if(mUnsortedCount >= mUnsortedSize) mUnsortedChildren = (SortCacheItem **)realloc(mUnsortedChildren, (mUnsortedSize *= 2) * sizeof(SortCacheItem *)); mUnsortedChildren[mUnsortedCount++] = i; } /** Clear the sorted and unsorted children datastructures. */ void clearChildren() { mSortedChildren.clear(); free( mUnsortedChildren ); mUnsortedChildren = 0; mUnsortedCount = mUnsortedSize = 0; } /** The corresponding KMail::HeaderItem */ HeaderItem *item() const { return mItem; } /** Set the corresponding KMail::HeaderItem */ void setItem(HeaderItem *i) { Q_ASSERT(!mItem); mItem = i; } /** sort key as used by the listview */ const TQString &key() const { return mKey; } /** Set the sort key used by the list view. */ void setKey(const TQString &key) { mKey = key; } int id() const { return mId; } void setId(int id) { mId = id; } /** offset in the cache file stream */ int offset() const { return mSortOffset; } void setOffset(int x) { mSortOffset = x; } void updateSortFile( FILE *sortStream, KMFolder *folder, bool waiting_for_parent = false, bool update_discovered_count = false); /** Set the list of mails with a certain subject that this item is on. * Used to remove the item from that list on deletion. */ void setSubjectThreadingList( TQPtrList *list ) { mSubjThreadingList = list; } /** The list of mails with a certain subject that this item is on. */ TQPtrList* subjectThreadingList() const { return mSubjThreadingList; } private: HeaderItem *mItem; SortCacheItem *mParent; int mId, mSortOffset; TQString mKey; TQPtrList mSortedChildren; int mUnsortedCount, mUnsortedSize; SortCacheItem **mUnsortedChildren; bool mImperfectlyThreaded; // pointer to the list it might be on so it can be remove from it // when the item goes away. TQPtrList* mSubjThreadingList; }; /** * Visual representation of a member of the set of displayables (mails in * the current folder). Each item is paired with a KMail::SortCacheItem. See there as to * how they are meant to cooperate. This should be about the visual aspects of * displaying an entry only. */ class HeaderItem : public KListViewItem { public: HeaderItem( TQListView* parent, int msgId, const TQString& key = TQString() ); HeaderItem( TQListViewItem* parent, int msgId, const TQString& key = TQString() ); ~HeaderItem (); /** Set the message id of this item, which is the offset/index in the folder * currently displayed by the KMHeaders list view. */ void setMsgId( int aMsgId ); // Profiling note: About 30% of the time taken to initialize the // listview is spent in this function. About 60% is spent in operator // new and TQListViewItem::TQListViewItem. void irefresh(); /** Return the msgId of the message associated with this item. */ int msgId() const; TQString to() const; TQString from() const; // Return the serial number of the message associated with this item; TQ_UINT32 msgSerNum() const; /** Expands all children of the list view item. */ void setOpenRecursive( bool open ); /** Returns the text of the list view item. */ TQString text( int col) const; void setup(); typedef TQValueList PixmapList; TQPixmap pixmapMerge( PixmapList pixmaps ) const; const TQPixmap *cryptoIcon(KMMsgBase *msgBase) const; const TQPixmap *signatureIcon(KMMsgBase *msgBase) const; const TQPixmap *statusIcon(KMMsgBase *msgBase) const; const TQPixmap *pixmap(int col) const; void paintCell( TQPainter * p, const TQColorGroup & cg, int column, int width, int align ); static TQString generate_key( KMHeaders *headers, KMMsgBase *msg, const KPaintInfo *paintInfo, int sortOrder ); virtual TQString key( int column, bool /*ascending*/ ) const; void setTempKey( TQString key ); int compare( TQListViewItem *i, int col, bool ascending ) const; TQListViewItem* firstChildNonConst(); /* Non const! */ /** Returns whether the item is about to be removed from the list view as a * result of some user action. Such items are not selectable and painted with * a strike-through decoration. */ bool aboutToBeDeleted() const { return mAboutToBeDeleted; } /** Set the item to be in about-to-be-deleted state, which means it * cannot be selected and will be painted with a strike-through decoration. */ void setAboutToBeDeleted( bool val ) { mAboutToBeDeleted = val; } /** Associate a KMail::SortCacheItem with this item. This is the structure used to * represent the mail during sorting and threading calculation. */ void setSortCacheItem( SortCacheItem *item ) { mSortCacheItem = item; } /** Returns the KMail::SortCacheItem associated with this display item. */ SortCacheItem* sortCacheItem() const { return mSortCacheItem; } private: int mMsgId; TQ_UINT32 mSerNum; TQString mKey; bool mAboutToBeDeleted; SortCacheItem *mSortCacheItem; }; // End of class HeaderItem } // End of namespace KMail #endif // HEADERITEM_H