[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kmail-devel
Subject:    Re: [PATCH] unread / total column
From:       Carsten Burghardt <cb () magic-shop ! de>
Date:       2002-05-01 10:52:12
[Download RAW message or body]

On Monday 29 April 2002 11:05, Marc Mutz wrote:
> On Monday 29 April 2002 00:03, Carsten Burghardt wrote:
> <snip>
>
> > Yes, that's what I had in mind. I've got a little riddle for you ;-)
> > If I integrate the Q_OBJECT macro into the KMFolderTreeItem class (I want
> > to call a slot there), I get tons of error message from the
> > kmfoldertree.moc-file:
>
> 1. Don't. QObjects are _huge_. Use a slot in the list view.
> 2. You have to move the declaration to a header file so that the makefile
> magic finds the Q_OBJECT.

Alright, attached is the latest version.
- popup-menu implemented
- the total-count is cached on startup and the folders are opened in the 
background (non-blocking) when you activate the total-column while kmail is 
running
- the order of the columns is remembered in a better way
- code cleaned up

Should be ready to go in IMO.
After that I will port the foldertree to KListView and clean up a bit. Then 
the sorting of the columns will also be remembered.

Regards,

Carsten
-- 
Carsten Burghardt
email: cb@magic-shop.de
WWW: http://www.magic-shop.de
PGP: http://www.magic-shop.de/Carsten_Burghardt.asc

["patch_unread_total.diff" (text/x-diff)]

? kdenetwork/kmail/.kmmainwin.cpp.swp
? kdenetwork/kmail/.kmfoldertree.cpp.swp
? kdenetwork/kmail/.kmmainwin.h.swp
Index: kdenetwork/kmail/kmfolder.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.cpp,v
retrieving revision 1.221
diff -u -3 -p -r1.221 kmfolder.cpp
--- kdenetwork/kmail/kmfolder.cpp	2002/04/20 19:27:14	1.221
+++ kdenetwork/kmail/kmfolder.cpp	2002/05/01 10:34:49
@@ -95,6 +95,7 @@ KMFolder :: KMFolder(KMFolderDir* aParen
   mDirty          = FALSE;
   mUnreadMsgs      = -1;
   mGuessedUnreadMsgs = -1;
+  mTotalMsgs      = -1;
   needsCompact    = FALSE;
   mChild          = 0;
   mConvertToUtf8  = FALSE;
@@ -402,6 +403,7 @@ bool KMFolder::readIndex()
   if (!readIndexHeader(&version)) return false;
 
   mUnreadMsgs = 0;
+  mTotalMsgs = 0;
   mHeaderOffset = ftell(mIndexStream);
 
   mMsgList.clear();
@@ -466,6 +468,7 @@ bool KMFolder::readIndex()
     mDirty = TRUE;
     writeIndex();
   }
+  mTotalMsgs = mMsgList.count();
   return true;
 }
 
@@ -811,10 +814,12 @@ void KMFolder::removeMsg(int idx, bool)
     --mUnreadMsgs;
     emit numUnreadMsgsChanged( this );
   }
+  --mTotalMsgs;
 
-  if (!mQuiet)
+  if (!mQuiet) {
     emit msgRemoved(idx, msgIdMD5);
-  else
+    emit msgRemoved(this);
+  } else
     mChanged = TRUE;
 }
 
@@ -839,12 +844,14 @@ KMMessage* KMFolder::take(int idx)
     --mUnreadMsgs;
     emit numUnreadMsgsChanged( this );
   }
+  --mTotalMsgs;
   msg->setParent(NULL);
   mDirty = TRUE;
   needsCompact=true; // message is taken from here - needs to be compacted
-  if (!mQuiet)
+  if (!mQuiet) {
     emit msgRemoved(idx,msgIdMD5);
-  else
+    emit msgRemoved(this);
+  } else
     mChanged = TRUE;
 
   return msg;
@@ -1111,6 +1118,7 @@ int KMFolder::expunge()
   }
 
   mUnreadMsgs = 0;
+  mTotalMsgs = 0;
   emit numUnreadMsgsChanged( this );
   if (mAutoCreateIndex)
     writeConfig();
@@ -1138,6 +1146,15 @@ QString KMFolder::label() const
   return name();
 }
 
+int KMFolder::count(bool cache) const
+{
+  if (cache && mTotalMsgs != -1)
+  {
+    return mTotalMsgs;
+  } else {
+    return mMsgList.count();
+  }
+}
 
 //-----------------------------------------------------------------------------
 int KMFolder::countUnread()
@@ -1266,6 +1283,8 @@ void KMFolder::readConfig()
   KConfigGroupSaver saver(config, "Folder-" + idString());
   if (mUnreadMsgs == -1)
     mUnreadMsgs = config->readNumEntry("UnreadMsgs", -1);
