summaryrefslogtreecommitdiffstats
path: root/kmail/headeritem.h
blob: afebb8804f47bd854976906d51f954f6c9906b4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/*******************************************************************************
**
** 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 <stdlib.h>

#include <tdelistview.h> // 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<SortCacheItem> *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<SortCacheItem> *list ) { mSubjThreadingList = list; }
    /** The list of mails with a certain subject that this item is on. */
    TQPtrList<SortCacheItem>* subjectThreadingList() const { return mSubjThreadingList; }

private:
    HeaderItem *mItem;
    SortCacheItem *mParent;
    int mId, mSortOffset;
    TQString mKey;

    TQPtrList<SortCacheItem> 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<SortCacheItem>* 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 TDEListViewItem
{
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<TQPixmap> 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