00001
00002
00003 #include <config.h>
00004 #include "kmfolderseldlg.h"
00005 #include "kmfoldertree.h"
00006 #include "kmfolder.h"
00007 #include "kmmainwidget.h"
00008 #include "globalsettings.h"
00009
00010 #include <kdebug.h>
00011 #include <klineedit.h>
00012 #include <kpopupmenu.h>
00013 #include <kiconloader.h>
00014
00015 #include <qlayout.h>
00016 #include <qtoolbutton.h>
00017
00018 namespace KMail {
00019
00020 class FolderItem : public KFolderTreeItem
00021 {
00022 public:
00023 FolderItem( KFolderTree * listView );
00024 FolderItem( KFolderTreeItem * listViewItem );
00025
00026 void setFolder( KMFolder * folder ) { mFolder = folder; };
00027 const KMFolder * folder() { return mFolder; };
00028
00029
00030
00031
00032
00033 bool isAlternate () {
00034 return mAlternate;
00035 }
00036
00037
00038 void setAlternate ( bool alternate ) {
00039 mAlternate = alternate;
00040 }
00041
00042
00043
00044 virtual void paintCell( QPainter *p, const QColorGroup &cg,
00045 int column, int width, int alignment )
00046 {
00047 KListView* view = static_cast< KListView* >( listView() );
00048
00049
00050 QColor nocolor;
00051 QColor alt = view->alternateBackground();
00052 view->setAlternateBackground( nocolor );
00053
00054
00055 QColorGroup *cgroup = (QColorGroup *)&view->viewport()->colorGroup();
00056 QColor base = cgroup->base();
00057 QColor text = cgroup->text();
00058 cgroup->setColor( QColorGroup::Base, isAlternate() ? alt : base );
00059 cgroup->setColor( QColorGroup::Text, isEnabled() ? text : Qt::lightGray );
00060
00061
00062 KListViewItem::paintCell( p, cg, column, width, alignment );
00063
00064
00065 cgroup->setColor( QColorGroup::Base, base );
00066 cgroup->setColor( QColorGroup::Text, text );
00067 view->setAlternateBackground( alt );
00068 }
00069
00070 private:
00071 KMFolder * mFolder;
00072 bool mAlternate;
00073 };
00074
00075
00076 FolderItem::FolderItem( KFolderTree * listView )
00077 : KFolderTreeItem( listView ),
00078 mFolder( 0 )
00079 {}
00080
00081
00082 FolderItem::FolderItem( KFolderTreeItem * listViewItem )
00083 : KFolderTreeItem( listViewItem ),
00084 mFolder( 0 )
00085 {}
00086
00087
00088 SimpleFolderTree::SimpleFolderTree( QWidget * parent,
00089 KMFolderTree * folderTree,
00090 const QString & preSelection,
00091 bool mustBeReadWrite )
00092 : KFolderTree( parent ), mFolderTree( folderTree )
00093 {
00094 setSelectionModeExt( Single );
00095 mFolderColumn = addColumn( i18n( "Folder" ), 0 );
00096 mPathColumn = addColumn( i18n( "Path" ), 0 );
00097 setAllColumnsShowFocus( true );
00098 setAlternateBackground( QColor( 0xf0, 0xf0, 0xf0 ) );
00099
00100 reload( mustBeReadWrite, true, true, preSelection );
00101 readColorConfig();
00102
00103 applyFilter( "" );
00104
00105 connect(this, SIGNAL(collapsed(QListViewItem*)), SLOT(recolorRows()));
00106 connect(this, SIGNAL(expanded(QListViewItem*)), SLOT(recolorRows()));
00107
00108 connect( this, SIGNAL( contextMenuRequested( QListViewItem*, const QPoint &, int ) ),
00109 this, SLOT( slotContextMenuRequested( QListViewItem*, const QPoint & ) ) );
00110 }
00111
00112
00113 void SimpleFolderTree::reload( bool mustBeReadWrite, bool showOutbox,
00114 bool showImapFolders, const QString& preSelection )
00115 {
00116 mLastMustBeReadWrite = mustBeReadWrite;
00117 mLastShowOutbox = showOutbox;
00118 mLastShowImapFolders = showImapFolders;
00119
00120 clear();
00121 FolderItem * lastItem = 0;
00122 FolderItem * lastTopItem = 0;
00123 FolderItem * selectedItem = 0;
00124 int lastDepth = 0;
00125
00126 QString selected = preSelection;
00127 if ( selected.isEmpty() && folder() )
00128 selected = folder()->idString();
00129
00130 mFilter = "";
00131 QString path;
00132
00133 for ( QListViewItemIterator it( mFolderTree ) ; it.current() ; ++it )
00134 {
00135 KMFolderTreeItem * fti = static_cast<KMFolderTreeItem *>( it.current() );
00136
00137
00138 if ( !fti || fti->protocol() == KFolderTreeItem::Search )
00139 continue;
00140
00141
00142 if ( fti->protocol() == KFolderTreeItem::Imap && !showImapFolders )
00143 continue;
00144
00145
00146 if ( fti->type() == KFolderTreeItem::Outbox && !showOutbox )
00147 continue;
00148
00149 int depth = fti->depth();
00150 FolderItem * item = 0;
00151 if ( depth <= 0 ) {
00152
00153 item = new FolderItem( this );
00154 if ( lastTopItem )
00155 item->moveItem( lastTopItem );
00156 lastTopItem = item;
00157 depth = 0;
00158 path = "";
00159 }
00160 else {
00161 if ( depth > lastDepth ) {
00162
00163 item = new FolderItem( lastItem );
00164 lastItem->setOpen(true);
00165 }
00166 else {
00167 path = path.section( '/', 0, -2 - (lastDepth-depth) );
00168
00169 if ( depth == lastDepth ) {
00170
00171 item = new FolderItem( static_cast<FolderItem*>(lastItem->parent()) );
00172 item->moveItem( lastItem );
00173 } else if ( depth < lastDepth ) {
00174
00175
00176 while ( ( depth <= --lastDepth ) && lastItem->parent() ) {
00177 lastItem = static_cast<FolderItem *>( lastItem->parent() );
00178 }
00179 if ( lastItem->parent() ) {
00180 item = new FolderItem( static_cast<FolderItem*>(lastItem->parent()) );
00181 item->moveItem( lastItem );
00182 } else {
00183
00184 kdDebug( 5006 ) << "You shouldn't get here: depth=" << depth
00185 << "folder name=" << fti->text( 0 ) << endl;
00186 item = new FolderItem( this );
00187 lastTopItem = item;
00188 }
00189 }
00190 }
00191 }
00192
00193 if ( depth > 0 )
00194 path += "/";
00195 path += fti->text( 0 );
00196
00197 item->setText( mFolderColumn, fti->text( 0 ) );
00198 item->setText( mPathColumn, path );
00199
00200 item->setProtocol( fti->protocol() );
00201 item->setType( fti->type() );
00202
00203
00204
00205 if ( mustBeReadWrite && ( !fti->folder() || fti->folder()->isReadOnly() ) ) {
00206 item->setSelectable( false );
00207 } else {
00208 if ( fti->folder() ) {
00209 item->setFolder( fti->folder() );
00210 if ( selected == item->folder()->idString() )
00211 selectedItem = item;
00212 }
00213 }
00214 lastItem = item;
00215 lastDepth = depth;
00216 }
00217
00218 if ( selectedItem ) {
00219 setSelected( selectedItem, true );
00220 ensureItemVisible( selectedItem );
00221 }
00222 }
00223
00224
00225 const KMFolder * SimpleFolderTree::folder() const
00226 {
00227 QListViewItem * item = currentItem();
00228 if ( item ) {
00229 const KMFolder * folder = static_cast<FolderItem *>( item )->folder();
00230 if( folder ) return folder;
00231 }
00232 return 0;
00233 }
00234
00235
00236 void SimpleFolderTree::setFolder( KMFolder *folder )
00237 {
00238 for ( QListViewItemIterator it( this ) ; it.current() ; ++it )
00239 {
00240 const KMFolder *fld = static_cast<FolderItem *>( it.current() )->folder();
00241 if ( fld == folder )
00242 {
00243 setSelected( it.current(), true );
00244 ensureItemVisible( it.current() );
00245 }
00246 }
00247 }
00248
00249
00250 void SimpleFolderTree::setFolder( const QString& idString )
00251 {
00252 setFolder( kmkernel->findFolderById( idString ) );
00253 }
00254
00255
00256 void SimpleFolderTree::addChildFolder()
00257 {
00258 const KMFolder *fld = folder();
00259 if ( fld ) {
00260 mFolderTree->addChildFolder( (KMFolder *) fld, parentWidget() );
00261 reload( mLastMustBeReadWrite, mLastShowOutbox, mLastShowImapFolders );
00262 setFolder( (KMFolder *) fld );
00263 }
00264 }
00265
00266
00267 void SimpleFolderTree::slotContextMenuRequested( QListViewItem *lvi,
00268 const QPoint &p )
00269 {
00270 if (!lvi)
00271 return;
00272 setCurrentItem( lvi );
00273 setSelected( lvi, TRUE );
00274
00275 const KMFolder * folder = static_cast<FolderItem *>( lvi )->folder();
00276 if ( !folder || folder->noContent() || folder->noChildren() )
00277 return;
00278
00279 KPopupMenu *folderMenu = new KPopupMenu;
00280 folderMenu->insertTitle( folder->label() );
00281 folderMenu->insertSeparator();
00282 folderMenu->insertItem(SmallIconSet("folder_new"),
00283 i18n("&New Subfolder..."), this,
00284 SLOT(addChildFolder()));
00285 kmkernel->setContextMenuShown( true );
00286 folderMenu->exec (p, 0);
00287 kmkernel->setContextMenuShown( false );
00288 delete folderMenu;
00289 folderMenu = 0;
00290 }
00291
00292
00293 void SimpleFolderTree::readColorConfig (void)
00294 {
00295 QColor c1=QColor(kapp->palette().active().text());
00296 QColor c2=QColor(kapp->palette().active().base());
00297
00298 mPaintInfo.colFore = c1;
00299 mPaintInfo.colBack = c2;
00300
00301 QPalette newPal = kapp->palette();
00302 newPal.setColor( QColorGroup::Base, mPaintInfo.colBack );
00303 newPal.setColor( QColorGroup::Text, mPaintInfo.colFore );
00304 setPalette( newPal );
00305 }
00306
00307
00308
00309 static int recurseFilter( QListViewItem * item, const QString& filter, int column )
00310 {
00311 if ( item == 0 )
00312 return 0;
00313
00314 QListViewItem * child;
00315 child = item->firstChild();
00316
00317 int enabled = 0;
00318 while ( child ) {
00319 enabled += recurseFilter( child, filter, column );
00320 child = child->nextSibling();
00321 }
00322
00323 if ( filter.length() == 0 ||
00324 item->text( column ).find( filter, 0, false ) >= 0 ) {
00325 item->setVisible( true );
00326 ++enabled;
00327 }
00328 else {
00329 item->setVisible( !!enabled );
00330 item->setEnabled( false );
00331 }
00332
00333 return enabled;
00334 }
00335
00336 void SimpleFolderTree::recolorRows()
00337 {
00338
00339 int alt = 0;
00340 QListViewItemIterator it ( this );
00341 while ( it.current() ) {
00342 FolderItem * item = static_cast< FolderItem* >( it.current() );
00343
00344 if ( item->isVisible() ) {
00345 bool visible = true;
00346 QListViewItem * parent = item->parent();
00347 while ( parent ) {
00348 if (!parent->isOpen()) {
00349 visible = false;
00350 break;
00351 }
00352 parent = parent->parent();
00353 }
00354
00355 if ( visible ) {
00356 item->setAlternate( alt );
00357 alt = !alt;
00358 }
00359 }
00360
00361 ++it;
00362 }
00363 }
00364
00365 void SimpleFolderTree::applyFilter( const QString& filter )
00366 {
00367
00368 QListViewItemIterator clean( this );
00369 while ( clean.current() ) {
00370 QListViewItem * item = clean.current();
00371 item->setEnabled( true );
00372 item->setVisible( true );
00373 item->setOpen( true );
00374 ++clean;
00375 }
00376
00377 mFilter = filter;
00378
00379 if ( filter.isEmpty() ) {
00380 setColumnText( mPathColumn, i18n("Path") );
00381 return;
00382 }
00383
00384
00385
00386
00387 QListViewItemIterator it( this );
00388 while ( it.current() ) {
00389 QListViewItem * item = it.current();
00390 if ( item->depth() <= 0 )
00391 recurseFilter( item, filter, mPathColumn );
00392 ++it;
00393 }
00394
00395
00396 recolorRows();
00397
00398
00399 QListViewItemIterator first ( this );
00400 while ( first.current() ) {
00401 FolderItem * item = static_cast< FolderItem* >( first.current() );
00402
00403 if ( item->isVisible() && item->isSelectable() ) {
00404 setSelected( item, true );
00405 ensureItemVisible( item );
00406 break;
00407 }
00408
00409 ++first;
00410 }
00411
00412
00413 if ( filter.length() > 0 )
00414 setColumnText( mPathColumn, i18n("Path") + " ( " + filter + " )" );
00415 else
00416 setColumnText( mPathColumn, i18n("Path") );
00417
00418 mFilter = filter;
00419 }
00420
00421
00422 void SimpleFolderTree::keyPressEvent( QKeyEvent *e ) {
00423 int ch = e->ascii();
00424
00425 if ( ch >= 32 && ch <= 126 )
00426 applyFilter( mFilter + ch );
00427
00428 else if ( ch == 8 || ch == 127 ) {
00429 if ( mFilter.length() > 0 ) {
00430 mFilter.truncate( mFilter.length()-1 );
00431 applyFilter( mFilter );
00432 }
00433 }
00434
00435 else
00436 KListView::keyPressEvent( e );
00437 }
00438
00439
00440
00441 KMFolderSelDlg::KMFolderSelDlg( KMMainWidget * parent, const QString& caption,
00442 bool mustBeReadWrite, bool useGlobalSettings )
00443 : KDialogBase( parent, "folder dialog", true, caption,
00444 Ok|Cancel|User1, Ok, true,
00445 KGuiItem(i18n("&New Subfolder..."), "folder_new",
00446 i18n("Create a new subfolder under the currently selected folder"))
00447 ),
00448 mUseGlobalSettings( useGlobalSettings )
00449 {
00450 KMFolderTree * ft = parent->folderTree();
00451 assert( ft );
00452
00453 QString preSelection = mUseGlobalSettings ?
00454 GlobalSettings::self()->lastSelectedFolder() : QString::null;
00455 mTreeView = new KMail::SimpleFolderTree( makeVBoxMainWidget(), ft,
00456 preSelection, mustBeReadWrite );
00457 init();
00458 }
00459
00460
00461 KMFolderSelDlg::KMFolderSelDlg( QWidget * parent, KMFolderTree * tree,
00462 const QString& caption, bool mustBeReadWrite, bool useGlobalSettings )
00463 : KDialogBase( parent, "folder dialog", true, caption,
00464 Ok|Cancel|User1, Ok, true,
00465 KGuiItem(i18n("&New Subfolder..."), "folder_new",
00466 i18n("Create a new subfolder under the currently selected folder"))
00467 ),
00468 mUseGlobalSettings( useGlobalSettings )
00469 {
00470 QString preSelection = mUseGlobalSettings ?
00471 GlobalSettings::self()->lastSelectedFolder() : QString::null;
00472 mTreeView = new KMail::SimpleFolderTree( makeVBoxMainWidget(), tree,
00473 preSelection, mustBeReadWrite );
00474 init();
00475 }
00476
00477
00478 void KMFolderSelDlg::init()
00479 {
00480 mTreeView->setFocus();
00481 connect( mTreeView, SIGNAL( doubleClicked( QListViewItem*, const QPoint&, int ) ),
00482 this, SLOT( slotSelect() ) );
00483 connect( mTreeView, SIGNAL( selectionChanged() ),
00484 this, SLOT( slotUpdateBtnStatus() ) );
00485
00486 readConfig();
00487 }
00488
00489
00490 KMFolderSelDlg::~KMFolderSelDlg()
00491 {
00492 const KMFolder * cur = folder();
00493 if ( cur && mUseGlobalSettings ) {
00494 GlobalSettings::self()->setLastSelectedFolder( cur->idString() );
00495 }
00496
00497 writeConfig();
00498 }
00499
00500
00501
00502 KMFolder * KMFolderSelDlg::folder( void )
00503 {
00504 return ( KMFolder * ) mTreeView->folder();
00505 }
00506
00507
00508 void KMFolderSelDlg::setFolder( KMFolder* folder )
00509 {
00510 mTreeView->setFolder( folder );
00511 }
00512
00513
00514 void KMFolderSelDlg::slotSelect()
00515 {
00516 accept();
00517 }
00518
00519
00520 void KMFolderSelDlg::slotUser1()
00521 {
00522 mTreeView->addChildFolder();
00523 }
00524
00525
00526 void KMFolderSelDlg::slotUpdateBtnStatus()
00527 {
00528 enableButton( User1, folder() &&
00529 ( !folder()->noContent() && !folder()->noChildren() ) );
00530 }
00531
00532
00533 void KMFolderSelDlg::setFlags( bool mustBeReadWrite, bool showOutbox,
00534 bool showImapFolders )
00535 {
00536 mTreeView->reload( mustBeReadWrite, showOutbox, showImapFolders );
00537 }
00538
00539 void KMFolderSelDlg::readConfig()
00540 {
00541 KConfig *config = KGlobal::config();
00542 config->setGroup( "FolderSelectionDialog" );
00543
00544 QSize size = config->readSizeEntry( "Size" );
00545 if ( !size.isEmpty() ) resize( size );
00546 else resize( 500, 300 );
00547
00548 QValueList<int> widths = config->readIntListEntry( "ColumnWidths" );
00549 if ( !widths.isEmpty() ) {
00550 mTreeView->setColumnWidth(mTreeView->mFolderColumn, widths[0]);
00551 mTreeView->setColumnWidth(mTreeView->mPathColumn, widths[1]);
00552 }
00553 else {
00554 int colWidth = width() / 2;
00555 mTreeView->setColumnWidth(mTreeView->mFolderColumn, colWidth);
00556 mTreeView->setColumnWidth(mTreeView->mPathColumn, colWidth);
00557 }
00558 }
00559
00560 void KMFolderSelDlg::writeConfig()
00561 {
00562 KConfig *config = KGlobal::config();
00563 config->setGroup( "FolderSelectionDialog" );
00564 config->writeEntry( "Size", size() );
00565
00566 QValueList<int> widths;
00567 widths.push_back(mTreeView->columnWidth(mTreeView->mFolderColumn));
00568 widths.push_back(mTreeView->columnWidth(mTreeView->mPathColumn));
00569 config->writeEntry( "ColumnWidths", widths );
00570 }
00571
00572 }
00573
00574 #include "kmfolderseldlg.moc"