+  if (mTotalMsgs == -1)
+    mTotalMsgs = config->readNumEntry("TotalMsgs", -1);
   mMailingListEnabled = config->readBoolEntry("MailingListEnabled");
   mMailingListPostingAddress = config->readEntry("MailingListPostingAddress");
   mMailingListAdminAddress = config->readEntry("MailingListAdminAddress");
@@ -1293,6 +1312,7 @@ void KMFolder::writeConfig()
   KConfig* config = kapp->config();
   KConfigGroupSaver saver(config, "Folder-" + idString());
   config->writeEntry("UnreadMsgs", mUnreadMsgs);
+  config->writeEntry("TotalMsgs", mTotalMsgs);
   config->writeEntry("MailingListEnabled", mMailingListEnabled);
   config->writeEntry("MailingListPostingAddress", mMailingListPostingAddress);
   config->writeEntry("MailingListAdminAddress", mMailingListAdminAddress);
Index: kdenetwork/kmail/kmfolder.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolder.h,v
retrieving revision 1.85
diff -u -3 -p -r1.85 kmfolder.h
--- kdenetwork/kmail/kmfolder.h	2002/04/20 19:27:14	1.85
+++ kdenetwork/kmail/kmfolder.h	2002/05/01 10:34:49
@@ -159,7 +159,7 @@ public:
   virtual int find(const QString& msgIdMD5) const;
 
   /** Number of messages in this folder. */
-  virtual int count() const { return mMsgList.count(); }
+  virtual int count(bool cache = false) const;
 
   /** Number of new or unread messages in this folder. */
   virtual int countUnread();
@@ -460,9 +460,11 @@ signals:
 
   /** Emitted when a message is removed from the folder. */
   void msgRemoved(int,QString);
+  void msgRemoved(KMFolder*);
 
   /** Emitted when a message is added from the folder. */
   void msgAdded(int);
+  void msgAdded(KMFolder*);
 
   /** Emitted when a field of the header of a specific message changed. */
   void msgHeaderChanged(int);
@@ -564,6 +566,7 @@ protected:
   
   /** number of unread messages, -1 if not yet set */
   int mUnreadMsgs, mGuessedUnreadMsgs;
+  int mTotalMsgs;
   bool mWriteConfigEnabled;
   /** sven: true if on destruct folder needs to be compacted. */
   bool needsCompact;
Index: kdenetwork/kmail/kmfolderimap.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfolderimap.cpp,v
retrieving revision 1.59
diff -u -3 -p -r1.59 kmfolderimap.cpp
--- kdenetwork/kmail/kmfolderimap.cpp	2002/04/27 18:45:30	1.59
+++ kdenetwork/kmail/kmfolderimap.cpp	2002/05/01 10:34:50
@@ -167,7 +167,7 @@ void KMFolderImap::addMsgQuiet(KMMessage
   if (folder) kernel->undoStack()->pushAction( aMsg->getMsgSerNum(), folder, this );
   if (folder) folder->take(folder->find(aMsg));
   delete aMsg;
-  if (mIsSelected) getFolder();
+  getFolder();
 }
 
 //-----------------------------------------------------------------------------
@@ -181,7 +181,7 @@ void KMFolderImap::addMsgQuiet(QPtrList<
   if (folder) folder->take(msgList);
   msgList.setAutoDelete(true);
   msgList.clear();
-  if (mIsSelected) getFolder();
+  getFolder();
 }
 
 //-----------------------------------------------------------------------------
