summaryrefslogtreecommitdiffstats
path: root/kmail/kmheaders.h
blob: 423ec3dcfdf89091f5dca3c0c6d133939d83f167 (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
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
// -*- mode: C++ -*-

#ifndef __KMHEADERS
#define __KMHEADERS

#include "kmime_util.h"
#include "headeritem.h"
using KMail::SortCacheItem;
using KMail::HeaderItem;

#include <tdelistview.h>
#include <kfoldertree.h> // for KPaintInfo
#include <kmmsgbase.h>   // for KMMsgStatus

#include <tqwidget.h>
#include <tqstrlist.h>
#include <tqmemarray.h>
#include <tqmap.h>
#include <tqdragobject.h>
#include <tqdict.h>
#include <tqguardedptr.h>

class KMFolder;
class KMMessage;
class KMMsgBase;
class KMCommand;
class KMMainWidget;
class TDEPopupMenu;
class TQPalette;
class TQPixmap;
class TQIconSet;
class TQDateTime;

typedef TQPtrList<KMMsgBase> KMMessageList;
typedef TQValueList<TQ_UINT32> SerNumList;
typedef TQMap<int,KMFolder*> KMMenuToFolder;
enum NestingPolicy { AlwaysOpen = 0, DefaultOpen, DefaultClosed, OpenUnread };


#define KMAIL_SORT_VERSION 1012
#define KMAIL_SORT_FILE(x) x->indexLocation() + ".sorted"
#define KMAIL_SORT_HEADER "## KMail Sort V%04d\n\t"
#define KMAIL_MAGIC_HEADER_OFFSET 21 //strlen(KMAIL_SORT_HEADER)
#define KMAIL_MAX_KEY_LEN 16384
#define KMAIL_RESERVED 3

/** The widget that shows the contents of folders */
class KMHeaders : public TDEListView
{
  Q_OBJECT
  

  friend class ::KMail::HeaderItem; // For easy access to the pixmaps

public:
  KMHeaders(KMMainWidget *owner, TQWidget *parent=0, const char *name=0);
  virtual ~KMHeaders();

  /** A new folder has been selected update the list of headers shown
   * To override the global settings for jumping to the first unread msg
   * use @p forceJumpToUnread
   */
  virtual void setFolder(KMFolder *, bool forceJumpToUnread = false);

  /** Return the folder whose message headers are being displayed */
  KMFolder* folder(void) { return mFolder; }

  /** read the config file and update nested state if necessary */
  void refreshNestedState(void);

  /** Set current message. If id<0 then the first message is shown,
    if id>count() the last message is shown. */
  virtual void setCurrentMsg(int msgId);

  /** Get a list of all items in the current thread */
  TQPtrList<TQListViewItem> currentThread() const;

  /** Set all messages in the current thread to status @p status
      or toggle it, if specified. */
  virtual void setThreadStatus(KMMsgStatus status, bool toggle=false);

  /* Set message status to read if it is new, or unread */
  virtual void setMsgRead(int msgId);

  /** The following methods processes all selected messages. */
  virtual void setMsgStatus(KMMsgStatus status, bool toggle=false);
  virtual void deleteMsg();
  virtual void applyFiltersOnMsg();
  virtual void undo();
  virtual bool canUndo() const;
  virtual HeaderItem * prepareMove( int *contentX, int *contentY );
  virtual void finalizeMove( HeaderItem *item, int contentX, int contentY );

  /** If destination is 0 then the messages are deleted, otherwise
    they are moved to this folder. The second parameter is usefull when the
    user has already confirmed the move/deletion. */
  virtual void moveMsgToFolder( KMFolder* destination,
                                bool askForConfirmation=true );

  /** Messages are duplicated and added to given folder.
      If aMsg is set this one will be written to the destination folder. */
  virtual void copyMsgToFolder(KMFolder* destination,
                               KMMessage* aMsg = 0);

  /** Resets toBeDeleted and selectable status of all selected items. */
  virtual void clearSelectableAndAboutToBeDeleted(TQ_UINT32 serNum);
  /** Returns list of selected messages. Mark the corresponding
      header items to be deleted, if specified. */
  virtual KMMessageList* selectedMsgs(bool toBeDeleted = false);

  /** Returns the index values of currently selected items */
  TQValueList<int> selectedItems();

  /** Returns the sernums of all selected items. */
  TQValueList<TQ_UINT32> selectedSernums();

  /** Returns the sernums of all visible (ie. items with expanded parent, not hidden by
      eg. the quick search) selected items.
  */
  TQValueList<TQ_UINT32> selectedVisibleSernums();

  /** Returns index of message returned by last getMsg() call */
  int indexOfGetMsg (void) const { return getMsgIndex; }

  /** Returns pointer to owning main window. */
  KMMainWidget* owner(void) const { return mOwner; }

  /** PaintInfo pointer */
  const KPaintInfo *paintInfo(void) const { return &mPaintInfo; }

  /** Read config options. */
  virtual void readConfig(void);

  /** Read color options and set palette. */
  virtual void readColorConfig(void);

  /**
   * Same as TDEListView::restoreLayout(), only that this does _not_ restore the sort order.
   * This is useful since restoreLayout() doesn't restore the sort order correctly, as
   * TDEListView doesn't know about our extended sort order like date of arrival.
   *
   * Note that if you want to restore the sort order correctly, call readConfig().
   */
  void restoreColumnLayout( TDEConfig *config, const TQString &group );

  /** Return the current message */
  virtual KMMessage* currentMsg();
  /** Return the current list view item */
  virtual HeaderItem* currentHeaderItem();
  /** Return the index of the message corresponding to the current item */
  virtual int currentItemIndex();
  /** Set the current item to the one corresponding to the given msg id */
  virtual void setCurrentItemByIndex( int msgIdx );
  /** Set the current item to the one corresponding to the given serial number (slow!) */
  void setCurrentItemBySerialNum( unsigned long serialNum );
  /** Return the message id of the top most visible item */
  virtual int topItemIndex();
  /** Make the item corresponding to the message with the given id the
      top most visible item. */
  virtual void setTopItemByIndex( int aMsgIdx );
  virtual void setNestedOverride( bool override );
  virtual void setSubjectThreading( bool subjThreading );
  /** Double force items to always be open */
  virtual void setOpen ( TQListViewItem *, bool );

  NestingPolicy getNestingPolicy() const { return nestingPolicy; }
  /** Returns true if the current header list is threaded. */
  bool isThreaded() const {
    return mNested != mNestedOverride; // xor
  }

  /** Find next/prev unread message. Starts at currentItem() if startAt
    is unset. */
  virtual int findUnread(bool findNext, int startAt=-1, bool onlyNew = false, bool acceptCurrent = false);

  void highlightMessage(TQListViewItem*, bool markitread);
  void highlightCurrentThread();

  /** return a string relativ to the current time */
  static TQString fancyDate( time_t otime );

  bool noRepaint;

  // filter events for popup
  bool eventFilter ( TQObject *o, TQEvent *e );

    /** gets the message represented by the item as a KMMsgBase. */
  const KMMsgBase * getMsgBaseForItem( const TQListViewItem *item ) const;

  // accessors
  TQFont newFont() const { return mNewFont; }
  TQFont unreadFont() const { return mUnreadFont; }
  TQFont importantFont() const { return mImportantFont; }
  TQFont todoFont() const { return mTodoFont; }
  TQFont dateFont() const { return mDateFont; }

  /**
    Sets the list of copied/cutted messages.
    @param msgs A list of serial numbers.
    @param move if true, the messages were cutted
  */
  void setCopiedMessages( const TQValueList<TQ_UINT32> &msgs, bool move );

  /**
    Returns true if the message with the given serial number has been cut.
    @param serNum A message serial number.
  */
  bool isMessageCut( TQ_UINT32 serNum ) const;

  /** Write global config options. */
  virtual void writeConfig(void);

signals:
  /** emitted when the list view item corresponding to this message
      has been selected */
  void selected(KMMessage *);
  /** emitted when the list view item corresponding to this message
      has been double clicked */
  void activated(KMMessage *);
  /** emitted when we might be about to delete messages */
  void maybeDeleting();
  /** emitted when the list of messages has been completely rebuilt */
  void messageListUpdated();

  /** emitted after a new item has been fully built and added to the
   * list view. We can't use TDEListView::itemAdded, as that is emitted
   * from the ctor of the item, at which point the building of the item
   * is not yet far enough along to update the quick search, which is
   * what is connected to this signal. */
  void msgAddedToListView( TQListViewItem* );

public slots:
  /** For when a list view item has been double clicked */
  void selectMessage(TQListViewItem*);
  /** For when a list view item has been selected */
  void highlightMessage(TQListViewItem*);
  /** For when righ mouse button is pressed */
  void slotRMB();
  /** Refresh list view item corresponding to the messae with the given id */
  void msgHeaderChanged(KMFolder *folder, int msgId);
  /** For when the list of messages in a folder has changed */
  void msgChanged();
  /** For when the folder has been cleared */
  void folderCleared();
  /** For when the folder has been cleared */
  void folderClosed();
  /** For when the message with the given message id has been added to a folder */
  void msgAdded(int);
  /** For when the message with the given id has been removed for a folder */
  void msgRemoved( int, TQString );
  /** Make the next header visible scrolling if necessary */
  void nextMessage();
  /** Same as nextMessage() but don't clear the current selection */
  void selectNextMessage();
  /** Make the previous header visible scrolling if necessary */
  void prevMessage();
  /** Same as prevMessage() but don't clear the current selection */
  void selectPrevMessage();
  /** Make the nextUnread message header visible scrolling if necessary, returning
    true if an unread message is found */
  bool nextUnreadMessage(bool acceptCurrent = false);
  /** Make the previous message header visible scrolling if necessary, returning
    true if an unread message is found */
  bool prevUnreadMessage();
  /** Focus the next message, but don't select it. */
  void incCurrentMessage();
  /** Focus the previous message, but don't select it. */
  void decCurrentMessage();
  /** Select the message which currently has focus, if it's not already selected. */
  void selectCurrentMessage();
  /** Don't show a drag cursor */
  void slotNoDrag();
  /** timer function to set the current time regularly */
  void resetCurrentTime();

  /** Refresh the list of message headers shown */
  void reset();

  /** Expands (@p expand == true) or collapses (@p expand == false)
      the current thread. */
  void slotExpandOrCollapseThread( bool expand );
  /** Expands (@p expand == true) or collapses (@p expand == false)
      all threads */
  void slotExpandOrCollapseAllThreads( bool expand );

  virtual void ensureCurrentItemVisible();

  /** Select an item and if it is the parent of a closed thread, also
    recursively select its children. */
  virtual void setSelected(TQListViewItem *item, bool selected);

  /** Select several items by message index
   * and if they are the parent of a closed thread, also
   * recursively select their children. */
  void setSelectedByIndex(TQValueList<int> items, bool selected);

  /** switch a column with the given id (see KPaintInfo enum)
      1 for activate, 0 for deactivate, -1 for toggle*/
  void slotToggleColumn(int id, int mode = -1);

  /** Provide information about number of messages in a folder */
  void setFolderInfoStatus();

protected:
  static TQPixmap *pixNew, *pixUns, *pixDel, *pixRead, *pixRep, *pixSent,
    *pixQueued, *pixFwd, *pixFlag, *pixWatched, *pixIgnored, *pixSpam, *pixHam,
    *pixFullySigned, *pixPartiallySigned, *pixUndefinedSigned,
    *pixFullyEncrypted, *pixPartiallyEncrypted, *pixUndefinedEncrypted,
    *pixFiller, *pixEncryptionProblematic,
    *pixSignatureProblematic, *pixAttachment, *pixInvitation,
    *pixReadFwd, *pixReadReplied, *pixReadFwdReplied, *pixTodo;

  /** Look for color changes */
  virtual bool event(TQEvent *e);

  /** Overridden to support backing pixmap */
  virtual void paintEmptyArea( TQPainter * p, const TQRect & rect );

  /** Ensure the current item is visible */
  void makeHeaderVisible();

  /** Auxillary method to findUnread */
  void findUnreadAux( HeaderItem*&, bool &, bool, bool );

  /** Returns message index of first selected message of the messages
    where the message with the given id is in. This for finding the correct
    message that shall be the current message after move/delete of multiple
    messages. */
  virtual int firstSelectedMsg() const;

  /** Read per-folder config options and apply them. */
  virtual void readFolderConfig(void);

  /** Write per-folder config options. */
  virtual void writeFolderConfig(void);

  /** Handle shift and control selection */
  virtual void contentsMousePressEvent(TQMouseEvent*);
  virtual void contentsMouseReleaseEvent(TQMouseEvent* e);
  virtual void keyPressEvent( TQKeyEvent * e );

  /** Called when a header is clicked */
  virtual void setSorting( int column, bool ascending = true);

  /** To initiate a drag operation */
  void contentsMouseMoveEvent( TQMouseEvent *e );

  /** reimplemented in order to update the frame width in case of a changed
      GUI style */
  void styleChange( TQStyle& oldStyle );

  /** Set the width of the frame to a reasonable value for the current GUI
      style */
  void setStyleDependantFrameWidth();

protected slots:
  /** Move messages corresponding to the selected items to the folder
      corresponding to the given menuId */
  virtual void moveSelectedToFolder( int menuId );
  /** Same thing but copy */
  virtual void copySelectedToFolder( int menuId );
  /** Apply the filter Rules to a single message */
  virtual int slotFilterMsg( KMMessage * );
  /** dirties the sort order */
  void dirtySortOrder(int);
  /** show context menu */
  void rightButtonPressed( TQListViewItem *, const TQPoint &, int );

private slots:
  void slotMoveCompleted( KMCommand * );

  void copyMessages();
  void cutMessages();
  void pasteMessages();

  void updateActions();

private:
  /** Is equivalent to clearing the list and inserting an item for
      each message in the current folder */
  virtual void updateMessageList( bool set_selection=false,
      bool forceJumpToUnread = false );

  /** Currently associated folder */
  TQGuardedPtr<KMFolder> mFolder;
  /** The KMMainWin for status bar updates */
  KMMainWidget* mOwner;
  /** Top most visible item */
  int mTopItem;
  /** Index of the current item */
  int mCurrentItem;
  /** Serial number of the current item */
  unsigned long mCurrentItemSerNum;
  /** Map messages ids into HeaderItems */
  TQMemArray<HeaderItem*> mItems;

  // ===== threading and sorting ==========
  bool mNested, mNestedOverride, mSubjThreading;
  NestingPolicy nestingPolicy;
  int mSortCol;
  bool mSortDescending;
  bool mIgnoreSortOrderChanges;

  struct {
      uint ascending : 1;
      uint dirty : 1;
      short column;
      uint fakeSort : 1;
      uint removed : 1;
  } mSortInfo;


  /** */
  TQDict< SortCacheItem > mSortCacheItems;
  /** */
  TQDict< TQPtrList< SortCacheItem > > mSubjectLists;
  /** */
  TQPtrList<HeaderItem> mImperfectlyThreadedList;

  /** Debugging helpers for outputting the threading data structures. */
  void printSubjectThreadingTree( );
  void printThreadingTree( );
  /** Initializes the mSortCacheItems tree with the contents of the folder */
  void buildThreadingTree( TQMemArray<SortCacheItem *> sortCache );
  /** Initializes the mSubjectLists tree with the contents of the folder */
  void buildSubjectThreadingTree( TQMemArray<SortCacheItem *> sortCache );
  /** Find a msg to thread item below */
  SortCacheItem* findParent(SortCacheItem *item);
  /** Find a msg to thread item below by subject */
  SortCacheItem* findParentBySubject(SortCacheItem *item);
  SortCacheItem* mRoot; // used to represent the list view itself while threading

  /** */
  void appendItemToSortFile(HeaderItem *);
  /** */
  bool writeSortOrder();
  /** */
  bool readSortOrder( bool set_selection = false,
      bool forceJumpToUnread = false );

  /** Updated as side effect of KMHeaders::getMsg */
  int getMsgIndex;
  /** ditto */
  bool getMsgMulti;
  /** ditto */
  HeaderItem* getMsgItem;
  /** @see KMHeaders::selectedMsgs isn't reentrant */
  KMMessageList mSelMsgBaseList;
  HeaderItem* mPrevCurrent;

  /** Current colours and backing pixmap */
  KPaintInfo mPaintInfo;

  TQFont mNewFont, mUnreadFont, mImportantFont, mDateFont,mTodoFont;

  /** Icons shown in header */
  static TQIconSet *up, *down;
  /** Map menu id into a folder */
  KMMenuToFolder mMenuToFolder;

  /** Drag and drop support */
  bool mMousePressed;
  /** ditto */
  TQPoint mPressPos;

  KMime::DateFormatter mDate;
  bool mReaderWindowActive;

  /** popup to switch columns */
  TDEPopupMenu* mPopup;

  // copied messages
  TQValueList<TQ_UINT32> mCopiedMessages;
  bool mMoveMessages;
}; // class
#endif