From 4d416f2a6ffc83620f7c2fffa6b4df207b5c7ff8 Mon Sep 17 00:00:00 2001 From: Carsten Burghardt Date: Sun, 30 Jun 2002 09:29:17 +0000 Subject: [PATCH] Rather heavy rework of the foldertree. It's now based on a new widget "KFolderTree" in libkdenetwork. DnD improvements and fixes by Ingo. svn path=/trunk/kdenetwork/kmail/; revision=163927 --- configuredialog.cpp | 52 +-- configuredialog_p.h | 4 +- kmacctimap.cpp | 2 +- kmfoldertree.cpp | 836 +++++++++++++++++++------------------------- kmfoldertree.h | 166 ++++----- kmheaders.cpp | 81 ++--- kmheaders.h | 46 +-- kmmainwin.cpp | 143 ++++---- kmmainwin.h | 8 +- 9 files changed, 553 insertions(+), 785 deletions(-) diff --git a/configuredialog.cpp b/configuredialog.cpp index ade52d021..80ceff616 100644 --- a/configuredialog.cpp +++ b/configuredialog.cpp @@ -3776,6 +3776,11 @@ MiscPageFoldersTab::MiscPageFoldersTab( QWidget * parent, const char * name ) connect(mDelayedMarkAsRead, SIGNAL(toggled(bool)), mDelayedMarkTime, SLOT(setEnabled(bool))); + // "show popup after Drag'n'Drop" checkbox: stretch 0 + mShowPopupAfterDnD = + new QCheckBox( i18n("Ask for action after dragging messages to another folder"), this ); + vlay->addWidget( mShowPopupAfterDnD ); + // "default mailbox format" combo + label: stretch 0 hlay = new QHBoxLayout( vlay ); // inherits spacing mMailboxPrefCombo = new QComboBox( false, this ); @@ -3791,32 +3796,6 @@ MiscPageFoldersTab::MiscPageFoldersTab( QWidget * parent, const char * name ) hlay->addWidget( label ); hlay->addWidget( mMailboxPrefCombo, 1 ); - vlay->addWidget( new KSeparator( KSeparator::HLine, this ) ); - - // mail Drag'n'Drop actions settings: - mActionWhenDnD = new QVButtonGroup( i18n("In normal mo&de"), this ); - mActionWhenDnD->layout()->setSpacing( KDialog::spacingHint() ); - mActionWhenDnD->insert(new QRadioButton( i18n("Move message"), mActionWhenDnD)); - mActionWhenDnD->insert(new QRadioButton( i18n("Copy message"), mActionWhenDnD)); - mActionWhenDnD->insert(new QRadioButton( i18n("Ask me"), mActionWhenDnD)); - mActionWhenShiftDnD = new QVButtonGroup( i18n("&SHIFT key pressed"), this ); - mActionWhenShiftDnD->layout()->setSpacing( KDialog::spacingHint() ); - mActionWhenShiftDnD->insert(new QRadioButton( i18n("Move message"), mActionWhenShiftDnD)); - mActionWhenShiftDnD->insert(new QRadioButton( i18n("Copy message"), mActionWhenShiftDnD)); - mActionWhenShiftDnD->insert(new QRadioButton( i18n("Ask me"), mActionWhenShiftDnD)); - mActionWhenCtrlDnD = new QVButtonGroup( i18n("CT&RL key pressed"), this ); - mActionWhenCtrlDnD->layout()->setSpacing( KDialog::spacingHint() ); - mActionWhenCtrlDnD->insert(new QRadioButton( i18n("Move message"), mActionWhenCtrlDnD)); - mActionWhenCtrlDnD->insert(new QRadioButton( i18n("Copy message"), mActionWhenCtrlDnD)); - mActionWhenCtrlDnD->insert(new QRadioButton( i18n("Ask me"), mActionWhenCtrlDnD)); - vlay->addWidget( - new QLabel( i18n("On Drag'n'Drop of mail to another folder:"), - this ) ); - hlay = new QHBoxLayout( vlay ); // inherits spacing - hlay->addWidget( mActionWhenDnD ); - hlay->addWidget( mActionWhenShiftDnD ); - hlay->addWidget( mActionWhenCtrlDnD ); - // "On exit..." groupbox: group = new QVGroupBox( i18n("On Program Exit, " "Perform the Following Tasks"), this ); @@ -3870,20 +3849,11 @@ void MiscPage::FoldersTab::setup() { mJumpToUnread->setChecked( behaviour.readBoolEntry( "JumpToUnread", false ) ); mDelayedMarkAsRead->setChecked( behaviour.readBoolEntry( "DelayedMarkAsRead", true ) ); mDelayedMarkTime->setValue( behaviour.readNumEntry( "DelayedMarkTime", 0 ) ); + mShowPopupAfterDnD->setChecked( behaviour.readBoolEntry( "ShowPopupAfterDnD", true ) ); int num = general.readNumEntry("default-mailbox-format", 1 ); if ( num < 0 || num > 1 ) num = 1; mMailboxPrefCombo->setCurrentItem( num ); - - num = behaviour.readNumEntry("DnD_action_normal", KMMsgDnDActionASK ); - if ( num < 0 || num > 2 ) num = KMMsgDnDActionASK; - mActionWhenDnD->setButton( num ); - num = behaviour.readNumEntry("DnD_action_SHIFT", KMMsgDnDActionMOVE ); - if ( num < 0 || num > 2 ) num = KMMsgDnDActionMOVE; - mActionWhenShiftDnD->setButton( num ); - num = behaviour.readNumEntry("DnD_action_CTRL", KMMsgDnDActionCOPY ); - if ( num < 0 || num > 2 ) num = KMMsgDnDActionCOPY; - mActionWhenCtrlDnD->setButton( num ); } void MiscPage::FoldersTab::apply() { @@ -3899,18 +3869,12 @@ void MiscPage::FoldersTab::apply() { behaviour.writeEntry( "JumpToUnread", mJumpToUnread->isChecked() ); behaviour.writeEntry( "DelayedMarkAsRead", mDelayedMarkAsRead->isChecked() ); behaviour.writeEntry( "DelayedMarkTime", mDelayedMarkTime->value() ); + behaviour.writeEntry( "ShowPopupAfterDnD", mShowPopupAfterDnD->isChecked() ); if ( mExpireAtExit->isChecked() ) general.writeEntry( "when-to-expire", expireAtExit ); else general.writeEntry( "when-to-expire", expireManual ); - - behaviour.writeEntry("DnD_action_normal", - mActionWhenDnD->id( mActionWhenDnD->selected() )); - behaviour.writeEntry("DnD_action_SHIFT", - mActionWhenShiftDnD->id( mActionWhenShiftDnD->selected() )); - behaviour.writeEntry("DnD_action_CTRL", - mActionWhenCtrlDnD->id( mActionWhenCtrlDnD->selected() )); } @@ -4707,8 +4671,8 @@ bool PluginPage::isPluginConfigEqual( int pluginno ) const kdDebug(5006) << "29) RET = " << ret << endl; return ret; } - + void PluginPage::savePluginConfig( int pluginno ) { if ( mCryptPlugList->isEmpty() ) diff --git a/configuredialog_p.h b/configuredialog_p.h index d88cf295c..e90b4a16a 100644 --- a/configuredialog_p.h +++ b/configuredialog_p.h @@ -793,9 +793,7 @@ protected: QCheckBox *mExpireAtExit; QCheckBox *mDelayedMarkAsRead; KIntSpinBox *mDelayedMarkTime; - QButtonGroup *mActionWhenDnD; - QButtonGroup *mActionWhenShiftDnD; - QButtonGroup *mActionWhenCtrlDnD; + QCheckBox *mShowPopupAfterDnD; }; class MiscPageAddressbookTab : public ConfigurationPage { diff --git a/kmacctimap.cpp b/kmacctimap.cpp index 8d95d53f5..ae7ff7a41 100644 --- a/kmacctimap.cpp +++ b/kmacctimap.cpp @@ -464,7 +464,7 @@ void KMAcctImap::killJobsForItem(KMFolderTreeItem * fti) QMap::Iterator it = mapJobData.begin(); while (it != mapJobData.end()) { - if (it.data().parent == fti->folder) + if (it.data().parent == fti->folder()) { killAllJobs(); break; diff --git a/kmfoldertree.cpp b/kmfoldertree.cpp index 97911758f..ecf0895fe 100644 --- a/kmfoldertree.cpp +++ b/kmfoldertree.cpp @@ -9,7 +9,6 @@ #include #include #include - #include #include "kmfoldermgr.h" @@ -20,6 +19,7 @@ #include "kmmainwin.h" #include "cryptplugwrapperlist.h" #include + QPixmap* KMFolderTree::pixDir = 0; QPixmap* KMFolderTree::pixNode = 0; QPixmap* KMFolderTree::pixPlain = 0; @@ -30,130 +30,82 @@ QPixmap* KMFolderTree::pixOut = 0; QPixmap* KMFolderTree::pixTr = 0; QPixmap* KMFolderTree::pixSent = 0; -//----------------------------------------------------------------------------- +//============================================================================= -KMFolderTreeItem::~KMFolderTreeItem() +int KMFolderTreeItem::countUnreadRecursive() { + if (mFolder) + return mFolder->countUnreadRecursive(); + else + return 0; } - -// Begin this code may be relicensed by Troll Tech - -void KMFolderTreeItem::paintCell( QPainter * p, const QColorGroup & cg, - int column, int width, int align ) +//----------------------------------------------------------------------------- +bool KMFolderTreeItem::acceptDrag(QDropEvent*) const { - if ( !p ) - return; - - QListView *lv = listView(); - int r = lv ? lv->itemMargin() : 1; - const QPixmap *icon = pixmap( column ); - int marg = lv ? lv->itemMargin() : 1; - - if (!mPaintInfo->pixmapOn) - p->fillRect( 0, 0, width, height(), cg.base() ); - - if ( isSelected() && - (column==0 || listView()->allColumnsShowFocus()) ) { - p->fillRect( r - marg, 0, width - r + marg, height(), - cg.brush( QColorGroup::Highlight ) ); - p->setPen( cg.highlightedText() ); - } else { - p->setPen( mPaintInfo->colFore ); - } - - if ( icon ) { - p->drawPixmap( r, (height()-icon->height())/2, *icon ); - r += icon->width() + listView()->itemMargin(); - } + if ( !mFolder || + (mFolder->noContent() && childCount() == 0) || + (mFolder->noContent() && isOpen()) ) + return false; + else + return true; +} - QString t = text( column ); - if ( !t.isEmpty() ) { - // use a bold-font for the folder- and the unread-columns - if ( folder && (folder->countUnreadRecursive() > 0) && - (column == 0 || column == static_cast(listView())->getUnreadColumIndex()) ) - { - QFont f = p->font(); - f.setWeight(QFont::Bold); - p->setFont(f); - } - QRect br; - p->drawText( r, 0, width-marg-r, height(), - align | AlignVCenter, t, -1, &br ); - if (!isSelected()) - p->setPen( mPaintInfo->colUnread ); - if (column == 0) - p->drawText( br.right(), 0, width-marg-br.right(), height(), - align | AlignVCenter, unread ); - } -} -// End this code may be relicensed by Troll Tech +//============================================================================= -//----------------------------------------------------------------------------- -// Implement the sorting of the folders -QString KMFolderTreeItem::key(int column, bool) const +KMFolderTree::KMFolderTree( CryptPlugWrapperList * cryptPlugList, + QWidget *parent, + const char *name ) + : KFolderTree( parent, name ), mCryptPlugList( cryptPlugList ) { - if (column > 0) return text(column); + static bool pixmapsLoaded = FALSE; + oldSelected = 0; + oldCurrent = 0; + mLastItem = NULL; - // root-folder - if (!folder) - return "\t6" + text(0).lower(); + addAcceptableDropMimetype("x-kmail-drag/message", false); - // make sure system folders come first when sorting - if (folder->isSystemFolder()) + addColumn( i18n("Folder"), 160 ); + + if (!pixmapsLoaded) { - if (folder->label() == i18n("inbox")) - return "\t0"; - if (folder->label() == i18n("outbox")) - return "\t1"; - if (folder->label() == i18n("sent-mail")) - return "\t2"; - if (folder->label() == i18n("trash")) - return "\t3"; - if (folder->label() == i18n("drafts")) - return "\t4"; + pixmapsLoaded = true; + + pixDir = new QPixmap( UserIcon("closed")); + pixNode = new QPixmap( UserIcon("green-bullet")); + pixPlain = new QPixmap( SmallIcon("folder")); + pixFld = new QPixmap( SmallIcon("folder")); + pixFull = new QPixmap( SmallIcon("folder_open")); + pixIn = new QPixmap( UserIcon("kmfldin")); + pixOut = new QPixmap( UserIcon("kmfldout")); + pixSent = new QPixmap( UserIcon("kmfldsent")); + pixTr = new QPixmap( SmallIcon("trashcan_empty")); } - // then all other local mail-folders - if (folder->protocol() != "imap") - return "\t5" + folder->label(); + // connect + connectSignals(); - // the imap-folders - if (folder->protocol() == "imap") - return "\t6" + folder->label(); + // 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())); - // fallback - return text(0).lower(); -} + // add the folders + reload(); -//----------------------------------------------------------------------------- -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); - } + // read the config + readConfig(); + + // get rid of old-folders + cleanupConfigFile(); } //----------------------------------------------------------------------------- -//----------------------------------------------------------------------------- - void KMFolderTree::drawContentsOffset( QPainter * p, int ox, int oy, int cx, int cy, int cw, int ch ) { @@ -161,71 +113,31 @@ void KMFolderTree::drawContentsOffset( QPainter * p, int ox, int oy, if (mPaintInfo.pixmapOn) paintEmptyArea( p, QRect( c - ox, cy - oy, cx + cw - c, ch ) ); - QListView::drawContentsOffset( p, ox, oy, cx, cy, cw, ch ); + KFolderTree::drawContentsOffset( p, ox, oy, cx, cy, cw, ch ); } - //----------------------------------------------------------------------------- -KMFolderTree::KMFolderTree( CryptPlugWrapperList * cryptPlugList, - QWidget *parent, - const char *name ) - : QListView( parent, name ), mList(), mCryptPlugList( cryptPlugList ) +// connects all needed signals to their slots +void KMFolderTree::connectSignals() { - static bool pixmapsLoaded = FALSE; - 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())); + connect(this, SIGNAL(currentChanged(QListViewItem*)), this, SLOT(doFolderSelected(QListViewItem*))); + connect(kernel->folderMgr(), SIGNAL(changed()), this, SLOT(doFolderListChanged())); + connect(kernel->folderMgr(), SIGNAL(removed(KMFolder*)), this, SLOT(slotFolderRemoved(KMFolder*))); + connect(kernel->imapFolderMgr(), SIGNAL(changed()), this, SLOT(doFolderListChanged())); + connect(kernel->imapFolderMgr(), SIGNAL(removed(KMFolder*)), this, SLOT(slotFolderRemoved(KMFolder*))); - readConfig(); - - addColumn( i18n("Folder"), 400 ); - - if (!pixmapsLoaded) - { - pixmapsLoaded = TRUE; - - pixDir = new QPixmap( UserIcon("closed")); - pixNode = new QPixmap( UserIcon("green-bullet")); - pixPlain = new QPixmap( SmallIcon("folder")); - pixFld = new QPixmap( SmallIcon("folder")); - pixFull = new QPixmap( SmallIcon("folder_open")); - pixIn = new QPixmap( UserIcon("kmfldin")); - pixOut = new QPixmap( UserIcon("kmfldout")); - pixSent = new QPixmap( UserIcon("kmfldsent")); - pixTr = new QPixmap( SmallIcon("trashcan_empty")); - } - setUpdatesEnabled(TRUE); - reload(); - cleanupConfigFile(); - - /** Drag and drop hover opening and autoscrolling support */ - setAcceptDrops( TRUE ); - viewport()->setAcceptDrops( TRUE ); - connect( &autoopen_timer, SIGNAL( timeout() ), this, SLOT( openFolder() ) ); @@ -237,20 +149,12 @@ KMFolderTree::KMFolderTree( CryptPlugWrapperList * cryptPlugList, connect( this, SIGNAL( mouseButtonPressed( int, QListViewItem*, const QPoint &, int)), this, SLOT( mouseButtonPressed( int, QListViewItem*, const QPoint &, int))); + connect( this, SIGNAL( expanded( QListViewItem* ) ), 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())); } //----------------------------------------------------------------------------- @@ -261,7 +165,7 @@ bool KMFolderTree::event(QEvent *e) readColorConfig(); return true; } - return QListView::event(e); + return KListView::event(e); } //----------------------------------------------------------------------------- @@ -274,7 +178,7 @@ void KMFolderTree::createFolderList(QStringList *str, while (it.current()) { fti = static_cast(it.current()); - if (fti && fti->folder) + if (fti && fti->folder()) { fti2 = static_cast(fti->parent()); prefix = ""; @@ -284,8 +188,8 @@ void KMFolderTree::createFolderList(QStringList *str, prefix += " "; } str->append(prefix + fti->text(0)); - if (fti->folder->noContent()) folders->append(NULL); - else folders->append(fti->folder); + if (fti->folder()->noContent()) folders->append(NULL); + else folders->append(fti->folder()); } ++it; } @@ -300,9 +204,9 @@ void KMFolderTree::createImapFolderList(KMFolderImap *aFolder, QStringList *name while (it.current()) { fti = static_cast(it.current()); - if (fti && fti->folder) + if (fti && fti->folder()) { - KMFolderImap *folder = static_cast(fti->folder); + KMFolderImap *folder = static_cast(fti->folder()); if (folder == aFolder) { names->append(fti->text(0)); @@ -371,24 +275,29 @@ void KMFolderTree::readConfig (void) setFont(KGlobalSettings::generalFont()); } - // read D'n'D behavior settings - { //area for config group "Behaviour" - KConfigGroupSaver saver(conf, "Behaviour"); - mActionWhenDnD = conf->readNumEntry("DnD_action_normal", KMMsgDnDActionASK ); - if ( mActionWhenDnD < 0 || mActionWhenDnD > 2 ) - mActionWhenDnD = KMMsgDnDActionASK; - mActionWhenShiftDnD = conf->readNumEntry("DnD_action_SHIFT", KMMsgDnDActionMOVE ); - if ( mActionWhenShiftDnD < 0 || mActionWhenShiftDnD > 2 ) - mActionWhenShiftDnD = KMMsgDnDActionMOVE; - mActionWhenCtrlDnD = conf->readNumEntry("DnD_action_CTRL", KMMsgDnDActionCOPY ); - if ( mActionWhenCtrlDnD < 0 || mActionWhenCtrlDnD > 2 ) - mActionWhenCtrlDnD = KMMsgDnDActionCOPY; - } + // read D'n'D behaviour setting + KConfigGroup behaviour( kapp->config(), "Behaviour" ); + mShowPopupAfterDnD = behaviour.readBoolEntry( "ShowPopupAfterDnD", true ); + + // restore the layout + restoreLayout(conf, "Geometry"); } //----------------------------------------------------------------------------- -KMFolderTree::~KMFolderTree() +// Save the configuration file +void KMFolderTree::writeConfig() { + // save the current state of the folders + QListViewItemIterator it( this ); + while (it.current()) { + KMFolderTreeItem* fti = static_cast(it.current()); + if (fti) + writeIsListViewItemOpen(fti); + ++it; + } + + // save the current layout + saveLayout(kapp->config(), "Geometry"); } //----------------------------------------------------------------------------- @@ -433,20 +342,6 @@ void KMFolderTree::paintEmptyArea( QPainter * p, const QRect & rect ) p->fillRect( rect, colorGroup().base() ); } - -//----------------------------------------------------------------------------- -// Save the configuration file -void KMFolderTree::writeConfig() -{ - QListViewItemIterator it( this ); - while (it.current()) { - KMFolderTreeItem* fti = static_cast(it.current()); - if (fti) - writeIsListViewItemOpen(fti); - ++it; - } -} - //----------------------------------------------------------------------------- // Reload the tree of items in the list view void KMFolderTree::reload(bool openFolders) @@ -455,30 +350,28 @@ void KMFolderTree::reload(bool openFolders) QString str; int top = contentsY(); - writeConfig(); - KMFolderTreeItem* fti = static_cast(currentItem()); mLastItem = NULL; QListViewItemIterator it( this ); while (it.current()) { fti = static_cast(it.current()); - if (fti && fti->folder) - disconnect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)), + if (fti && fti->folder()) + disconnect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)), this,SLOT(refresh(KMFolder*))); ++it; } clear(); - // We need our own root so that we can make it a KMFolderTreeItem - // and use our custom paintBranches - root = new KMFolderTreeItem( this, &mPaintInfo ); - root->setOpen( TRUE ); + // construct the root of the local folders + root = new KMFolderTreeItem( this, i18n("Local Folders") ); + root->setOpen( true ); fdir = &kernel->folderMgr()->dir(); addDirectory(fdir, root); fdir = &kernel->imapFolderMgr()->dir(); - addDirectory(fdir, root); + // each imap-account creates it's own root + addDirectory(fdir, NULL); if (openFolders) { @@ -492,39 +385,42 @@ void KMFolderTree::reload(bool openFolders) while (jt.current()) { KMFolderTreeItem* fti = static_cast(jt.current()); - if (fti && fti->folder) + if (fti && fti->folder()) { - // first disconnect before each connect to make sure we don't call it twice - disconnect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)), + // first disconnect before each connect + // to make sure we don't call it several times with each reload + disconnect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)), this,SLOT(refresh(KMFolder*))); - connect(fti->folder,SIGNAL(numUnreadMsgsChanged(KMFolder*)), + connect(fti->folder(),SIGNAL(numUnreadMsgsChanged(KMFolder*)), this,SLOT(refresh(KMFolder*))); - if (totalIsActive || unreadIsActive) + if (isTotalActive() || isUnreadActive()) { // we want to be noticed of changes to update the unread/total columns - disconnect(fti->folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), + disconnect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)), this,SLOT(slotUpdateCounts(KMFolder*))); - connect(fti->folder, SIGNAL(numUnreadMsgsChanged(KMFolder*)), + connect(fti->folder(), SIGNAL(numUnreadMsgsChanged(KMFolder*)), this,SLOT(slotUpdateCounts(KMFolder*))); - if (fti->folder->protocol() == "imap") + if (fti->folder()->protocol() == "imap") { // imap-only - disconnect(fti->folder, SIGNAL(folderComplete(KMFolderImap*, bool)), + disconnect(fti->folder(), SIGNAL(folderComplete(KMFolderImap*, bool)), this,SLOT(slotUpdateCounts(KMFolderImap*, bool))); - connect(fti->folder, SIGNAL(folderComplete(KMFolderImap*, bool)), + connect(fti->folder(), SIGNAL(folderComplete(KMFolderImap*, bool)), this,SLOT(slotUpdateCounts(KMFolderImap*, bool))); + } else { + // others-only, imap doesn't need this because of the folderComplete-signal + disconnect(fti->folder(), SIGNAL(msgAdded(KMFolder*)), + this,SLOT(slotUpdateCounts(KMFolder*))); + connect(fti->folder(), SIGNAL(msgAdded(KMFolder*)), + this,SLOT(slotUpdateCounts(KMFolder*))); } - disconnect(fti->folder, SIGNAL(msgRemoved(KMFolder*)), - this,SLOT(slotUpdateCounts(KMFolder*))); - connect(fti->folder, SIGNAL(msgRemoved(KMFolder*)), + disconnect(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*)), + connect(fti->folder(), SIGNAL(msgRemoved(KMFolder*)), this,SLOT(slotUpdateCounts(KMFolder*))); } if (!openFolders) - slotUpdateCounts(fti->folder); + slotUpdateCounts(fti->folder()); } ++jt; } @@ -538,26 +434,25 @@ void KMFolderTree::slotUpdateOneCount() if ( !mUpdateIterator.current() ) return; KMFolderTreeItem* fti = static_cast(mUpdateIterator.current()); ++mUpdateIterator; - if ( !fti->folder ) { + 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); + bool open = fti->folder()->isOpened(); + if (!open) fti->folder()->open(); + slotUpdateCounts(fti->folder()); // restore previous state - if (!open) fti->folder->close(); + 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 ) +void KMFolderTree::addDirectory( KMFolderDir *fdir, KMFolderTreeItem* parent ) { KMFolderNode *folderNode; KMFolder* folder; @@ -566,11 +461,23 @@ void KMFolderTree::addDirectory( KMFolderDir *fdir, QListViewItem* parent ) for (folderNode = fdir->first(); folderNode != NULL; folderNode = fdir->next()) + { if (!folderNode->isDir()) { folder = static_cast(folderNode); - Q_ASSERT(parent); - fti = new KMFolderTreeItem( parent, folder, &mPaintInfo ); - + if (!parent) + { + // create new root-item + // it needs a folder e.g. to save it's state (open/close) + fti = new KMFolderTreeItem( this, folder->label(), folder ); + fti->setExpandable( true ); + } else { + // create new child + fti = new KMFolderTreeItem( parent, folder->label(), folder ); + } + // restore last open-state + fti->setOpen( readIsListViewItemOpen(fti) ); + + // assign icons if (folder->isSystemFolder()) { if (folder->label() == i18n("inbox")) @@ -585,15 +492,15 @@ void KMFolderTree::addDirectory( KMFolderDir *fdir, QListViewItem* parent ) fti->setPixmap( 0, *pixPlain ); } else fti->setPixmap( 0, (folder->normalIcon()) ? *(folder->normalIcon()) : (*pixPlain) ); - if (fti->folder && fti->folder->child()) - addDirectory( fti->folder->child(), fti ); - if (fti->folder && fti->folder->protocol() == "imap" && parent && - !parent->parent()) fti->setExpandable( TRUE ); - fti->setOpen( readIsListViewItemOpen(fti) ); + // add child-folders + if (folder && folder->child()) + addDirectory( folder->child(), fti ); // make sure that the folder-settings are correctly read on startup by calling listDirectory - if (readIsListViewItemOpen(fti) && fti->folder->protocol() == "imap") + if (readIsListViewItemOpen(fti) && + folder && fti->folder()->protocol() == "imap") slotFolderExpanded(fti); } + } // for-end } //----------------------------------------------------------------------------- @@ -618,36 +525,27 @@ void KMFolderTree::delayedUpdate() while (it.current()) { bool repaintRequired = false; KMFolderTreeItem* fti = static_cast(it.current()); - if (!fti || !fti->folder) { + if (!fti || !fti->folder()) { ++it; continue; } - QString extendedName, num; - if (fti->folder->countUnread() > 0) { - 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)) ); + int count = fti->folder()->countUnread(); + if (count != fti->unreadCount()) + repaintRequired = true; + fti->setUnreadCount(count); + if (count > 0) { + if (!fti->folder()->isSystemFolder()) + fti->setPixmap( 0, ((fti->folder()->unreadIcon()) ? *(fti->folder()->unreadIcon()) : (*pixFull)) ); } else { - extendedName = ""; - if (!fti->folder->isSystemFolder()) - fti->setPixmap( 0, ((fti->folder->normalIcon()) ? *(fti->folder->normalIcon()) : (*pixPlain)) ); + if (!fti->folder()->isSystemFolder()) + fti->setPixmap( 0, ((fti->folder()->normalIcon()) ? *(fti->folder()->normalIcon()) : (*pixPlain)) ); } - if (extendedName != fti->unread) { + if ( fti->folder()->needsRepainting() ) { repaintRequired = true; - fti->unread = extendedName; - } - if ( fti->folder->needsRepainting() ) { - repaintRequired = true; - fti->folder->repaintScheduled(); + fti->folder()->repaintScheduled(); } if (upd && repaintRequired) @@ -663,7 +561,7 @@ void KMFolderTree::delayedUpdate() void KMFolderTree::doFolderListChanged() { KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >(currentItem()); - KMFolder* folder = (fti) ? fti->folder : NULL; + KMFolder* folder = (fti) ? fti->folder() : NULL; reload(); QListViewItem *qlvi = indexOfFolder(folder); if (qlvi) { @@ -677,7 +575,7 @@ void KMFolderTree::slotFolderRemoved(KMFolder *aFolder) { KMFolderTreeItem *fti = static_cast (indexOfFolder(aFolder)); - if (!fti || !fti->folder) return; + if (!fti || !fti->folder()) return; if (fti == currentItem()) { QListViewItem *qlvi = fti->itemAbove(); @@ -687,16 +585,8 @@ void KMFolderTree::slotFolderRemoved(KMFolder *aFolder) delete fti; } -//----------------------------------------------------------------------------- -void KMFolderTree::setSelected( QListViewItem *i, bool select ) -{ - clearSelection(); - QListView::setSelected( i, select ); -} - //----------------------------------------------------------------------------- // Methods for navigating folders with the keyboard - void KMFolderTree::prepareItem( KMFolderTreeItem* fti ) { QListViewItem *parent = fti->parent(); @@ -707,11 +597,13 @@ void KMFolderTree::prepareItem( KMFolderTreeItem* fti ) ensureItemVisible( fti ); } +//----------------------------------------------------------------------------- void KMFolderTree::nextUnreadFolder() { nextUnreadFolder( false ); } +//----------------------------------------------------------------------------- void KMFolderTree::nextUnreadFolder(bool confirm) { //Set iterator to the current folder @@ -737,14 +629,15 @@ void KMFolderTree::nextUnreadFolder(bool confirm) } } +//----------------------------------------------------------------------------- bool KMFolderTree::checkUnreadFolder (KMFolderTreeItem* fti, bool confirm) { - if (fti && fti->folder && - (fti->folder->countUnread() > 0)) { + if (fti && fti->folder() && + (fti->folder()->countUnread() > 0)) { if ( confirm ) { // If confirm is true then we are doing "ReadOn" and we want to miss // Out the trash folder - if (fti->folder->label() == i18n("trash")) + if (fti->folder()->label() == i18n("trash")) return false; else { // warn user that going to next folder - but keep track of @@ -752,7 +645,7 @@ bool KMFolderTree::checkUnreadFolder (KMFolderTreeItem* fti, bool confirm) // parameter (kept in the config file for kmail) if ( KMessageBox::questionYesNo( this, i18n( "Go to the next unread message in folder %1?" ) - .arg( fti->folder->label() ), + .arg( fti->folder()->label() ), i18n( "Go to the Next Unread Message" ), KStdGuiItem::yes(), KStdGuiItem::no(), // defaults "AskNextFolder", @@ -764,12 +657,13 @@ bool KMFolderTree::checkUnreadFolder (KMFolderTreeItem* fti, bool confirm) blockSignals( true ); doFolderSelected( fti ); blockSignals( false ); - emit folderSelectedUnread( fti->folder ); + emit folderSelectedUnread( fti->folder() ); return true; } return false; } +//----------------------------------------------------------------------------- void KMFolderTree::prevUnreadFolder() { QListViewItemIterator it( currentItem() ); @@ -777,7 +671,7 @@ void KMFolderTree::prevUnreadFolder() while (it.current()) { --it; KMFolderTreeItem* fti = static_cast(it.current()); - if (fti && fti->folder && (fti->folder->countUnread() > 0)) { + if (fti && fti->folder() && (fti->folder()->countUnread() > 0)) { prepareItem( fti ); doFolderSelected( fti ); return; @@ -785,12 +679,13 @@ void KMFolderTree::prevUnreadFolder() } } +//----------------------------------------------------------------------------- void KMFolderTree::incCurrentFolder() { QListViewItemIterator it( currentItem() ); ++it; KMFolderTreeItem* fti = static_cast(it.current()); - if (fti && fti->folder) { + if (fti && fti->folder()) { prepareItem( fti ); disconnect(this,SIGNAL(currentChanged(QListViewItem*)), this,SLOT(doFolderSelected(QListViewItem*))); @@ -801,12 +696,13 @@ void KMFolderTree::incCurrentFolder() } } +//----------------------------------------------------------------------------- void KMFolderTree::decCurrentFolder() { QListViewItemIterator it( currentItem() ); --it; KMFolderTreeItem* fti = static_cast(it.current()); - if (fti && fti->folder) { + if (fti && fti->folder()) { prepareItem( fti ); disconnect(this,SIGNAL(currentChanged(QListViewItem*)), this,SLOT(doFolderSelected(QListViewItem*))); @@ -817,20 +713,22 @@ void KMFolderTree::decCurrentFolder() } } +//----------------------------------------------------------------------------- void KMFolderTree::selectCurrentFolder() { KMFolderTreeItem* fti = static_cast( currentItem() ); - if (fti && fti->folder) { + if (fti && fti->folder()) { prepareItem( fti ); doFolderSelected( fti ); } } +//----------------------------------------------------------------------------- KMFolder *KMFolderTree::currentFolder() const { KMFolderTreeItem* fti = static_cast( currentItem() ); if (fti ) - return fti->folder; + return fti->folder(); else return 0; } @@ -843,12 +741,12 @@ void KMFolderTree::doFolderSelected( QListViewItem* qlvi ) { KMFolderTreeItem* fti = static_cast< KMFolderTreeItem* >(qlvi); KMFolder* folder = 0; - if (fti) folder = fti->folder; + if (fti) folder = fti->folder(); - if (mLastItem && mLastItem != fti && mLastItem->folder - && (mLastItem->folder->protocol() == "imap")) + if (mLastItem && mLastItem != fti && mLastItem->folder() + && (mLastItem->folder()->protocol() == "imap")) { - KMFolderImap *imapFolder = static_cast(mLastItem->folder); + KMFolderImap *imapFolder = static_cast(mLastItem->folder()); imapFolder->setSelected(FALSE); KMAcctImap *act = imapFolder->account(); if (act) @@ -869,12 +767,13 @@ void KMFolderTree::doFolderSelected( QListViewItem* qlvi ) emit folderSelected(folder); if (folder->protocol() == "imap") { - KMFolderImap *imap_folder = static_cast(fti->folder); + KMFolderImap *imap_folder = static_cast(fti->folder()); imap_folder->setSelected(TRUE); if (imap_folder->getContentState() != KMFolderImap::imapInProgress) imap_folder->getFolder(); } else { - // we don't need this for imap-folders because they're updated with the folderComplete-signal + // we don't need this for imap-folders because + // they're updated with the folderComplete-signal slotUpdateCounts(folder); } } @@ -888,15 +787,16 @@ void KMFolderTree::resizeEvent(QResizeEvent* e) KConfigGroupSaver saver(conf, "Geometry"); conf->writeEntry(name(), size().width()); - KMFolderTreeInherited::resizeEvent(e); + KListView::resizeEvent(e); } + //----------------------------------------------------------------------------- QListViewItem* KMFolderTree::indexOfFolder(const KMFolder* folder) { QListViewItemIterator it( this ); while (it.current()) { KMFolderTreeItem* fti = static_cast(it.current()); - if (fti && fti->folder == folder) { + if (fti && fti->folder() == folder) { return it.current(); } ++it; @@ -921,29 +821,33 @@ void KMFolderTree::rightButtonPressed(QListViewItem *lvi, const QPoint &p, int) return; KPopupMenu *folderMenu = new KPopupMenu; - if (fti->folder) folderMenu->insertTitle(fti->folder->label()); + if (fti->folder()) folderMenu->insertTitle(fti->folder()->label()); - if ((!fti->folder || (fti->folder->noContent() - && fti->parent() == firstChild()))) + if ((!fti->folder() || (fti->folder()->noContent() + && !fti->parent()))) { + QString createChild = i18n("&Create Child Folder..."); + if (!fti->folder()) createChild = i18n("&Create Folder..."); + folderMenu->insertItem(SmallIcon("folder_new"), - i18n("&Create Child Folder..."), this, + createChild, this, SLOT(addChildFolder())); - if (!fti->folder) { + if (!fti->folder()) { folderMenu->insertItem(i18n("Compact All &Folders"), kernel->folderMgr(), SLOT(compactAll())); folderMenu->insertItem(i18n("Expire All Folders"), kernel->folderMgr(), SLOT(expireAll())); - } else if (fti->folder->protocol() == "imap") + } else if (fti->folder()->protocol() == "imap") { folderMenu->insertItem(SmallIcon("mail_get"), i18n("Check &Mail"), - static_cast(fti->folder)->account(), + static_cast(fti->folder())->account(), SLOT(processNewMail())); + } } else { - if ((fti->folder == kernel->outboxFolder()) && (fti->folder->count()) ) + if ((fti->folder() == kernel->outboxFolder()) && (fti->folder()->count()) ) folderMenu->insertItem(SmallIcon("mail_send"), i18n("Send Queued"), topLevelWidget(), SLOT(slotSendQueued())); - if (!fti->folder->isSystemFolder() || fti->folder->protocol() == "imap") + if (!fti->folder()->isSystemFolder() || fti->folder()->protocol() == "imap") { folderMenu->insertItem(SmallIcon("folder_new"), i18n("&Create Child Folder..."), this, @@ -953,30 +857,30 @@ void KMFolderTree::rightButtonPressed(QListViewItem *lvi, const QPoint &p, int) // Want to be able to display properties for ALL folders, // so we can edit expiry properties. // -- smp. - if (!fti->folder->noContent()) + if (!fti->folder()->noContent()) { folderMenu->insertItem(i18n("&Properties..."), topLevelWidget(), SLOT(slotModifyFolder())); - if (fti->folder->protocol() != "imap" && fti->folder->isAutoExpire()) + if (fti->folder()->protocol() != "imap" && fti->folder()->isAutoExpire()) folderMenu->insertItem(i18n("E&xpire"), topLevelWidget(), SLOT(slotExpireFolder())); folderMenu->insertItem(i18n("C&ompact"), topLevelWidget(), SLOT(slotCompactFolder())); folderMenu->insertSeparator(); - if (fti->folder->countUnread() > 0) + if (fti->folder()->countUnread() > 0) folderMenu->insertItem(SmallIcon("goto"), i18n("&Mark All Messages as Read"), topLevelWidget(), SLOT(slotMarkAllAsRead())); folderMenu->insertItem(i18n("&Empty"), topLevelWidget(), SLOT(slotEmptyFolder())); } - if ( !fti->folder->isSystemFolder() ) + if ( !fti->folder()->isSystemFolder() ) folderMenu->insertItem(i18n("&Remove"), topLevelWidget(), SLOT(slotRemoveFolder())); - if (!fti->folder->noContent() && fti->folder->isMailingList()) + if (!fti->folder()->noContent() && fti->folder()->isMailingList()) { folderMenu->insertSeparator(); folderMenu->insertItem(i18n("Post to &Mailing-List"), @@ -991,7 +895,6 @@ void KMFolderTree::rightButtonPressed(QListViewItem *lvi, const QPoint &p, int) //----------------------------------------------------------------------------- // If middle button and folder holds mailing-list, create a message to that list - void KMFolderTree::mouseButtonPressed(int btn, QListViewItem *lvi, const QPoint &, int) { // react on middle-button only @@ -1000,15 +903,15 @@ void KMFolderTree::mouseButtonPressed(int btn, QListViewItem *lvi, const QPoint // get underlying folder KMFolderTreeItem* fti = dynamic_cast(lvi); - if (!fti || !fti->folder) + if (!fti || !fti->folder()) return; - if (!fti->folder->isMailingList()) + if (!fti->folder()->isMailingList()) return; KMMessage *msg = new KMMessage; - msg->initHeader(fti->folder->identity()); - msg->setTo(fti->folder->mailingListPostAddress()); - KMComposeWin *win = new KMComposeWin(mCryptPlugList, msg, fti->folder->identity()); + msg->initHeader(fti->folder()->identity()); + msg->setTo(fti->folder()->mailingListPostAddress()); + KMComposeWin *win = new KMComposeWin(mCryptPlugList, msg, fti->folder()->identity()); win->show(); } @@ -1021,14 +924,14 @@ void KMFolderTree::addChildFolder() KMFolderTreeItem *fti = static_cast(currentItem()); if (!fti) return; - KMFolder *aFolder = fti->folder; - if (fti->folder) - if (!fti->folder->createChildFolder()) + KMFolder *aFolder = fti->folder(); + if (fti->folder()) + if (!fti->folder()->createChildFolder()) return; KMFolderDir *dir = &(kernel->folderMgr()->dir()); - if (fti->folder) - dir = fti->folder->child(); + if (fti->folder()) + dir = fti->folder()->child(); KMFolderDialog *d = new KMFolderDialog(0, dir, topLevelWidget(), i18n("Create Child Folder") ); @@ -1056,7 +959,7 @@ void KMFolderTree::addChildFolder() bool KMFolderTree::readIsListViewItemOpen(KMFolderTreeItem *fti) { KConfig* config = kapp->config(); - KMFolder *folder = fti->folder; + KMFolder *folder = fti->folder(); if (!folder) return TRUE; KConfigGroupSaver saver(config, "Folder-" + folder->idString()); @@ -1069,7 +972,7 @@ bool KMFolderTree::readIsListViewItemOpen(KMFolderTreeItem *fti) void KMFolderTree::writeIsListViewItemOpen(KMFolderTreeItem *fti) { KConfig* config = kapp->config(); - KMFolder *folder = fti->folder; + KMFolder *folder = fti->folder(); if (!folder) return; KConfigGroupSaver saver(config, "Folder-" + folder->idString()); @@ -1088,8 +991,8 @@ void KMFolderTree::cleanupConfigFile() for (QListViewItemIterator fldIt(this); fldIt.current(); fldIt++) { fti = static_cast(fldIt.current()); - if (fti && fti->folder) - folderMap.insert(fti->folder->idString(), fti->isExpandable()); + if (fti && fti->folder()) + folderMap.insert(fti->folder()->idString(), fti->isExpandable()); } QStringList groupList = config->groupList(); QString name; @@ -1116,6 +1019,7 @@ enum { DRAG_CANCEL = 2 }; +//----------------------------------------------------------------------------- void KMFolderTree::openFolder() { autoopen_timer.stop(); @@ -1127,14 +1031,11 @@ void KMFolderTree::openFolder() static const int autoopenTime = 750; +//----------------------------------------------------------------------------- void KMFolderTree::contentsDragEnterEvent( QDragEnterEvent *e ) { oldCurrent = 0; oldSelected = 0; - if ( !KMHeaderToFolderDrag::canDecode(e) ) { - e->ignore(); - return; - } oldCurrent = currentItem(); QListViewItemIterator it( this ); @@ -1152,12 +1053,17 @@ void KMFolderTree::contentsDragEnterEvent( QDragEnterEvent *e ) } disconnect(this, SIGNAL(currentChanged(QListViewItem*)), this, SLOT(doFolderSelected(QListViewItem*))); + + if ( !acceptDrag(e) ) { + e->ignore(); + } } static const int autoscroll_margin = 16; static const int initialScrollTime = 30; static const int initialScrollAccel = 5; +//----------------------------------------------------------------------------- void KMFolderTree::startAutoScroll() { if ( !autoscroll_timer.isActive() ) { @@ -1167,11 +1073,13 @@ void KMFolderTree::startAutoScroll() } } +//----------------------------------------------------------------------------- void KMFolderTree::stopAutoScroll() { autoscroll_timer.stop(); } +//----------------------------------------------------------------------------- void KMFolderTree::autoScroll() { QPoint p = viewport()->mapFromGlobal( QCursor::pos() ); @@ -1201,13 +1109,9 @@ void KMFolderTree::autoScroll() } } +//----------------------------------------------------------------------------- void KMFolderTree::contentsDragMoveEvent( QDragMoveEvent *e ) { - if ( !KMHeaderToFolderDrag::canDecode(e) ) { - e->ignore(); - return; - } - QPoint vp = contentsToViewport(e->pos()); QRect inside_margin((contentsX() > 0) ? autoscroll_margin : 0, (contentsY() > 0) ? autoscroll_margin : 0, @@ -1217,30 +1121,39 @@ void KMFolderTree::contentsDragMoveEvent( QDragMoveEvent *e ) ? autoscroll_margin*2 : 0)); QListViewItem *i = itemAt( vp ); if ( i ) { - setCurrentItem( i ); + if ( acceptDrag(e) ) { + setCurrentItem( i ); + } if ( !inside_margin.contains(vp) ) { startAutoScroll(); e->accept(QRect(0,0,0,0)); // Keep sending move events autoopen_timer.stop(); } else { - e->accept(); + if ( acceptDrag(e) ) { + e->accept(); + } + else { + e->ignore(); + } if ( i != dropItem ) { autoopen_timer.stop(); dropItem = i; autoopen_timer.start( autoopenTime ); } } - switch ( e->action() ) { - case QDropEvent::Copy: - break; - case QDropEvent::Move: - e->acceptAction(); - break; - case QDropEvent::Link: - e->acceptAction(); - break; - default: - ; + if ( acceptDrag(e) ) { + switch ( e->action() ) { + case QDropEvent::Copy: + break; + case QDropEvent::Move: + e->acceptAction(); + break; + case QDropEvent::Link: + e->acceptAction(); + break; + default: + ; + } } } else { e->ignore(); @@ -1249,6 +1162,7 @@ void KMFolderTree::contentsDragMoveEvent( QDragMoveEvent *e ) } } +//----------------------------------------------------------------------------- void KMFolderTree::contentsDragLeaveEvent( QDragLeaveEvent * ) { if (!oldCurrent) return; @@ -1264,64 +1178,56 @@ void KMFolderTree::contentsDragLeaveEvent( QDragLeaveEvent * ) this, SLOT(doFolderSelected(QListViewItem*))); } +//----------------------------------------------------------------------------- void KMFolderTree::contentsDropEvent( QDropEvent *e ) { autoopen_timer.stop(); stopAutoScroll(); QListViewItem *item = itemAt( contentsToViewport(e->pos()) ); - if ( item ) { - QString str; - KMFolderTreeItem *fti = static_cast(item); - if (fti && (fti != oldSelected) && (fti->folder)) - { - int root_x, root_y, win_x, win_y; - uint keybstate; - Window rootw, childw; - XQueryPointer( qt_xdisplay(), qt_xrootwin(), &rootw, &childw, - &root_x, &root_y, &win_x, &win_y, &keybstate ); - - int actionSettings; - if ( keybstate & ControlMask ) - actionSettings = mActionWhenCtrlDnD; - else if ( keybstate & ShiftMask ) - actionSettings = mActionWhenShiftDnD; - else - actionSettings = mActionWhenDnD; - - switch ( actionSettings ) { - case KMMsgDnDActionMOVE: - emit folderDrop(fti->folder); - break; - case KMMsgDnDActionCOPY: - emit folderDropCopy(fti->folder); - break; - default: { - KPopupMenu *menu = new KPopupMenu( this ); - menu->insertItem( i18n("Move"), DRAG_MOVE, 0 ); - menu->insertItem( i18n("Copy"), DRAG_COPY, 1 ); - menu->insertSeparator(); - menu->insertItem( i18n("Cancel"), DRAG_CANCEL, 3 ); - int id = menu->exec( QCursor::pos(), 0 ); - switch(id) { - case DRAG_COPY: - emit folderDropCopy(fti->folder); - break; - case DRAG_MOVE: - emit folderDrop(fti->folder); - break; - case DRAG_CANCEL: - //just chill, doing nothing - break; - default: - kdDebug(5006)<<"## This should never happen! ##"<ignore(); + + KMFolderTreeItem *fti = static_cast(item); + if (fti && (fti != oldSelected) && (fti->folder())) + { + int root_x, root_y, win_x, win_y; + uint keybstate; + Window rootw, childw; + XQueryPointer( qt_xdisplay(), qt_xrootwin(), &rootw, &childw, + &root_x, &root_y, &win_x, &win_y, &keybstate ); + + if ( keybstate & ControlMask ) { + emit folderDropCopy(fti->folder()); + } else if ( keybstate & ShiftMask ) { + emit folderDrop(fti->folder()); + } else { + if ( mShowPopupAfterDnD ) { + KPopupMenu *menu = new KPopupMenu( this ); + menu->insertItem( i18n("Move"), DRAG_MOVE, 0 ); + menu->insertItem( i18n("Copy"), DRAG_COPY, 1 ); + menu->insertSeparator(); + menu->insertItem( i18n("Cancel"), DRAG_CANCEL, 3 ); + int id = menu->exec( QCursor::pos(), 0 ); + switch(id) { + case DRAG_COPY: + emit folderDropCopy(fti->folder()); + break; + case DRAG_MOVE: + emit folderDrop(fti->folder()); + break; + case DRAG_CANCEL: + //just chill, doing nothing + break; + default: + kdDebug(5006) << "Unknown dnd-type!" << endl; + } } - e->accept(); + else + emit folderDrop(fti->folder()); + } + e->accept(); } else - e->ignore(); + e->ignore(); // Begin this wasn't necessary in QT 2.0.2 dropItem = 0L; @@ -1363,24 +1269,25 @@ void KMFolderTree::keyPressEvent( QKeyEvent * e ) //Seems to behave sensibly even if ShiftButton is down, suprising if (cntrl) { disconnect(this,SIGNAL(currentChanged(QListViewItem*)), - this,SLOT(doFolderSelected(QListViewItem*))); + this,SLOT(doFolderSelected(QListViewItem*))); switch (e->key()) { - case Key_Down: - case Key_Up: - case Key_Home: - case Key_End: - case Key_Next: - case Key_Prior: - case Key_Plus: - case Key_Minus: - case Key_Escape: - KMFolderTreeInherited::keyPressEvent( e ); + case Key_Down: + case Key_Up: + case Key_Home: + case Key_End: + case Key_Next: + case Key_Prior: + case Key_Plus: + case Key_Minus: + case Key_Escape: + KListView::keyPressEvent( e ); } connect(this,SIGNAL(currentChanged(QListViewItem*)), this,SLOT(doFolderSelected(QListViewItem*))); } } +//----------------------------------------------------------------------------- void KMFolderTree::contentsMousePressEvent( QMouseEvent * e ) { int b = e->state() & !ShiftButton & !ControlButton; @@ -1390,7 +1297,7 @@ void KMFolderTree::contentsMousePressEvent( QMouseEvent * e ) e->button(), b ); clearSelection(); - KMFolderTreeInherited::contentsMousePressEvent( f ); + KListView::contentsMousePressEvent( f ); // Force current item to be selected for some reason in certain weird // circumstances this is not always the case delete f; @@ -1399,6 +1306,7 @@ void KMFolderTree::contentsMousePressEvent( QMouseEvent * e ) setSelected( currentItem(), true ); } +//----------------------------------------------------------------------------- void KMFolderTree::contentsMouseReleaseEvent( QMouseEvent * e ) { int b = e->state() & !ShiftButton & !ControlButton; @@ -1407,15 +1315,16 @@ void KMFolderTree::contentsMouseReleaseEvent( QMouseEvent * e ) e->globalPos(), e->button(), b ); - KMFolderTreeInherited::contentsMouseReleaseEvent( f ); + KListView::contentsMouseReleaseEvent( f ); delete f; } +//----------------------------------------------------------------------------- void KMFolderTree::contentsMouseMoveEvent( QMouseEvent* e ) { if (e->state() != NoButton) return; - KMFolderTreeInherited::contentsMouseMoveEvent( e ); + KListView::contentsMouseMoveEvent( e ); } @@ -1423,10 +1332,9 @@ void KMFolderTree::contentsMouseMoveEvent( QMouseEvent* e ) void KMFolderTree::slotFolderExpanded( QListViewItem * item ) { KMFolderTreeItem *fti = static_cast(item); - if (fti && fti->parent() == firstChild() && fti->folder - && fti->folder->protocol() == "imap") + if (fti && fti->folder() && fti->folder()->protocol() == "imap") { - KMFolderImap *folder = static_cast(fti->folder); + KMFolderImap *folder = static_cast(fti->folder()); if (folder->getSubfolderState() == KMFolderImap::imapNoInformation) folder->listDirectory( fti ); } @@ -1437,10 +1345,10 @@ void KMFolderTree::slotFolderExpanded( QListViewItem * item ) void KMFolderTree::slotFolderCollapsed( QListViewItem * item ) { KMFolderTreeItem *fti = static_cast(item); - if (fti && fti->parent() == firstChild() && fti->folder - && fti->folder->protocol() == "imap") + if (fti && fti->parent() == firstChild() && fti->folder() + && fti->folder()->protocol() == "imap") { - KMFolderImap *folder = static_cast(fti->folder); + KMFolderImap *folder = static_cast(fti->folder()); folder->setSubfolderState(KMFolderImap::imapNoInformation); } } @@ -1451,16 +1359,16 @@ void KMFolderTree::slotAccountDeleted(KMFolderImap *aFolder) { writeConfig(); KMFolderTreeItem* fti = static_cast(currentItem()); - if (fti && fti->folder && fti->folder == aFolder) + if (fti && fti->folder() && fti->folder() == aFolder) doFolderSelected(0); QListViewItem *lvi = firstChild(); if (lvi) lvi = lvi->firstChild(); while (lvi) { fti = static_cast(lvi); - if (fti && fti->folder) + if (fti && fti->folder()) { - KMFolderImap *folder = static_cast(fti->folder); + KMFolderImap *folder = static_cast(fti->folder()); if (folder == aFolder) { delete fti; @@ -1472,6 +1380,7 @@ void KMFolderTree::slotAccountDeleted(KMFolderImap *aFolder) } +//----------------------------------------------------------------------------- void KMFolderTree::slotUpdateCounts(KMFolderImap * folder, bool success) { if (success) slotUpdateCounts(static_cast(folder)); @@ -1487,51 +1396,41 @@ void KMFolderTree::slotUpdateCounts(KMFolder * folder) KMFolderTreeItem* fti = static_cast(current); // sanity check - if (!fti || !fti->folder) return; + if (!fti) return; + if (!fti->folder()) fti->setTotalCount(-1); - QString extendedName, num; + // get the unread count 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()); + if (folder->noContent()) // always empty + count = -1; + else if (fti->folder()->countUnread() == 0) + count = 0; + else + count = fti->folder()->countUnread(); - fti->setText(unreadIndex, num); - extendedName = ""; + // set it + bool repaint = false; + if (fti->unreadCount() != count) repaint = true; + fti->setUnreadCount(count); - } 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) + if (isTotalActive()) { + count = 0; // get the total-count - if (fti->folder->isOpened()) - count = fti->folder->count(); + if (fti->folder()->isOpened()) + count = fti->folder()->count(); else - count = fti->folder->count(true); // count with caching + count = fti->folder()->count(true); // count with caching - if (fti->folder->noContent()) - num = QString::null; - else if (count == 0) - num = "-"; - else - num.setNum(count); + if (fti->folder()->noContent()) + count = -1; - fti->setText(totalIndex, num); + // set it + fti->setTotalCount(count); + } + if (repaint) { + // repaint the item and it's parents + for (QListViewItem *p = fti; p; p = p->parent()) p->repaint(); } } @@ -1542,45 +1441,35 @@ void KMFolderTree::toggleColumn(int column, bool openFolders) if (column == unread) { // switch unread - if (unreadIsActive) + if ( isUnreadActive() ) { - removeColumn( unreadIndex ); - if (totalIsActive && totalIndex > unreadIndex) --totalIndex; - unreadIndex = -1; - unreadIsActive = false; + removeUnreadColumn(); reload(); } else { - unreadIndex = addColumn( i18n("Unread"), 70 ); - unreadIsActive = true; - setColumnAlignment( unreadIndex, Qt :: AlignRight); + addUnreadColumn( i18n("Unread"), 70 ); reload(); } // toggle KPopupMenu and KToggleAction - mPopup->setItemChecked( mUnreadPop, unreadIsActive ); + mPopup->setItemChecked( mUnreadPop, isUnreadActive() ); if ( parentWidget()->parentWidget()->isA("KMMainWin") ) static_cast(parentWidget()->parentWidget()) - ->unreadColumnToggle->setChecked( unreadIsActive ); + ->unreadColumnToggle->setChecked( isUnreadActive() ); } else if (column == total) { // switch total - if (totalIsActive) + if ( isTotalActive() ) { - removeColumn( totalIndex ); - if (unreadIsActive && totalIndex < unreadIndex) --unreadIndex; - totalIndex = -1; - totalIsActive = false; + removeTotalColumn(); reload(); } else { - totalIndex = addColumn( i18n("Total"), 70 ); - totalIsActive = true; - setColumnAlignment( totalIndex, Qt :: AlignRight); + addTotalColumn( i18n("Total"), 70 ); reload(openFolders); } // toggle KPopupMenu and KToggleAction - mPopup->setItemChecked( mTotalPop, totalIsActive ); + mPopup->setItemChecked( mTotalPop, isTotalActive() ); if ( parentWidget()->parentWidget()->isA("KMMainWin") ) static_cast(parentWidget()->parentWidget()) - ->totalColumnToggle->setChecked( totalIsActive ); + ->totalColumnToggle->setChecked( isTotalActive() ); } else kdDebug(5006) << "unknown column:" << column << endl; } @@ -1598,19 +1487,18 @@ void KMFolderTree::slotToggleTotalColumn() toggleColumn(total, true); } -/* //----------------------------------------------------------------------------- bool KMFolderTree::eventFilter( QObject *o, QEvent *e ) { - if (e->type() == QEvent::MouseButtonPress && - dynamic_cast(e)->button() == RightButton) + if ( e->type() == QEvent::MouseButtonPress && + static_cast(e)->button() == RightButton && + o->isA("QHeader") ) { - mPopup->popup( mapToGlobal( header()->geometry().bottomRight() ) ); + mPopup->popup( static_cast(e)->globalPos() ); return true; } - return KMFolderTreeInherited::eventFilter(o, e); + return KFolderTree::eventFilter(o, e); } -*/ #include "kmfoldertree.moc" diff --git a/kmfoldertree.h b/kmfoldertree.h index 56a7177c6..017a4ab25 100644 --- a/kmfoldertree.h +++ b/kmfoldertree.h @@ -2,82 +2,66 @@ #define __KMFOLDERTREE #include -#include #include #include + #include #include +#include -// Fixme! A temporary dependency -#include "kmheaders.h" // For KMHeaderToFolderDrag & KMPaintInfo - +#include "kmheaders.h" #include "kmfolder.h" class QDropEvent; class QPixmap; class QPainter; class KMFolderImap; +class KMFolderTree; class CryptPlugWrapperList; -class KMFolderTreeItem : public QListViewItem +class KMFolderTreeItem : public KFolderTreeItem { public: - KMFolder* folder; - QString unread; - KMPaintInfo *mPaintInfo; - - /** Construct the root item */ - KMFolderTreeItem( QListView *parent, - KMPaintInfo *aPaintInfo ) - : QListViewItem( parent, i18n("Mail") ), - folder( 0 ), - unread( QString::null ), - mPaintInfo( aPaintInfo ) + /** Construct a root item _without_ folder */ + KMFolderTreeItem( KFolderTree *parent, + QString name ) + : KFolderTreeItem( parent, name ), mFolder( 0 ) {} - KMFolderTreeItem( QListView *parent, - KMFolder* folder, - KMPaintInfo *aPaintInfo ) - : QListViewItem( parent, i18n("Mail") ), - folder( folder ), - unread( QString::null ), - mPaintInfo( aPaintInfo ) + + /** Construct a root item _with_ folder */ + KMFolderTreeItem( KFolderTree *parent, QString name, + KMFolder* folder ) + : KFolderTreeItem( parent, name, folder->protocol() ), mFolder( folder ) {} /** Construct a child item */ - KMFolderTreeItem( QListViewItem* parent, - KMFolder* folder, - KMPaintInfo *aPaintInfo ) - : QListViewItem( parent, (folder) ? folder->label() : QString::null ), - folder( folder ), - unread( QString::null ), - mPaintInfo( aPaintInfo ) + KMFolderTreeItem( KFolderTreeItem* parent, QString name, + KMFolder* folder ) + : KFolderTreeItem( parent, folder->protocol(), name ), mFolder( folder ) {} - - virtual ~KMFolderTreeItem(); - void paintCell( QPainter * p, const QColorGroup & cg, - int column, int width, int align ); + /** gets the recursive unread-count */ + virtual int countUnreadRecursive(); - virtual QString key( int, bool ) const; + /** associated folder */ + KMFolder* folder() { return mFolder; } - virtual int compare( QListViewItem * i, int col, bool ascending ) const; + /** dnd */ + virtual bool acceptDrag(QDropEvent* ) const; +protected: + KMFolder* mFolder; }; +//========================================================================== -#define KMFolderTreeInherited QListView -class KMFolderTree : public QListView +class KMFolderTree : public KFolderTree { Q_OBJECT -protected: - virtual void drawContentsOffset( QPainter * p, int ox, int oy, - int cx, int cy, int cw, int ch ); - public: KMFolderTree( CryptPlugWrapperList * cryptPlugList, QWidget *parent=0, const char *name=0 ); - virtual ~KMFolderTree(); /** Save config options */ void writeConfig(); @@ -86,7 +70,7 @@ public: virtual void reload(bool openFolders = false); /** Recusively add folders in a folder directory to a listview item. */ - virtual void addDirectory( KMFolderDir *fdir, QListViewItem* parent ); + virtual void addDirectory( KMFolderDir *fdir, KMFolderTreeItem* parent ); /** Find index of given folder. Returns -1 if not found */ virtual QListViewItem* indexOfFolder(const KMFolder*); @@ -105,9 +89,6 @@ public: /** Read color options and set palette. */ void readColorConfig(void); - /** Ensure that there is only one selected item */ - virtual void setSelected( QListViewItem *, bool ); - /** Remove information about not existing folders from the config file */ void cleanupConfigFile(); @@ -124,18 +105,6 @@ public: /** 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*); @@ -149,28 +118,35 @@ signals: /** Messages have been dropped onto a folder with Ctrl */ void folderDropCopy(KMFolder*); -protected: - /** open ancestors and ensure item is visible */ - void prepareItem( KMFolderTreeItem* ); - public slots: /** Select the next folder with unread messages */ void nextUnreadFolder(); + /** Select the previous folder with unread messages */ void prevUnreadFolder(); + /** Increment current folder */ void incCurrentFolder(); + /** Decrement current folder */ void decCurrentFolder(); + /** Select the current folder */ void selectCurrentFolder(); + /** Executes delayed update of folder tree */ void delayedUpdate(); + /** Remove all items associated with the given IMAP account */ void slotAccountDeleted(KMFolderImap*); + /** Select the item and switch to the folder */ void doFolderSelected(QListViewItem*); + /** autoscroll support */ + void startAutoScroll(); + void stopAutoScroll(); + protected slots: // void slotRMB(int, int); /** called by the folder-manager when the list of folders changed */ @@ -203,6 +179,12 @@ protected slots: void slotToggleUnreadColumn(); void slotToggleTotalColumn(); + void autoScroll(); + + /** right and middle mouse button */ + void rightButtonPressed( QListViewItem *, const QPoint &, int); + void mouseButtonPressed( int btn, QListViewItem *, const QPoint &, int); + protected: /** Catch palette changes */ virtual bool event(QEvent *e); @@ -218,7 +200,6 @@ protected: bool readIsListViewItemOpen(KMFolderTreeItem *fti); void writeIsListViewItemOpen(KMFolderTreeItem *fti); - KMFolderNodeList mList; QTimer mUpdateTimer; static QPixmap *pixDir, *pixNode, *pixPlain, *pixFld, *pixFull, *pixIn, *pixOut, *pixTr, *pixSent; @@ -226,7 +207,7 @@ protected: /** We need out own root, otherwise the @ref QListView will create its own root of type @ref QListViewItem, hence no overriding paintBranches and no backing pixmap */ - QListViewItem *root; + KMFolderTreeItem *root; /** Drag and drop methods */ void contentsDragEnterEvent( QDragEnterEvent *e ); @@ -245,42 +226,35 @@ protected: QListViewItem *dropItem; KMFolderTreeItem *mLastItem; QTimer autoopen_timer; - KMPaintInfo mPaintInfo; // filter some rmb-events -// bool eventFilter(QObject*, QEvent*); + bool eventFilter(QObject*, QEvent*); + + virtual void drawContentsOffset( QPainter * p, int ox, int oy, + int cx, int cy, int cw, int ch ); + + /** open ancestors and ensure item is visible */ + void prepareItem( KMFolderTreeItem* ); + + /** connect all signals */ + void connectSignals(); - // ########### 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; - - // actions for D'n'D from Headers to Folder - int mActionWhenDnD; - int mActionWhenShiftDnD; - int mActionWhenCtrlDnD; + QTimer autoscroll_timer; + int autoscroll_time; + int autoscroll_accel; + CryptPlugWrapperList * mCryptPlugList; -public slots: - void startAutoScroll(); - void stopAutoScroll(); -protected slots: - void autoScroll(); - void rightButtonPressed( QListViewItem *, const QPoint &, int); - void mouseButtonPressed( int btn, QListViewItem *, const QPoint &, int); + /** total column */ + QListViewItemIterator mUpdateIterator; + + /** popup for unread/total */ + KPopupMenu* mPopup; + int mUnreadPop; + int mTotalPop; + + /** show popup after D'n'D? */ + bool mShowPopupAfterDnD; }; #endif diff --git a/kmheaders.cpp b/kmheaders.cpp index 238893623..62239f8d8 100644 --- a/kmheaders.cpp +++ b/kmheaders.cpp @@ -82,24 +82,6 @@ QIconSet* KMHeaders::down = 0; bool KMHeaders::mTrue = true; bool KMHeaders::mFalse = false; -//----------------------------------------------------------------------------- -// KMHeaderToFolderDrag method definitions -QPixmap* KMHeaderToFolderDrag::dragPix = 0; -KMHeaderToFolderDrag::KMHeaderToFolderDrag( QWidget * parent, - const char * name ) - : QStoredDrag( "KMHeaderToFolderDrag/magic", parent, name ) -{ - dragPix = new QPixmap( DesktopIcon("message", - KIcon::SizeMedium ) ); - - setPixmap( *dragPix ); -} - -bool KMHeaderToFolderDrag::canDecode( QDropEvent* e ) -{ - return e->provides( "KMHeaderToFolderDrag/magic" ); -} - //----------------------------------------------------------------------------- // KMHeaderItem method definitions @@ -381,7 +363,7 @@ public: _cg.setColor( QColorGroup::Text, c ); } - static QString generate_key( int id, KMHeaders *headers, KMMsgBase *msg, const KMPaintInfo *paintInfo, int sortOrder) + static QString generate_key( int id, KMHeaders *headers, KMMsgBase *msg, const KPaintInfo *paintInfo, int sortOrder) { // It appears, that QListView in Qt-3.0 asks for the key // in QListView::clear(), which is called from @@ -609,10 +591,10 @@ KMHeaders::~KMHeaders () bool KMHeaders::eventFilter ( QObject *o, QEvent *e ) { if ( e->type() == QEvent::MouseButtonPress && - dynamic_cast(e)->button() == RightButton && + static_cast(e)->button() == RightButton && o->isA("QHeader") ) { - mPopup->popup( mapToGlobal( header()->geometry().center() ) ); + mPopup->popup( static_cast(e)->globalPos() ); return true; } return KListView::eventFilter(o, e); @@ -742,16 +724,6 @@ void KMHeaders::readConfig (void) KConfigGroupSaver saver(config, "Behaviour"); mLoopOnGotoUnread = config->readBoolEntry( "LoopOnGotoUnread", true ); mJumpToUnread = config->readBoolEntry( "JumpToUnread", false ); - // read D'n'D behavior settings - mActionWhenDnD = config->readNumEntry("DnD_action_normal", KMMsgDnDActionASK ); - if ( mActionWhenDnD < 0 || mActionWhenDnD > 2 ) - mActionWhenDnD = KMMsgDnDActionASK; - mActionWhenShiftDnD = config->readNumEntry("DnD_action_SHIFT", KMMsgDnDActionMOVE ); - if ( mActionWhenShiftDnD < 0 || mActionWhenShiftDnD > 2 ) - mActionWhenShiftDnD = KMMsgDnDActionMOVE; - mActionWhenCtrlDnD = config->readNumEntry("DnD_action_CTRL", KMMsgDnDActionCOPY ); - if ( mActionWhenCtrlDnD < 0 || mActionWhenCtrlDnD > 2 ) - mActionWhenCtrlDnD = KMMsgDnDActionCOPY; } restoreLayout(config, "Header-Geometry"); @@ -1968,7 +1940,7 @@ void KMHeaders::copyMsgToFolder(KMFolder* destFolder, // copy the message(s); note: the list is empty afterwards! KMFolderImap *imapDestFolder = static_cast(destFolder); imapDestFolder->copyMsg(list); - if (imapDestFolder->isSelected()) imapDestFolder->getFolder(); + imapDestFolder->getFolder(); } destFolder->close(); @@ -2612,30 +2584,27 @@ void KMHeaders::contentsMouseMoveEvent( QMouseEvent* e ) mousePressed = FALSE; QListViewItem *item = itemAt( contentsToViewport(presspos) ); if ( item ) { - KMHeaderToFolderDrag* d = new KMHeaderToFolderDrag(viewport()); - - const ButtonState keybstate = e->state(); - int actionSettings; - if ( keybstate & Qt::ControlButton ) - actionSettings = mActionWhenCtrlDnD; - else if ( keybstate & Qt::ShiftButton ) - actionSettings = mActionWhenShiftDnD; + QDragObject *d = new QStoredDrag("x-kmail-drag/message", viewport()); + + // Are multiple messages selected? + unsigned int count = 0; + for( QListViewItemIterator it(this); (it.current() && count < 2); it++ ) + if( it.current()->isSelected() ) + count++; + + // Set pixmap + QPixmap pixmap; + if( count == 1 ) + pixmap = QPixmap( DesktopIcon("message", KIcon::SizeSmall) ); else - actionSettings = mActionWhenDnD; - switch ( actionSettings ) { - case KMMsgDnDActionMOVE: - d->dragMove(); - break; - case KMMsgDnDActionCOPY: - d->dragCopy(); - break; - default: - // We will ASK the user via PopUp menu. - // But we _must_ call dragMove() since otherwise Qt will - // show the '+' indicator if CTRL key is hold down even if - // our KMail user has specified /not/ to copy via CRTL+D'n'D. - d->dragMove(); + pixmap = QPixmap( DesktopIcon("kmultiple", KIcon::SizeSmall) ); + + // Calculate hotspot (as in Konqueror) + if( !pixmap.isNull() ) { + QPoint hotspot( pixmap.width() / 2, pixmap.height() / 2 ); + d->setPixmap( pixmap, hotspot ); } + d->drag(); } } } @@ -2683,9 +2652,9 @@ void KMHeaders::slotRMB() mOwner->updateMessageMenu(); QPopupMenu *msgMoveMenu = new QPopupMenu(menu); - mOwner->folderToPopupMenu( NULL, TRUE, this, &mMenuToFolder, msgMoveMenu ); + mOwner->folderToPopupMenu( TRUE, this, &mMenuToFolder, msgMoveMenu ); QPopupMenu *msgCopyMenu = new QPopupMenu(menu); - mOwner->folderToPopupMenu( NULL, FALSE, this, &mMenuToFolder, msgCopyMenu ); + mOwner->folderToPopupMenu( FALSE, this, &mMenuToFolder, msgCopyMenu ); bool out_folder = kernel->folderIsDraftOrOutbox(mFolder); if ( out_folder ) diff --git a/kmheaders.h b/kmheaders.h index dee807f36..84b4f2571 100644 --- a/kmheaders.h +++ b/kmheaders.h @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include @@ -28,43 +29,6 @@ class KMScoringManager; typedef QPtrList KMMessageList; typedef QMap KMMenuToFolder; -/** A special drag class for header list to folder tree DnD operations */ -class KMHeaderToFolderDrag: public QStoredDrag { -public: - KMHeaderToFolderDrag( QWidget * parent = 0, const char * name = 0 ); - ~KMHeaderToFolderDrag() {}; - - static bool canDecode( QDropEvent* e ); -protected: - static QPixmap *dragPix; -}; - -/** Information shared by all items in a list view */ -struct KMPaintInfo { - bool pixmapOn; - QPixmap pixmap; - QColor colFore; - QColor colBack; - QColor colNew; - QColor colUnread; - QColor colFlag; - bool showSize; // Do we display the message size? -#ifdef SCORING - bool showScore; -#endif - bool orderOfArrival; - bool status; - int flagCol; - int senderCol; - int subCol; - int dateCol; -#ifdef SCORING - int scoreCol; -#endif - int sizeCol; - bool showCryptoIcons; -}; - /** The widget that shows the contents of folders */ #define KMHeadersInherited KListView class KMHeaders : public KListView @@ -148,7 +112,7 @@ public: KMMainWin* owner(void) const { return mOwner; } /** PaintInfo pointer */ - const KMPaintInfo *paintInfo(void) const { return &mPaintInfo; } + const KPaintInfo *paintInfo(void) const { return &mPaintInfo; } /** Read config options. */ virtual void readConfig(void); @@ -374,7 +338,7 @@ private: /** For shift selection */ QListViewItem *beginSelection, *endSelection; /** Current colours and backing pixmap */ - KMPaintInfo mPaintInfo; + KPaintInfo mPaintInfo; #ifdef SCORING KMScoringManager *mScoringManager; @@ -407,10 +371,6 @@ private: KMime::DateFormatter mDate; /** value of config key Behaviour/LoopOnGotoUnread */ bool mLoopOnGotoUnread; - // actions for D'n'D from Headers to Folder - int mActionWhenDnD; - int mActionWhenShiftDnD; - int mActionWhenCtrlDnD; bool mJumpToUnread; /** popup to switch columns */ diff --git a/kmmainwin.cpp b/kmmainwin.cpp index 2ad62c054..d48bf8c00 100644 --- a/kmmainwin.cpp +++ b/kmmainwin.cpp @@ -287,34 +287,27 @@ void KMMainWin::readConfig(void) mPanner1Sep[1] = width() - siz.height(); } - if (!mStartupDone) + if (!mStartupDone || + oldWindowLayout != mWindowLayout || + oldShowMIMETreeMode != mShowMIMETreeMode ) { - /** unread / total columns */ - - // get the number (aka section) of the column; -1 is de-activated - int unreadColumn = config->readNumEntry("UnreadColumn", -1); + /** unread / total columns + * as we have some dependencies in this widget + * it's better to manage these here */ + int unreadColumn = config->readNumEntry("UnreadColumn", -1); int totalColumn = config->readNumEntry("TotalColumn", -1); - // activate them - if (unreadColumn != -1) { + /* we need to _activate_ them in the correct order + * this is ugly because we can't use header()->moveSection + * but otherwise the restoreLayout from KMFolderTree + * doesn't know that to do */ + if (unreadColumn != -1 && unreadColumn < totalColumn) mFolderTree->toggleColumn(KMFolderTree::unread); - mFolderTree->setColumnWidth(mFolderTree->getUnreadColumnNumber(), config->readNumEntry("UnreadColumnWidth")); - } - if (totalColumn != -1) { + if (totalColumn != -1) mFolderTree->toggleColumn(KMFolderTree::total); - mFolderTree->setColumnWidth(mFolderTree->getTotalColumnNumber(), config->readNumEntry("TotalColumnWidth")); - } - // get the correct order back - if (totalColumn < unreadColumn && totalColumn != -1) - 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 */ + if (unreadColumn != -1 && unreadColumn > totalColumn) + mFolderTree->toggleColumn(KMFolderTree::unread); + } } @@ -434,22 +427,9 @@ void KMMainWin::writeConfig(void) 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); + config->writeEntry("UnreadColumn", mFolderTree->unreadIndex()); + config->writeEntry("TotalColumn", mFolderTree->totalIndex()); } @@ -598,7 +578,7 @@ void KMMainWin::createWidgets(void) // create a mime part tree and store it's pointer in the reader win mMimePartTree = new KMMimePartTree( mMsgView, mimeParent, "mMimePartTree" ); mMsgView->setMimePartTree( mMimePartTree ); - if( 0 < mShowMIMETreeMode ) + if( 1 < mShowMIMETreeMode ) mMimePartTree->show(); else mMimePartTree->hide(); @@ -689,7 +669,7 @@ void KMMainWin::activatePanners(void) break; } - if( 0 < mShowMIMETreeMode ) + if( 1 < mShowMIMETreeMode ) mMimePartTree->show(); else mMimePartTree->hide(); @@ -1727,8 +1707,12 @@ void KMMainWin::folderSelected(KMFolder* aFolder, bool jumpToUnread) kernel->kbp()->busy(); - if( !aFolder && mFolderTree->currentItem() == mFolderTree->firstChild() ) { - slotIntro(); + if( !aFolder || aFolder->noContent() || + aFolder->count() == 0 ) + { + mMsgView->setMsg( 0, FALSE ); + if( mMimePartTree ) + mMimePartTree->hide(); } else if( !mFolder ) { mMsgView->enableMsgDisplay(); mMsgView->setMsg( 0, TRUE ); @@ -3195,8 +3179,7 @@ void KMMainWin::copySelectedToFolder(int menuId ) //----------------------------------------------------------------------------- -QPopupMenu* KMMainWin::folderToPopupMenu(KMFolderTreeItem* fti, - bool move, +QPopupMenu* KMMainWin::folderToPopupMenu(bool move, QObject *receiver, KMMenuToFolder *aMenuToFolder, QPopupMenu *menu ) @@ -3210,7 +3193,29 @@ QPopupMenu* KMMainWin::folderToPopupMenu(KMFolderTreeItem* fti, menu->removeItemAt( 0 ); } - if (!fti) fti = static_cast(mFolderTree->firstChild()); + for (QListViewItem *item = mFolderTree->firstChild(); + item; item = item->nextSibling()) + { + // operate on top-level items + QString label = item->text(0); + // make a new Submenu + QPopupMenu* subMenu = new QPopupMenu(menu); + subMenu = makeFolderMenu(dynamic_cast(item), + move, receiver, aMenuToFolder, subMenu); + menu->insertItem( label, subMenu ); + } + + return menu; +} + +//----------------------------------------------------------------------------- +QPopupMenu* KMMainWin::makeFolderMenu(KMFolderTreeItem* item, + bool move, + QObject *receiver, + KMMenuToFolder *aMenuToFolder, + QPopupMenu *menu ) +{ + // connect the signals if (move) { disconnect(menu, SIGNAL(activated(int)), receiver, @@ -3224,48 +3229,55 @@ QPopupMenu* KMMainWin::folderToPopupMenu(KMFolderTreeItem* fti, SLOT(copySelectedToFolder(int))); } - if (fti->folder && !fti->folder->isDir()) + if (item->folder() && !item->folder()->isDir() + && !item->folder()->noContent()) { - int menuId; - if (move) - menuId = menu->insertItem(i18n("Move to this Folder")); - else - menuId = menu->insertItem(i18n("Copy to this Folder")); - aMenuToFolder->insert( menuId, fti->folder ); - menu->insertSeparator(); + int menuId; + if (move) + menuId = menu->insertItem(i18n("Move to this Folder")); + else + menuId = menu->insertItem(i18n("Copy to this Folder")); + aMenuToFolder->insert( menuId, item->folder() ); + menu->insertSeparator(); } - fti = static_cast(fti->firstChild()); - while (fti) + + for (QListViewItem *it = item->firstChild(); + it; it = it->nextSibling()) { - if (fti->folder) + KMFolderTreeItem* fti = dynamic_cast(it); + if (fti->folder()) { QString label = fti->text(0); label.replace(QRegExp("&"),QString("&&")); if (fti->firstChild()) { - QPopupMenu *subMenu = folderToPopupMenu(fti, move, receiver, + // descend + QPopupMenu *subMenu = makeFolderMenu(fti, move, receiver, aMenuToFolder, new QPopupMenu(menu, "subMenu")); menu->insertItem(label, subMenu); - } else - if (!fti->folder->isDir()) - { - int menuId = menu->insertItem(label); - aMenuToFolder->insert( menuId, fti->folder ); + } else { + // insert an item + if (!fti->folder()->isDir()) + { + int menuId = menu->insertItem(label); + aMenuToFolder->insert( menuId, fti->folder() ); + } } } - fti = static_cast(fti->nextSibling()); } return menu; } + + //----------------------------------------------------------------------------- void KMMainWin::updateMessageMenu() { mMenuToFolder.clear(); - folderToPopupMenu( 0, true, this, &mMenuToFolder, moveActionMenu->popupMenu() ); - folderToPopupMenu( 0, false, this, &mMenuToFolder, copyActionMenu->popupMenu() ); + folderToPopupMenu( true, this, &mMenuToFolder, moveActionMenu->popupMenu() ); + folderToPopupMenu( false, this, &mMenuToFolder, copyActionMenu->popupMenu() ); updateMessageActions(); } @@ -3596,7 +3608,6 @@ void KMMainWin::slotTransferCancelled() void KMMainWin::slotIntro() { if ( !mFolderTree || !mMsgView ) return; - // ### select "Mail" in folder tree until Carsten Burghard removes it. if ( !mFolderTree->firstChild() ) return; if ( mFolderTree->currentItem() != mFolderTree->firstChild() ) // don't loop mFolderTree->doFolderSelected( mFolderTree->firstChild() ); diff --git a/kmmainwin.h b/kmmainwin.h index 11e42cbf9..8bbca1783 100644 --- a/kmmainwin.h +++ b/kmmainwin.h @@ -79,8 +79,12 @@ public: be moved into the given folder, otherwise messages will be copied. Am empty @ref KMMenuToFolder must be passed in. */ - virtual QPopupMenu* folderToPopupMenu(KMFolderTreeItem* fti, - bool move, + virtual QPopupMenu* folderToPopupMenu(bool move, + QObject *receiver, + KMMenuToFolder *aMenuToFolder, + QPopupMenu *menu); + QPopupMenu* makeFolderMenu(KMFolderTreeItem* item, + bool move, QObject *receiver, KMMenuToFolder *aMenuToFolder, QPopupMenu *menu);