You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
506 lines
15 KiB
506 lines
15 KiB
/****************************************************************************** |
|
* |
|
* Copyright (c) 2007 Volker Krause <vkrause@kde.org> |
|
* Copyright 2008 Szymon Tomasz Stefanek <pragma@kvirc.net> |
|
* |
|
* This program is free software; you can redistribute it and/or modify |
|
* it under the terms of the GNU General Public License as published by |
|
* the Free Software Foundation; either version 2 of the License, or |
|
* (at your option) any later version. |
|
* |
|
* This program is distributed in the hope that it will be useful, |
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|
* GNU General Public License for more details. |
|
* |
|
* You should have received a copy of the GNU General Public License |
|
* along with this program; if not, write to the Free Software |
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
|
* |
|
*******************************************************************************/ |
|
|
|
#include "favoritefolderview.h" |
|
|
|
#include "folderstorage.h" |
|
#include "folderselectiondialog.h" |
|
#include "globalsettings.h" |
|
#include "kmacctcachedimap.h" |
|
#include "kmfolder.h" |
|
#include "kmfolderimap.h" |
|
#include "kmfoldercachedimap.h" |
|
#include "kmmainwidget.h" |
|
#include "korghelper.h" |
|
#include "mainfolderview.h" |
|
|
|
#include <kicon.h> |
|
#include <kinputdialog.h> |
|
#include <klocale.h> |
|
#include <kmenu.h> |
|
|
|
#include <libkdepim/broadcaststatus.h> |
|
#include <libkdepim/kaddrbookexternal.h> |
|
|
|
#include <QDBusConnection> |
|
#include <QDBusInterface> |
|
|
|
|
|
namespace KMail |
|
{ |
|
|
|
FavoriteFolderView::FavoriteFolderView( KMMainWidget *mainWidget, FolderViewManager *manager, QWidget *parent, const char *name ) |
|
: FolderView( mainWidget, manager, parent, "FavoriteFolderView", name ) |
|
{ |
|
setRootIsDecorated( false ); // we have only toplevel items |
|
setSortingPolicy( SortByDragAndDropKey ); |
|
setColumnText( LabelColumn, i18n( "Favorite Folders" ) ); |
|
} |
|
|
|
FolderViewItem * FavoriteFolderView::createItem( |
|
FolderViewItem *, |
|
const QString &label, |
|
KMFolder *folder, |
|
KPIM::FolderTreeWidgetItem::Protocol proto, |
|
KPIM::FolderTreeWidgetItem::FolderType type |
|
) |
|
{ |
|
if ( !folder ) |
|
return 0; |
|
|
|
int idx = GlobalSettings::self()->favoriteFolderIds().indexOf( folder->id() ); |
|
if ( idx < 0 ) |
|
{ |
|
// Not in favorites. If the folder is an inbox which we haven't seen before |
|
// (i.e. a new account), then add it, else return here already. |
|
|
|
// The old FavoriteFolderView code contains a snippet that automatically |
|
// adds the inboxes of all the accounts to the view. |
|
// While this is a quiestionable rule, Thomas says that it might be for some |
|
// usability reason so I'm adding it here too.... |
|
if ( type != FolderViewItem::Inbox ) |
|
return 0; // not an inbox |
|
if ( GlobalSettings::self()->favoriteFolderViewSeenInboxes().contains( folder->id() ) ) |
|
return 0; // already seen |
|
|
|
QList<int> seenInboxes = GlobalSettings::self()->favoriteFolderViewSeenInboxes(); |
|
seenInboxes.append( folder->id() ); // FIXME: this list never shrinks |
|
GlobalSettings::self()->setFavoriteFolderViewSeenInboxes( seenInboxes ); |
|
} |
|
|
|
// If we reached this point, we want to add the folder to the favorite folder |
|
// view |
|
|
|
QString name; |
|
bool newFavorite = !( idx >= 0 && idx < GlobalSettings::self()->favoriteFolderNames().count() ); |
|
if ( !newFavorite ) |
|
name = GlobalSettings::self()->favoriteFolderNames().at( idx ); |
|
|
|
if ( name.isEmpty() ) |
|
{ |
|
name = label; |
|
|
|
// locate the item's parent |
|
if ( proto == FolderViewItem::Local ) |
|
name += QString(" (%1)").arg( i18n("Local Folders") ); |
|
else { |
|
KMFolder *owner = folder; |
|
while( owner->ownerFolder() ) |
|
owner = owner->ownerFolder(); |
|
|
|
name += QString(" (%1)").arg( owner->label() ); |
|
} |
|
|
|
// Ok, we created a new folder here, so make sure it is also in the list of |
|
// favorite folder ids and names. Otherwise, the item would not be added on |
|
// the next reload() |
|
QList<int> idList = GlobalSettings::self()->favoriteFolderIds(); |
|
QList<QString> nameList = GlobalSettings::self()->favoriteFolderNames(); |
|
idList.append( folder->id() ); |
|
nameList.append( name ); |
|
GlobalSettings::self()->setFavoriteFolderIds( idList ); |
|
GlobalSettings::self()->setFavoriteFolderNames( nameList ); |
|
} |
|
|
|
FolderViewItem *item = new FolderViewItem( this, name, folder, proto, type ); |
|
item->setAlwaysDisplayCounts( true ); |
|
return item; |
|
} |
|
|
|
void FavoriteFolderView::storeFavorites() |
|
{ |
|
QList<int> lIds; |
|
QStringList lNames; |
|
|
|
QTreeWidgetItemIterator it( this ); |
|
while( FolderViewItem * item = static_cast<FolderViewItem *>( *it ) ) |
|
{ |
|
lIds.append( item->folder()->id() ); |
|
lNames.append( item->labelText() ); |
|
++it; |
|
} |
|
|
|
GlobalSettings::self()->setFavoriteFolderIds( lIds ); |
|
GlobalSettings::self()->setFavoriteFolderNames( lNames ); |
|
} |
|
|
|
void FavoriteFolderView::appendAddFolderActionToMenu( KMenu *menu ) const |
|
{ |
|
menu->addAction( KIcon( "bookmark-new" ), i18n( "Add Favorite Folder..." ), |
|
this, SLOT( addFolder() ) ); |
|
} |
|
|
|
void FavoriteFolderView::fillContextMenuViewStructureRelatedActions( KMenu *menu, FolderViewItem */*item*/, bool multiSelection ) |
|
{ |
|
menu->addAction( KIcon( "edit-delete" ), i18n( "Remove From Favorites" ), this, SLOT( removeFolders() ) ); |
|
if ( !multiSelection ) |
|
menu->addAction( KIcon( "edit-rename" ), i18n( "Rename Favorite..." ), this, SLOT( renameFolder() ) ); |
|
appendAddFolderActionToMenu( menu ); |
|
} |
|
|
|
void FavoriteFolderView::fillContextMenuNoItem( KMenu *mneu ) |
|
{ |
|
appendAddFolderActionToMenu( mneu ); |
|
} |
|
|
|
//======================================================================================= |
|
// DND Machinery: we allow adding items from outside and maybe sorting stuff by dnd. |
|
// |
|
|
|
class FoldersDropAction |
|
{ |
|
public: |
|
enum Action |
|
{ |
|
Accept, |
|
Reject |
|
}; |
|
|
|
public: |
|
// in |
|
QDropEvent *event; |
|
FavoriteFolderView *view; |
|
// out |
|
Action action; |
|
FolderViewItem *reference; |
|
FolderView::DropInsertPosition position; |
|
QRect validityRect; |
|
QString description; |
|
}; |
|
|
|
static void computeFoldersDropAction( FoldersDropAction *act ) |
|
{ |
|
act->reference = static_cast<FolderViewItem *>( act->view->itemAt( act->event->pos() ) ); |
|
|
|
if ( !act->reference ) |
|
{ |
|
// not over an item: try to use the last item in the view as reference |
|
int cc = act->view->topLevelItemCount(); |
|
if ( cc < 1 ) |
|
{ |
|
// nothing in the view at all: totally new items, accept on the whole viewport |
|
act->action = FoldersDropAction::Accept; |
|
act->validityRect = act->view->viewport()->rect(); |
|
act->description = i18n("Add Folders to Favorites"); |
|
return; |
|
} |
|
|
|
act->reference = static_cast<FolderViewItem *>( act->view->topLevelItem( cc - 1 ) ); |
|
// now item != 0 (and item is visible) |
|
} |
|
|
|
QRect r = act->view->visualItemRect( act->reference ); |
|
QRect mouseRect( act->event->pos().x() - 1, act->event->pos().y() - 1, 2, 2 ); |
|
|
|
// set defaults |
|
act->action = FoldersDropAction::Reject; |
|
act->validityRect = mouseRect; |
|
|
|
// make sure we're not dragging stuff over itself |
|
|
|
QList<QPointer<KMFolder> > lFolders = DraggedFolderList::get(); |
|
if ( lFolders.isEmpty() ) |
|
return; // nothing we can accept |
|
|
|
for ( QList< QPointer< KMFolder > >::Iterator it = lFolders.begin(); it != lFolders.end(); ++it ) |
|
{ |
|
if ( !( *it ) ) |
|
return; // one of the folders was lost in the way: don't bother |
|
if ( ( *it ) == act->reference->folder() ) |
|
return; // inserting above or below itself |
|
} |
|
|
|
act->action = FoldersDropAction::Accept; |
|
|
|
if ( act->event->pos().y() < ( r.top() + ( r.height() / 2 ) ) ) |
|
{ |
|
act->position = FolderView::AboveReference; |
|
act->validityRect = r; |
|
act->validityRect.setHeight( r.height() / 2 ); |
|
act->description = i18n( "Insert Folders Above %1", act->reference->labelText() ); |
|
return; |
|
} |
|
|
|
r.setTop( r.top() + ( r.height() / 2 ) ); |
|
r.setHeight( r.height() / 2 ); |
|
act->validityRect = r.united( mouseRect ); |
|
act->position = FolderView::BelowReference; |
|
act->description = i18n( "Insert Folders Below %1", act->reference->labelText() ); |
|
} |
|
|
|
void FavoriteFolderView::handleFoldersDragMoveEvent( QDragMoveEvent *e ) |
|
{ |
|
FoldersDropAction act; |
|
act.event = e; |
|
act.view = this; |
|
|
|
computeFoldersDropAction( &act ); |
|
if ( act.action == FoldersDropAction::Accept ) |
|
{ |
|
e->accept( act.validityRect ); |
|
setDropIndicatorData( 0, act.reference, act.position ); |
|
} else { |
|
e->ignore( act.validityRect ); |
|
setDropIndicatorData( 0, 0 ); |
|
} |
|
|
|
KPIM::BroadcastStatus::instance()->setStatusMsg( act.description ); |
|
} |
|
|
|
void FavoriteFolderView::handleFoldersDropEvent( QDropEvent *e ) |
|
{ |
|
FoldersDropAction act; |
|
act.event = e; |
|
act.view = this; |
|
|
|
computeFoldersDropAction( &act ); |
|
|
|
if ( act.action != FoldersDropAction::Accept ) |
|
{ |
|
e->ignore(); |
|
return; |
|
} |
|
|
|
e->accept(); |
|
|
|
int refIdx; |
|
if ( act.reference ) |
|
{ |
|
refIdx = indexOfTopLevelItem( act.reference ); |
|
if ( act.position == FolderView::AboveReference ) |
|
refIdx--; |
|
} else { |
|
refIdx = -1; |
|
} |
|
|
|
QList<QPointer<KMFolder> > lFolders = DraggedFolderList::get(); |
|
if ( lFolders.isEmpty() ) |
|
return; // nothing we can accept |
|
|
|
setUpdatesEnabled( false ); |
|
|
|
for ( QList<QPointer<KMFolder> >::Iterator it = lFolders.begin(); it != lFolders.end(); ++it ) |
|
{ |
|
if ( !( *it ) ) |
|
continue; // umphf |
|
|
|
FolderViewItem *moved = findItemByFolder( *it ); |
|
if ( !moved ) |
|
moved = addFolderInternal( *it ); |
|
if ( !moved ) |
|
continue; // umphf x 2 |
|
int removedIdx = indexOfTopLevelItem( moved ); |
|
takeTopLevelItem( removedIdx ); |
|
if ( removedIdx >= refIdx ) |
|
refIdx++; |
|
insertTopLevelItem( refIdx, moved ); |
|
} |
|
|
|
setUpdatesEnabled( true ); |
|
|
|
if ( sortingPolicy() == SortByDragAndDropKey ) |
|
{ |
|
fixSortingKeysForChildren( invisibleRootItem() ); |
|
sortByColumn( LabelColumn, Qt::AscendingOrder ); |
|
} |
|
} |
|
|
|
void FavoriteFolderView::addFolder( KMFolder *fld ) |
|
{ |
|
if ( findItemByFolder( fld ) ) |
|
return; // already there |
|
|
|
if ( !addFolderInternal( fld ) ) |
|
return; |
|
|
|
if ( sortingPolicy() == SortByDragAndDropKey ) |
|
fixSortingKeysForChildren( invisibleRootItem() ); |
|
} |
|
|
|
FolderViewItem * FavoriteFolderView::addFolderInternal( KMFolder *fld ) |
|
{ |
|
QList<int> lIds = GlobalSettings::self()->favoriteFolderIds(); |
|
if ( lIds.contains( fld->id() ) ) |
|
return 0; // ugh |
|
|
|
// add it to the list so createItem won't filter it out |
|
lIds.append( fld->id() ); |
|
GlobalSettings::self()->setFavoriteFolderIds( lIds ); |
|
|
|
QStringList lNames = GlobalSettings::self()->favoriteFolderNames(); |
|
lNames.append(QString()); |
|
GlobalSettings::self()->setFavoriteFolderNames( lNames ); |
|
|
|
FolderViewItem * it = createItem( |
|
0, ( fld )->label(), ( fld ), |
|
FolderViewItem::protocolByFolder( fld ), |
|
FolderViewItem::folderTypeByFolder( fld ) |
|
); |
|
|
|
// re-store favorites with the right item name |
|
storeFavorites(); |
|
|
|
return it; |
|
} |
|
|
|
void FavoriteFolderView::addFolder() |
|
{ |
|
FolderSelectionDialog dlg( mainWidget(), i18n("Add Favorite Folder"), false ); |
|
if ( dlg.exec() != QDialog::Accepted ) |
|
return; |
|
KMFolder *folder = dlg.folder(); |
|
if ( !folder ) |
|
return; |
|
addFolderInternal( folder ); |
|
} |
|
|
|
void FavoriteFolderView::renameFolder() |
|
{ |
|
FolderViewItem * it = static_cast<FolderViewItem *>( currentItem() ); |
|
if ( !it ) |
|
return; |
|
|
|
// We would REALLY like to use the nice Qt item renaming method but we can't |
|
// since KMMainWidget assigns the return key to a QAction default shortcut. |
|
// We never get the return key and thus never can end editing succesfuly. |
|
// An action-disabling workaround requires too much code to be implemented. |
|
|
|
bool ok; |
|
QString name = KInputDialog::getText( i18n( "Rename Favorite" ), |
|
i18nc( "@label:textbox New name of the folder.", "Name:" ), |
|
it->labelText(), &ok, this ); |
|
if ( !ok ) |
|
return; |
|
|
|
it->setLabelText( name ); |
|
|
|
storeFavorites(); |
|
} |
|
|
|
void FavoriteFolderView::removeFolders() |
|
{ |
|
QList<QTreeWidgetItem *> lSelected = selectedItems(); |
|
if ( lSelected.isEmpty() ) |
|
return; |
|
|
|
for( QList<QTreeWidgetItem *>::Iterator it = lSelected.begin(); it != lSelected.end(); ++it ) |
|
{ |
|
FolderViewItem * item = static_cast<FolderViewItem *>( *it ); |
|
if ( !item ) |
|
continue; // hum |
|
if ( !item->folder() ) |
|
continue; |
|
|
|
delete item; |
|
} |
|
|
|
storeFavorites(); |
|
} |
|
|
|
void FavoriteFolderView::checkMail() |
|
{ |
|
bool found = false; |
|
|
|
QTreeWidgetItemIterator it( this ); |
|
|
|
while( *it ) |
|
{ |
|
FolderViewItem *fti = static_cast<FolderViewItem*>( *it ); |
|
|
|
if ( |
|
fti->folder()->folderType() == KMFolderTypeImap || |
|
fti->folder()->folderType() == KMFolderTypeCachedImap |
|
) |
|
{ |
|
if ( !found ) |
|
if ( !kmkernel->askToGoOnline() ) |
|
break; |
|
|
|
found = true; |
|
|
|
if ( fti->folder()->folderType() == KMFolderTypeImap ) |
|
{ |
|
KMFolderImap *imap = static_cast<KMFolderImap*>( fti->folder()->storage() ); |
|
imap->getAndCheckFolder(); |
|
} else if ( fti->folder()->folderType() == KMFolderTypeCachedImap ) |
|
{ |
|
KMFolderCachedImap* f = static_cast<KMFolderCachedImap*>( fti->folder()->storage() ); |
|
f->account()->processNewMailSingleFolder( fti->folder() ); |
|
} |
|
} |
|
|
|
++it; |
|
} |
|
|
|
} |
|
|
|
static void selectKontactPlugin( const QString &plugin ) |
|
{ |
|
QDBusInterface *kontact = new QDBusInterface( "org.kde.kontact", |
|
"/KontactInterface", "org.kde.kontact.KontactInterface", |
|
QDBusConnection::sessionBus() ); |
|
if ( kontact->isValid() ) |
|
kontact->call( "selectPlugin", plugin ); |
|
delete kontact; |
|
} |
|
|
|
void FavoriteFolderView::activateItemInternal( FolderViewItem *fvi, bool keepSelection, bool notifyManager, bool middleButton ) |
|
{ |
|
FolderView::activateItemInternal( fvi, keepSelection, notifyManager, middleButton ); |
|
|
|
// handle groupware folders |
|
if ( !fvi || !fvi->folder() || !fvi->folder()->storage() ) |
|
return; |
|
switch ( fvi->folder()->storage()->contentsType() ) |
|
{ |
|
case KMail::ContentsTypeContact: |
|
KPIM::KAddrBookExternal::openAddressBook( this ); |
|
break; |
|
case KMail::ContentsTypeNote: |
|
selectKontactPlugin( "kontact_knotesplugin" ); |
|
break; |
|
case KMail::ContentsTypeCalendar: |
|
case KMail::ContentsTypeTask: |
|
case KMail::ContentsTypeJournal: |
|
{ |
|
KMail::KorgHelper::ensureRunning(); |
|
QString plugin; |
|
switch ( fvi->folder()->storage()->contentsType() ) |
|
{ |
|
case KMail::ContentsTypeCalendar: |
|
plugin = QLatin1String( "kontact_korganizerplugin" ); break; |
|
case KMail::ContentsTypeTask: |
|
plugin = QLatin1String( "kontact_todoplugin" ); break; |
|
case KMail::ContentsTypeJournal: |
|
plugin = QLatin1String( "kontact_journalplugin" ); break; |
|
default: assert( false ); |
|
} |
|
selectKontactPlugin( plugin ); |
|
} |
|
break; |
|
default: // make gcc happy |
|
break; |
|
} |
|
} |
|
|
|
} // namespace KMail |
|
|
|
#include "favoritefolderview.moc"
|
|
|