@@ -1400,7 +1400,6 @@ void KMFolderImap::getUids(QValueList<in
 
 void KMFolderImap::getUids(QPtrList<KMMessage>& msgList, QValueList<int>& uids, \
KMFolder* msgParent)  {
-  int idx = -1;
   KMMessage *msg = NULL;
 
   if (!msgParent) msgParent = msgList.first()->parent();
Index: kdenetwork/kmail/kmfoldermaildir.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfoldermaildir.cpp,v
retrieving revision 1.23
diff -u -3 -p -r1.23 kmfoldermaildir.cpp
--- kdenetwork/kmail/kmfoldermaildir.cpp	2002/03/08 21:24:58	1.23
+++ kdenetwork/kmail/kmfoldermaildir.cpp	2002/05/01 10:34:50
@@ -351,6 +351,7 @@ int KMFolderMaildir::addMsg(KMMessage* a
       ++mUnreadMsgs;
     emit numUnreadMsgsChanged( this );
   }
+  ++mTotalMsgs;
 
   // store information about the position in the folder file in the message
   aMsg->setParent(this);
@@ -405,9 +406,10 @@ int KMFolderMaildir::addMsg(KMMessage* a
   if (index_return)
     *index_return = idx;
 
-  if (!mQuiet)
+  if (!mQuiet) {
     emit msgAdded(idx);
-  else
+    emit msgAdded(this);
+  } else
     mChanged = TRUE;
 
   needsCompact = true;
Index: kdenetwork/kmail/kmfoldermbox.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfoldermbox.cpp,v
retrieving revision 1.21
diff -u -3 -p -r1.21 kmfoldermbox.cpp
--- kdenetwork/kmail/kmfoldermbox.cpp	2002/01/19 07:48:36	1.21
+++ kdenetwork/kmail/kmfoldermbox.cpp	2002/05/01 10:34:50
@@ -812,6 +812,7 @@ int KMFolderMbox::addMsg(KMMessage* aMsg
     else ++mUnreadMsgs;
     emit numUnreadMsgsChanged( this );
   }
+  ++mTotalMsgs;
 
   // store information about the position in the folder file in the message
   aMsg->setParent(this);
@@ -872,9 +873,10 @@ int KMFolderMbox::addMsg(KMMessage* aMsg
   
   // some "paper work"
   if (aIndex_ret) *aIndex_ret = idx;
-  if (!mQuiet)
+  if (!mQuiet) {
     emit msgAdded(idx);
-  else
+    emit msgAdded(this);
+  } else
     mChanged = TRUE;
 
   if (opened) close();
Index: kdenetwork/kmail/kmfoldertree.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfoldertree.cpp,v
retrieving revision 1.178
diff -u -3 -p -r1.178 kmfoldertree.cpp
--- kdenetwork/kmail/kmfoldertree.cpp	2002/04/30 03:48:47	1.178
+++ kdenetwork/kmail/kmfoldertree.cpp	2002/05/01 10:34:51
@@ -5,10 +5,10 @@
 #include <unistd.h>
 #include <assert.h>
 
-#include <kpopupmenu.h>
 #include <kapplication.h>
 #include <kiconloader.h>
 #include <kmessagebox.h>
+#include <kaction.h>
 
 #include <kdebug.h>
 
@@ -17,8 +17,8 @@
 #include "kmfoldertree.h"
 #include "kmfolderdia.h"
 #include "kmcomposewin.h"
+#include "kmmainwin.h"
 #include "cryptplugwrapperlist.h"
-#include <qpopupmenu.h>
 
 QPixmap* KMFolderTree::pixDir = 0;
 QPixmap* KMFolderTree::pixNode = 0;
@@ -69,7 +69,10 @@ void KMFolderTreeItem::paintCell( QPaint
 
   QString t = text( column );
   if ( !t.isEmpty() ) {
-    if( folder && (folder->countUnreadRecursive() > 0) ) {
+    // use a bold-font for the folder- and the unread-columns
+    if ( folder && (folder->countUnreadRecursive() > 0) &&
+       (column == 0 || column == \
static_cast<KMFolderTree*>(listView())->getUnreadColumIndex()) )  +    {
       QFont f = p->font();
       f.setWeight(QFont::Bold);
       p->setFont(f);
@@ -89,10 +92,16 @@ void KMFolderTreeItem::paintCell( QPaint
 
 
 //-----------------------------------------------------------------------------
-// Make sure system folders come first when sorting
-// (or last when sorting in descending order)
-QString KMFolderTreeItem::key( int, bool ) const
+// Implement the sorting of the folders
+QString KMFolderTreeItem::key(int column, bool) const
 {
+  if (column > 0) return text(column);
+
+  // root-folder
+  if (!folder)
+    return "\t6" + text(0).lower();
+
+  // make sure system folders come first when sorting
   if (folder->isSystemFolder())
   {
     if (folder->label() == i18n("inbox"))
@@ -106,13 +115,45 @@ QString KMFolderTreeItem::key( int, bool
     if (folder->label() == i18n("drafts"))
       return "\t4";
   }
-  if (folder->protocol() == "imap")
+  // then all other local mail-folders
+  if (folder->protocol() != "imap")
     return "\t5" + folder->label();
+
+  // the imap-folders
+  if (folder->protocol() == "imap")
+    return "\t6" + folder->label();
+
+  // fallback
   return text(0).lower();
 }
 
+//-----------------------------------------------------------------------------
+int KMFolderTreeItem::compare( QListViewItem * i, int col, bool ascending ) const 
+{
+  if (col == 0) 
+  {
+    // sort by folder
+    return key(col, ascending).localeAwareCompare( i->key(col, ascending) );
+  }
+  else 
+  {
+    // sort by unread or total-column
+    int a = 0, b = 0; 
+    if (!text(col).isNull() && text(col) != "-") 
+      a = text(col).toInt();
+    if (!i->text(col).isNull() && i->text(col) != "-") 
+      b = i->text(col).toInt();
+    
+    if ( a == b )
+      return 0;
+    else 
+      return (a < b ? -1 : 1);
+  }
+}
 
 //-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+
 void KMFolderTree::drawContentsOffset( QPainter * p, int ox, int oy,
                                        int cx, int cy, int cw, int ch )
 {
@@ -134,12 +175,17 @@ KMFolderTree::KMFolderTree( CryptPlugWra
   oldSelected = 0;
   oldCurrent = 0;
   mLastItem = NULL;
-
+  totalIsActive = false;
+  unreadIsActive = false;
+  unreadIndex = -1;
+  totalIndex = -1;
 
   // Espen 2000-05-14: Getting rid of thick ugly frames
   setLineWidth(0);
 
   setSelectionMode( Extended );
+  setAllColumnsShowFocus(true);
+  setShowSortIndicator(true);
 
   connect(&mUpdateTimer, SIGNAL(timeout()),
           this, SLOT(delayedUpdate()));
@@ -156,8 +202,7 @@ KMFolderTree::KMFolderTree( CryptPlugWra
 
   readConfig();
 
-  addColumn( i18n("Folders"), 400 );
-  setShowSortIndicator(TRUE);
+  addColumn( i18n("Folder"), 400 );
 
   if (!pixmapsLoaded)
   {
@@ -177,10 +222,10 @@ KMFolderTree::KMFolderTree( CryptPlugWra
   reload();
   cleanupConfigFile();
 
+  /** Drag and drop hover opening and autoscrolling support */
   setAcceptDrops( TRUE );
   viewport()->setAcceptDrops( TRUE );
 
-  // Drag and drop hover opening and autoscrolling support
   connect( &autoopen_timer, SIGNAL( timeout() ),
 	   this, SLOT( openFolder() ) );
 
@@ -196,8 +241,19 @@ KMFolderTree::KMFolderTree( CryptPlugWra
            this, SLOT( slotFolderExpanded( QListViewItem* ) ) );
   connect( this, SIGNAL( collapsed( QListViewItem* ) ),
            this, SLOT( slotFolderCollapsed( QListViewItem* ) ) );
+  /** dnd end */
+
+  /** popup to switch columns */
+  header()->setClickEnabled(true);
+  header()->installEventFilter(this);
+  mPopup = new KPopupMenu;
+  mPopup->insertTitle(i18n("Select columns"));
+  mPopup->setCheckable(true);
+  mUnreadPop = mPopup->insertItem(i18n("Unread Column"), this, \
SLOT(slotToggleUnreadColumn())); +  mTotalPop = mPopup->insertItem(i18n("Total \
Column"), this, SLOT(slotToggleTotalColumn()));  }
 
+//-----------------------------------------------------------------------------
 bool KMFolderTree::event(QEvent *e)
 {
   if (e->type() == QEvent::ApplicationPaletteChange)
@@ -379,7 +435,7 @@ void KMFolderTree::writeConfig()
 
 //-----------------------------------------------------------------------------
 // Reload the tree of items in the list view
-void KMFolderTree::reload(void)
+void KMFolderTree::reload(bool openFolders)
 {
   KMFolderDir* fdir;
   QString str;
@@ -410,12 +466,52 @@ void KMFolderTree::reload(void)
   fdir = &kernel->imapFolderMgr()->dir();
   addDirectory(fdir, root);
 
+  if (openFolders)
+  {
+    // we open all folders to update the count
+    mUpdateIterator = QListViewItemIterator (this);
+    QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
+  }
+  
   QListViewItemIterator jt( this );
-  while (jt.current()) {
+
+  while (jt.current()) 
+  {
     KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(jt.current());
     if (fti && fti->folder)
+    {
+      // first disconnect before each connect to make sure we don't call it twice
+      disconnect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)),
+	      this,SLOT(refresh(KMFolder*)));
       connect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)),
 	      this,SLOT(refresh(KMFolder*)));
+      if (totalIsActive || unreadIsActive)
+      {
+        // we want to be noticed of changes to update the unread/total columns
+        disconnect(fti->folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+        connect(fti->folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+        if (fti->folder->protocol() == "imap") 
+        {
+          // imap-only
+          disconnect(fti->folder, SIGNAL(folderComplete(KMFolderImap*, bool)),
+              this,SLOT(slotUpdateCounts(KMFolderImap*, bool)));
+          connect(fti->folder, SIGNAL(folderComplete(KMFolderImap*, bool)),
+              this,SLOT(slotUpdateCounts(KMFolderImap*, bool)));
+        }
+        disconnect(fti->folder, SIGNAL(msgRemoved(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+        connect(fti->folder, SIGNAL(msgRemoved(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+        disconnect(fti->folder, SIGNAL(msgAdded(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+        connect(fti->folder, SIGNAL(msgAdded(KMFolder*)),
+            this,SLOT(slotUpdateCounts(KMFolder*)));
+      }
+      if (!openFolders)
+        slotUpdateCounts(fti->folder);
+    }
     ++jt;
   }
   ensureVisible(0, top + visibleHeight(), 0, 0);
@@ -423,6 +519,29 @@ void KMFolderTree::reload(void)
 }
 
 //-----------------------------------------------------------------------------
+void KMFolderTree::slotUpdateOneCount() 
+{
+  if ( !mUpdateIterator.current() ) return;
+  KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(mUpdateIterator.current());
+  ++mUpdateIterator;
+  if ( !fti->folder ) {
+    // next one please
+    QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
+    return;
+  }
+ 
+  kdDebug() << "slotUpdateOneCount:" << fti->folder->label() << endl;
+  // open the folder and update the count
+  bool open = fti->folder->isOpened();
+  if (!open) fti->folder->open();
+  slotUpdateCounts(fti->folder);
+  // restore previous state
+  if (!open) fti->folder->close();
+  
+  QTimer::singleShot( 0, this, SLOT(slotUpdateOneCount()) );
+}
+
+//-----------------------------------------------------------------------------
 // Recursively add a directory of folders to the tree of folders
 void KMFolderTree::addDirectory( KMFolderDir *fdir, QListViewItem* parent )
 {
@@ -490,11 +609,15 @@ void KMFolderTree::delayedUpdate()
       continue;
     }
 
-    QString extendedName;
+    QString extendedName, num;
     if (fti->folder->countUnread() > 0) {
-      QString num;
-	num.setNum(fti->folder->countUnread());
-      extendedName = " (" + num + ")";
+      num.setNum(fti->folder->countUnread());
+      if (unreadIsActive)
+      {
+        fti->setText(unreadIndex, num);
+        extendedName = "";
+      } else
+        extendedName = " (" + num + ")";
       if (!fti->folder->isSystemFolder())
 	fti->setPixmap( 0, ((fti->folder->unreadIcon()) ? *(fti->folder->unreadIcon()) : \
(*pixFull)) );  }
@@ -729,23 +852,16 @@ void KMFolderTree::doFolderSelected( QLi
     emit folderSelected(0); // Root has been selected
   }
   else {
-    QString extendedName;
     emit folderSelected(folder);
-    if (fti->folder->protocol() == "imap")
+    if (folder->protocol() == "imap")
     {
       KMFolderImap *imap_folder = static_cast<KMFolderImap*>(fti->folder);
       imap_folder->setSelected(TRUE);
       if (imap_folder->getContentState() != KMFolderImap::imapInProgress)
         imap_folder->getFolder();
-    }
-    if (folder && (folder->countUnread() > 0) ) {
-      QString num;
-      num.setNum(folder->countUnread());
-      extendedName = " (" + num + ")";
-    }
-    if (extendedName != fti->unread) {
-      fti->unread = extendedName;
-      fti->repaint();
+    } else {
+      // we don't need this for imap-folders because they're updated with the \
folderComplete-signal +      slotUpdateCounts(folder);
     }
   }
 }
@@ -759,7 +875,6 @@ void KMFolderTree::resizeEvent(QResizeEv
   conf->writeEntry(name(), size().width());
 
   KMFolderTreeInherited::resizeEvent(e);
-  setColumnWidth( 0, visibleWidth() - 1 );
 }
 
 //-----------------------------------------------------------------------------
@@ -792,7 +907,8 @@ void KMFolderTree::rightButtonPressed(QL
   if (!fti )
     return;
 
-  QPopupMenu *folderMenu = new QPopupMenu;
+  KPopupMenu *folderMenu = new KPopupMenu;
+  if (fti->folder) folderMenu->insertTitle(fti->folder->label());
 
   if ((!fti->folder || (fti->folder->noContent()
     && fti->parent() == firstChild())))
@@ -1318,6 +1434,144 @@ void KMFolderTree::slotAccountDeleted(KM
   }
 }
 
+
+void KMFolderTree::slotUpdateCounts(KMFolderImap * folder, bool success)
+{
+  if (success) slotUpdateCounts(static_cast<KMFolder*>(folder));
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderTree::slotUpdateCounts(KMFolder * folder)
+{
+  QListViewItem * current;
+
+  if (folder) current = indexOfFolder(folder);
+  else current = currentItem();
+
+  KMFolderTreeItem* fti = static_cast<KMFolderTreeItem*>(current);
+  // sanity check
+  if (!fti || !fti->folder) return;
+
+  QString extendedName, num;
+  int count = 0;
+  if (unreadIsActive)
+  {
+    // unread-column is active
+    if (folder->noContent()) // always empty
+      num = QString::null;
+    else if (fti->folder->countUnread() == 0)
+      num = "-";
+    else
+      num.setNum(fti->folder->countUnread());
+
+    fti->setText(unreadIndex, num);
+    extendedName = "";
+
+  } else if (fti->folder->countUnread() > 0)
+  {
+    // "classic"-way
+    num.setNum(fti->folder->countUnread());
+    extendedName = " (" + num + ")";
+  }
+  if (extendedName != fti->unread) 
+  {
+    // repaint on change
+    fti->unread = extendedName;
+    fti->repaint();
+  }
+  if (totalIsActive)
+  {
+    // get the total-count
+    if (fti->folder->isOpened())
+      count = fti->folder->count();
+    else 
+      count = fti->folder->count(true); // count with caching
+    
+    if (fti->folder->noContent())
+      num = QString::null;
+    else if (count == 0)
+      num = "-";
+    else
+      num.setNum(count);
+
+    fti->setText(totalIndex, num);
+  }
+}
+
+
+//-----------------------------------------------------------------------------
+void KMFolderTree::toggleColumn(int column, bool openFolders)
+{
+  if (column == unread)
+  {
+    // switch unread
+    if (unreadIsActive)
+    {
+      removeColumn( unreadIndex );
+      if (totalIsActive && totalIndex > unreadIndex) --totalIndex;
+      unreadIndex = -1;
+      unreadIsActive = false;
+      reload();
+    } else {
+      unreadIndex = addColumn( i18n("Unread"), 70 );
+      unreadIsActive = true;
+      setColumnAlignment( unreadIndex, Qt :: AlignRight);
+      reload();
+    }
+    // toggle KPopupMenu and KToggleAction
+    mPopup->setItemChecked( mUnreadPop, unreadIsActive );
+    if ( parentWidget()->parentWidget()->isA("KMMainWin") )
+      static_cast<KMMainWin*>(parentWidget()->parentWidget())
+        ->unreadColumnToggle->setChecked( unreadIsActive );
+
+  } else if (column == total) {	
+    // switch total
+    if (totalIsActive)
+    {
+      removeColumn( totalIndex );
+      if (unreadIsActive && totalIndex < unreadIndex) --unreadIndex;
+      totalIndex = -1;
+      totalIsActive = false;
+      reload();
+    } else {
+      totalIndex = addColumn( i18n("Total"), 70 );
+      totalIsActive = true;
+      setColumnAlignment( totalIndex, Qt :: AlignRight);
+      reload(openFolders);
+    }
+    // toggle KPopupMenu and KToggleAction
+    mPopup->setItemChecked( mTotalPop, totalIsActive );
+    if ( parentWidget()->parentWidget()->isA("KMMainWin") )
+      static_cast<KMMainWin*>(parentWidget()->parentWidget())
+        ->totalColumnToggle->setChecked( totalIsActive );
+
+  } else kdDebug(5006) << "unknown column:" << column << endl;
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderTree::slotToggleUnreadColumn()
+{
+  toggleColumn(unread);
+}
+
+//-----------------------------------------------------------------------------
+void KMFolderTree::slotToggleTotalColumn()
+{
+  // activate the total-column and force the folders to be opened
+  toggleColumn(total, true);
+}
+
+//-----------------------------------------------------------------------------
+bool KMFolderTree::eventFilter( QObject *o, QEvent *e )
+{
+  if (e->type() == QEvent::MouseButtonPress &&
+      dynamic_cast<QMouseEvent*>(e)->button() == RightButton)
+  {
+    mPopup->popup( mapToGlobal( header()->geometry().bottomRight() ) );
+    return true;
+  }
+  return KMFolderTreeInherited::eventFilter(o, e);
+}
 
 #include "kmfoldertree.moc"
 
Index: kdenetwork/kmail/kmfoldertree.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmfoldertree.h,v
retrieving revision 1.49
diff -u -3 -p -r1.49 kmfoldertree.h
--- kdenetwork/kmail/kmfoldertree.h	2002/04/22 06:04:07	1.49
+++ kdenetwork/kmail/kmfoldertree.h	2002/05/01 10:34:51
@@ -4,7 +4,9 @@
 #include <qwidget.h>
 #include <qlistview.h>
 #include <qtimer.h>
+#include <qheader.h>
 #include <klocale.h>
+#include <kpopupmenu.h>
 
 // Fixme! A temporary dependency
 #include "kmheaders.h" // For KMHeaderToFolderDrag & KMPaintInfo
@@ -19,7 +21,6 @@ class CryptPlugWrapperList;
 
 class KMFolderTreeItem : public QListViewItem
 {
- 
 public:
   KMFolder* folder;
   QString unread;
@@ -56,7 +57,11 @@ public:
 
   void paintCell( QPainter * p, const QColorGroup & cg,
                   int column, int width, int align ); 
+
   virtual QString key( int, bool ) const;
+
+  virtual int compare( QListViewItem * i, int col, bool ascending ) const; 
+
 };
 
 
@@ -78,7 +83,7 @@ public:
   void writeConfig();
 
   /** Get/refresh the folder tree */
-  virtual void reload(void);
+  virtual void reload(bool openFolders = false);
 
   /** Recusively add folders in a folder directory to a listview item. */
   virtual void addDirectory( KMFolderDir *fdir, QListViewItem* parent );
@@ -114,6 +119,23 @@ public:
 
   KMFolder *currentFolder() const;
 
+  enum ColumnMode {unread=15, total=16};
+
+  /** toggles the unread and total columns on/off */
+  void toggleColumn(int column, bool openFolders = false);
+
+  /** returns true when the column is active */
+  bool isUnreadActive() { return unreadIsActive; }
+  bool isTotalActive() { return totalIsActive; }
+
+  /** returns the current column number (section) */
+  int getUnreadColumnNumber() { return header()->mapToSection(unreadIndex); }
+  int getTotalColumnNumber() { return header()->mapToSection(totalIndex); }
+
+  /** returns the current column number (section) */
+  int getUnreadColumIndex() { return unreadIndex; }
+  int getTotalColumnIndex() { return totalIndex; }
+
 signals:
   /** The selected folder has changed */
   void folderSelected(KMFolder*);
@@ -172,6 +194,15 @@ protected slots:
   /** Tell the folder to refresh the contents on the next expansion */
   void slotFolderCollapsed( QListViewItem * item );
 
+  /** Update the total and unread columns (if available) */
+  void slotUpdateCounts(KMFolder * folder);
+  void slotUpdateCounts(KMFolderImap * folder, bool success = true);
+  void slotUpdateOneCount();
+
+  /** slots for the unread/total-popup */
+  void slotToggleUnreadColumn();
+  void slotToggleTotalColumn();
+
 protected:
   /** Catch palette changes */
   virtual bool event(QEvent *e);
@@ -208,6 +239,7 @@ protected:
   virtual void contentsMousePressEvent( QMouseEvent * e );
   virtual void contentsMouseReleaseEvent( QMouseEvent * e );
   virtual void contentsMouseMoveEvent( QMouseEvent* e );
+
   /** Drag and drop variables */
   QListViewItem *oldCurrent, *oldSelected;
   QListViewItem *dropItem;
@@ -215,12 +247,28 @@ protected:
   QTimer autoopen_timer;
   KMPaintInfo mPaintInfo;
 
+  // filter some rmb-events
+  bool eventFilter(QObject*, QEvent*);
+
   // ########### The Trolls may move this Drag and drop stuff to QScrollView
 private:
     QTimer autoscroll_timer;
     int autoscroll_time;
     int autoscroll_accel;
     CryptPlugWrapperList * mCryptPlugList;
+
+    /** unread and total column */
+    bool unreadIsActive;
+    bool totalIsActive;
+    QListViewItemIterator mUpdateIterator;
+    int unreadIndex; 
+    int totalIndex;
+
+    /** popup for unread/total */
+    KPopupMenu* mPopup;
+    int mUnreadPop;
+    int mTotalPop;
+
 public slots:
     void startAutoScroll();
     void stopAutoScroll();
Index: kdenetwork/kmail/kmmainwin.cpp
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmainwin.cpp,v
retrieving revision 1.452
diff -u -3 -p -r1.452 kmmainwin.cpp
--- kdenetwork/kmail/kmmainwin.cpp	2002/04/30 17:55:06	1.452
+++ kdenetwork/kmail/kmmainwin.cpp	2002/05/01 10:34:52
@@ -13,6 +13,7 @@
 #include <qmap.h>
 #include <qvaluelist.h>
 #include <qtextcodec.h>
+#include <qheader.h>
 
 #include <kopenwith.h>
 
@@ -293,6 +294,32 @@ void KMMainWin::readConfig(void)
       (*mPanner1Sep)[1] = width() - siz.height();
     }
 
+    /** unread / total columns */
+
+    // get the number (aka section) of the column; -1 is de-activated
+    int unreadColumn = config->readNumEntry("UnreadColumn", -1); 
+    int totalColumn = config->readNumEntry("TotalColumn", -1);
+
+    // activate them
+    if (unreadColumn != -1) { 
+      slotToggleUnreadColumn();
+      mFolderTree->setColumnWidth(mFolderTree->getUnreadColumnNumber(), \
config->readNumEntry("UnreadColumnWidth")); +    }
+    if (totalColumn != -1) {
+      slotToggleTotalColumn();
+      mFolderTree->setColumnWidth(mFolderTree->getTotalColumnNumber(), \
config->readNumEntry("TotalColumnWidth")); +    }
+    // get the correct order back
+    if (totalColumn < unreadColumn)
+      mFolderTree->header()->moveSection(2, 1);
+    
+    // resize the folder column
+    int foldercolumnsize = config->readNumEntry("FolderColumnWidth", -1);
+    if (foldercolumnsize == -1) // first start
+      foldercolumnsize = config->readNumEntry("FolderPaneWidth", 160);
+    mFolderTree->setColumnWidth(0, foldercolumnsize);
+
+    /** unread/total end */
   }
 
   mMsgView->readConfig();
@@ -410,6 +437,23 @@ void KMMainWin::writeConfig(void)
         config->writeEntry( "HeaderPaneWidth", mPanner2->sizes()[1] );
         break;
     }
+
+    // width of the folder-column (needed if unread/total-column is active
+    config->writeEntry("FolderColumnWidth", mFolderTree->columnWidth(0));
+    // save the state of the unread/total-columns
+    if (mFolderTree->isUnreadActive())
+    {
+      config->writeEntry("UnreadColumn", mFolderTree->getUnreadColumnNumber());
+      config->writeEntry("UnreadColumnWidth", \
mFolderTree->columnWidth(mFolderTree->getUnreadColumnNumber())); +    } else 
+      config->writeEntry("UnreadColumn", -1);
+
+    if (mFolderTree->isTotalActive())
+    {
+      config->writeEntry("TotalColumn", mFolderTree->getTotalColumnNumber());
+      config->writeEntry("TotalColumnWidth", \
mFolderTree->columnWidth(mFolderTree->getTotalColumnNumber())); +    } else 
+      config->writeEntry("TotalColumn", -1);
   }
 
 
@@ -1398,6 +1442,17 @@ void KMMainWin::slotToggleFixedFont()
   mMsgView->slotToggleFixedFont();
 }
 
+//-----------------------------------------------------------------------------
+void KMMainWin::slotToggleUnreadColumn()
+{
+  mFolderTree->toggleColumn(KMFolderTree::unread);
+}
+
+//-----------------------------------------------------------------------------
+void KMMainWin::slotToggleTotalColumn()
+{
+  mFolderTree->toggleColumn(KMFolderTree::total);
+}
 
 //-----------------------------------------------------------------------------
 void KMMainWin::slotMoveMsg()
@@ -2606,6 +2661,22 @@ void KMMainWin::setupMenuBar()
   raction = actionForAttachmentStyle( mMsgView->attachmentStyle() );
   if ( raction )
     raction->setChecked( true );
+
+  unreadColumnToggle = new KToggleAction( i18n("View->", "&Unread Column"), 0, this,
+			       SLOT(slotToggleUnreadColumn()),
+			       actionCollection(), "view_columns_unread" );
+  msg = i18n("Toggle display of column showing the "
+	     "number of unread messages in folders.");
+  unreadColumnToggle->setToolTip( msg );
+  unreadColumnToggle->setChecked( mFolderTree->isUnreadActive() );
+
+  totalColumnToggle = new KToggleAction( i18n("View->", "&Total Column"), 0, this,
+			       SLOT(slotToggleTotalColumn()),
+			       actionCollection(), "view_columns_total" );
+  msg = i18n("Toggle display of column showing the "
+	     "total number of messages in folders.");
+  totalColumnToggle->setToolTip( msg );
+  totalColumnToggle->setChecked( mFolderTree->isTotalActive() );
 
   toggleFixFontAction = new KToggleAction( i18n("Fixed Font &Widths"),
 			0, this, SLOT(slotToggleFixedFont()),
Index: kdenetwork/kmail/kmmainwin.h
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmainwin.h,v
retrieving revision 1.118
diff -u -3 -p -r1.118 kmmainwin.h
--- kdenetwork/kmail/kmmainwin.h	2002/04/30 02:04:51	1.118
+++ kdenetwork/kmail/kmmainwin.h	2002/05/01 10:34:53
@@ -99,6 +99,7 @@ public:
 					QPopupMenu *menu);
 
   static void cleanup();
+
   KAction *replyAction, *noQuoteReplyAction, *replyAllAction, *replyListAction,
     *forwardAction, *forwardAttachedAction, *redirectAction,
     *deleteAction, *saveAsAction, *bounceAction, *editAction,
@@ -108,6 +109,10 @@ public:
     *moveActionMenu, *copyActionMenu;
   CryptPlugWrapperList mCryptPlugList;
 
+  /** we need to access those KToggleActions from the foldertree-popup */
+  KToggleAction* unreadColumnToggle;
+  KToggleAction* totalColumnToggle;
+
   void folderSelected(KMFolder*, bool jumpToUnread);
 
   /** Jump to any message in any folder.  The message serial number of the
@@ -223,6 +228,8 @@ protected slots:
   void slotSetThreadStatusFlag();
   void slotShowMsgSrc();
   void slotToggleFixedFont();
+  void slotToggleUnreadColumn();
+  void slotToggleTotalColumn();
   void slotBriefHeaders();
   void slotFancyHeaders();
   void slotStandardHeaders();
Index: kdenetwork/kmail/kmmainwin.rc
===================================================================
RCS file: /home/kde/kdenetwork/kmail/kmmainwin.rc,v
retrieving revision 1.30
diff -u -3 -p -r1.30 kmmainwin.rc
--- kdenetwork/kmail/kmmainwin.rc	2002/04/26 19:26:56	1.30
+++ kdenetwork/kmail/kmmainwin.rc	2002/05/01 10:34:53
@@ -1,5 +1,5 @@
 <!DOCTYPE kpartgui >
-<kpartgui version="30" name="kmmainwin" >
+<kpartgui version="31" name="kmmainwin" >
  <MenuBar>
   <Menu noMerge="1" name="file" >
    <text>&amp;File</text>
@@ -37,10 +37,10 @@
    <Action name="view_headers"/>
    <Action name="view_attachments"/>
    <Separator/>
-   <Action name="toggle_fixedfont"/>
+   <Action name="view_columns_unread"/>
+   <Action name="view_columns_total"/>
    <Separator/>
-   <Action name="toggle_unreadcolumn"/>
-   <Action name="toggle_totalcolumn"/>
+   <Action name="toggle_fixedfont"/>
    <Separator/>
    <Action name="view_source"/>
   </Menu>


_______________________________________________
KMail Developers mailing list
kmail@mail.kde.org
http://mail.kde.org/mailman/listinfo/kmail

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic