00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
#include <qfile.h>
00022
00023
#include <kfileitem.h>
00024
#include <kdebug.h>
00025
00026
#include <sys/types.h>
00027
#include <sys/stat.h>
00028
#include <unistd.h>
00029
00030
#include "kfiletreeviewitem.h"
00031
#include "kfiletreebranch.h"
00032
00033
00034
00035 KFileTreeBranch::KFileTreeBranch(
KFileTreeView *parent,
const KURL& url,
00036
const QString& name,
00037
const QPixmap& pix,
bool showHidden,
00038
KFileTreeViewItem *branchRoot )
00039
00040 :
KDirLister( false ),
00041 m_root( branchRoot ),
00042 m_startURL( url ),
00043 m_name ( name ),
00044 m_rootIcon( pix ),
00045 m_openRootIcon( pix ),
00046 m_recurseChildren(true),
00047 m_showExtensions(true)
00048 {
00049
kdDebug( 250) <<
"Creating branch for url " << url.
prettyURL() <<
endl;
00050
00051
00052
if( ! branchRoot )
00053 {
00054 m_root =
new KFileTreeViewItem( parent,
00055
new KFileItem( url,
"inode/directory",
00056 S_IFDIR ),
00057
this );
00058 }
00059
00060 m_root->setExpandable(
true );
00061 m_root->setPixmap( 0, pix );
00062 m_root->setText( 0, name );
00063
00064
setShowingDotFiles( showHidden );
00065
00066 connect(
this, SIGNAL(
refreshItems(
const KFileItemList&)),
00067
this, SLOT ( slotRefreshItems(
const KFileItemList& )));
00068
00069 connect(
this, SIGNAL(
newItems(
const KFileItemList&)),
00070
this, SLOT ( addItems(
const KFileItemList& )));
00071
00072 connect(
this, SIGNAL(
completed(
const KURL& )),
00073
this, SLOT(slCompleted(
const KURL&)));
00074
00075 connect(
this, SIGNAL(
started(
const KURL& )),
00076
this, SLOT( slotListerStarted(
const KURL& )));
00077
00078 connect(
this, SIGNAL(
deleteItem(
KFileItem* )),
00079
this, SLOT( slotDeleteItem(
KFileItem* )));
00080
00081 connect(
this, SIGNAL(
canceled(
const KURL&) ),
00082
this, SLOT( slotCanceled(
const KURL&) ));
00083
00084 connect(
this, SIGNAL(
clear()),
00085
this, SLOT( slotDirlisterClear()));
00086
00087 connect(
this, SIGNAL(
clear(
const KURL&)),
00088
this, SLOT( slotDirlisterClearURL(
const KURL&)));
00089
00090 connect(
this, SIGNAL(
redirection(
const KURL& ,
const KURL& ) ),
00091
this, SLOT( slotRedirect(
const KURL&,
const KURL& )));
00092
00093 m_openChildrenURLs.append( url );
00094 }
00095
00096
void KFileTreeBranch::setOpenPixmap(
const QPixmap& pix )
00097 {
00098 m_openRootIcon = pix;
00099
00100
if(
root()->isOpen())
00101 {
00102
root()->setPixmap( 0, pix );
00103 }
00104 }
00105
00106
void KFileTreeBranch::slotListerStarted(
const KURL &url )
00107 {
00108
00109
kdDebug( 250) <<
"Starting to list " << url.
prettyURL() <<
endl;
00110 }
00111
00112
00113
KFileTreeViewItem *KFileTreeBranch::parentKFTVItem(
KFileItem *item )
00114 {
00115
KFileTreeViewItem *parent = 0;
00116
00117
if( ! item )
return 0;
00118
00119
00120
00121
00122
KURL url = item->
url();
00123
00124
KURL dirUrl( url );
00125 dirUrl.setFileName( QString::null );
00126
00127
00128 parent =
findTVIByURL( dirUrl );
00129
00130
return( parent );
00131 }
00132
00133
00134
void KFileTreeBranch::slotRefreshItems(
const KFileItemList& list )
00135 {
00136
KFileItemListIterator it( list );
00137
kdDebug(250) <<
"Refreshing " << list.count() <<
" items !" <<
endl;
00138
KFileItem *currItem;
00139
KFileTreeViewItem *item = 0;
00140
00141
while ( (currItem = it.current()) != 0 )
00142 {
00143 item =
findTVIByURL(currItem->
url());
00144
if (item) {
00145 item->setPixmap(0, item->
fileItem()->
pixmap( KIcon::SizeSmall ));
00146 item->setText( 0, item->
fileItem()->
text());
00147 }
00148 ++it;
00149 }
00150 }
00151
00152
void KFileTreeBranch::addItems(
const KFileItemList& list )
00153 {
00154
KFileItemListIterator it( list );
00155
kdDebug(250) <<
"Adding " << list.count() <<
" items !" <<
endl;
00156
KFileItem *currItem;
00157
KFileTreeViewItemList treeViewItList;
00158
KFileTreeViewItem *parentItem = 0;
00159
00160
while ( (currItem = it.current()) != 0 )
00161 {
00162 parentItem = parentKFTVItem( currItem );
00163
00164
00165
00166
KFileTreeViewItem *newKFTVI =
00167 static_cast<KFileTreeViewItem *>(currItem->
extraData(
this ));
00168
00169
if( ! newKFTVI )
00170 {
00171 newKFTVI =
createTreeViewItem( parentItem, currItem );
00172
if (!newKFTVI)
00173 {
00174
00175 ++it;
00176
continue;
00177 }
00178 currItem->
setExtraData(
this, newKFTVI );
00179
00180
00181
if( !m_showExtensions && !currItem->
isDir() )
00182 {
00183
QString name = currItem->
text();
00184
int mPoint =
name.findRev(
'.' );
00185
if( mPoint > 0 )
00186
name =
name.left( mPoint );
00187 newKFTVI->setText( 0, name );
00188 }
00189 }
00190
00191
00192
00193
00194
if(
dirOnlyMode() && !m_recurseChildren && currItem->
isLocalFile( ) && currItem->
isDir() )
00195 {
00196
KURL url = currItem->
url();
00197
QString filename = url.
directory(
false,
true ) + url.
fileName();
00198
00199
00200
00201
kdDebug(250) <<
"Doing stat on " << filename <<
endl;
00202
struct stat statBuf;
00203
if(
stat( QFile::encodeName( filename ), &statBuf ) == 0 )
00204 {
00205
int hardLinks = statBuf.st_nlink;
00206
kdDebug(250) <<
"stat succeeded, hardlinks: " << hardLinks <<
endl;
00207
00208
00209
00210
00211
if( hardLinks != 2 )
00212 {
00213 newKFTVI->setExpandable(
true);
00214 }
00215
else
00216 {
00217 newKFTVI->setExpandable(
false);
00218 }
00219
if( hardLinks >= 2 )
00220 {
00221
kdDebug(250) <<
"Emitting for " << url.
prettyURL() <<
endl;
00222 emit(
directoryChildCount( newKFTVI, hardLinks-2));
00223 }
00224 }
00225
else
00226 {
00227
kdDebug(250) <<
"stat of " << filename <<
" failed !" <<
endl;
00228 }
00229 }
00230 ++it;
00231
00232 treeViewItList.append( newKFTVI );
00233 }
00234
00235 emit
newTreeViewItems(
this, treeViewItList );
00236 }
00237
00238 KFileTreeViewItem*
KFileTreeBranch::createTreeViewItem(
KFileTreeViewItem *parent,
00239
KFileItem *fileItem )
00240 {
00241
KFileTreeViewItem *tvi = 0;
00242
if( parent && fileItem )
00243 {
00244 tvi =
new KFileTreeViewItem( parent,
00245 fileItem,
00246
this );
00247 }
00248
else
00249 {
00250
kdDebug(250) <<
"createTreeViewItem: Have no parent" <<
endl;
00251 }
00252
return( tvi );
00253 }
00254
00255 void KFileTreeBranch::setChildRecurse(
bool t )
00256 {
00257 m_recurseChildren = t;
00258
if( t ==
false )
00259 m_openChildrenURLs.clear();
00260 }
00261
00262
00263 void KFileTreeBranch::setShowExtensions(
bool visible )
00264 {
00265 m_showExtensions = visible;
00266 }
00267
00268 bool KFileTreeBranch::showExtensions( )
const
00269
{
00270
return( m_showExtensions );
00271 }
00272
00273
00274
00275
00276
00277
00278
void KFileTreeBranch::slotDeleteItem(
KFileItem *it )
00279 {
00280
if( !it )
return;
00281
kdDebug(250) <<
"Slot Delete Item hitted for " << it->
url().
prettyURL() <<
endl;
00282
00283
KFileTreeViewItem *kfti = static_cast<KFileTreeViewItem*>(it->
extraData(
this));
00284
00285
if( kfti )
00286 {
00287
kdDebug( 250 ) <<
"Child count: " << kfti->childCount() <<
endl;
00288
if( kfti->childCount() > 0 )
00289 {
00290
KFileTreeViewItem *child = static_cast<KFileTreeViewItem*>(kfti->firstChild());
00291
00292
while( child )
00293 {
00294
kdDebug(250) <<
"Calling child to be deleted !" <<
endl;
00295
KFileTreeViewItem *nextChild = static_cast<KFileTreeViewItem*>(child->nextSibling());
00296 slotDeleteItem( child->
fileItem());
00297 child = nextChild;
00298 }
00299 }
00300
00301
kdDebug(250) <<
"Found corresponding KFileTreeViewItem" <<
endl;
00302
delete( kfti );
00303 }
00304
else
00305 {
00306
kdDebug(250) <<
"Error: kfiletreeviewitem: "<< kfti <<
endl;
00307 }
00308 }
00309
00310
00311
void KFileTreeBranch::slotCanceled(
const KURL& url )
00312 {
00313
00314
00315 m_openChildrenURLs.remove( url);
00316
00317
00318
KFileTreeViewItem *item =
findTVIByURL(url);
00319
if (!item)
return;
00320 emit
populateFinished(item);
00321 }
00322
00323
void KFileTreeBranch::slotDirlisterClear()
00324 {
00325
kdDebug(250)<<
"*** Clear all !" <<
endl;
00326
00327
if( m_root )
00328 deleteChildrenOf( m_root );
00329 }
00330
00331
void KFileTreeBranch::slotDirlisterClearURL(
const KURL& url )
00332 {
00333
kdDebug(250)<<
"*** Clear for URL !" << url.
prettyURL() <<
endl;
00334
KFileItem *item =
findByURL( url );
00335
if( item )
00336 {
00337
KFileTreeViewItem *ftvi =
00338 static_cast<KFileTreeViewItem *>(item->
extraData(
this ));
00339 deleteChildrenOf( ftvi );
00340 }
00341 }
00342
00343
void KFileTreeBranch::deleteChildrenOf(
QListViewItem *parent )
00344 {
00345
00346
00347
if ( !parent )
00348
return;
00349
00350
while ( parent->firstChild() )
00351
delete parent->firstChild();
00352 }
00353
00354
void KFileTreeBranch::slotRedirect(
const KURL& oldUrl,
const KURL&newUrl )
00355 {
00356
if( oldUrl.
equals( m_startURL,
true ))
00357 {
00358 m_startURL = newUrl;
00359 }
00360 }
00361
00362 KFileTreeViewItem*
KFileTreeBranch::findTVIByURL(
const KURL& url )
00363 {
00364
KFileTreeViewItem *resultItem = 0;
00365
00366
if( m_startURL.
equals(url,
true) )
00367 {
00368
kdDebug(250) <<
"findByURL: Returning root as a parent !" <<
endl;
00369 resultItem = m_root;
00370 }
00371
else if( m_lastFoundURL.
equals( url,
true ))
00372 {
00373
kdDebug(250) <<
"findByURL: Returning from lastFoundURL!" <<
endl;
00374 resultItem = m_lastFoundItem;
00375 }
00376
else
00377 {
00378
kdDebug(250) <<
"findByURL: searching by dirlister: " << url.
url() <<
endl;
00379
00380
KFileItem *it =
findByURL( url );
00381
00382
if( it )
00383 {
00384 resultItem = static_cast<KFileTreeViewItem*>(it->
extraData(
this));
00385 m_lastFoundItem = resultItem;
00386 m_lastFoundURL = url;
00387 }
00388 }
00389
00390
return( resultItem );
00391 }
00392
00393
00394
void KFileTreeBranch::slCompleted(
const KURL& url )
00395 {
00396
kdDebug(250) <<
"SlotCompleted hit for " << url.
prettyURL() <<
endl;
00397
KFileTreeViewItem *currParent =
findTVIByURL( url );
00398
if( ! currParent )
return;
00399
00400
kdDebug(250) <<
"current parent " << currParent <<
" is already listed: "
00401 << currParent->
alreadyListed() <<
endl;
00402
00403 emit(
populateFinished(currParent));
00404 emit(
directoryChildCount(currParent, currParent->childCount()));
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 currParent->
setListed(
true);
00415
00416
kdDebug(250) <<
"recurseChildren: " << m_recurseChildren <<
endl;
00417
kdDebug(250) <<
"isLocalFile: " << m_startURL.
isLocalFile() <<
endl;
00418
kdDebug(250) <<
"dirOnlyMode: " <<
dirOnlyMode() <<
endl;
00419
00420
00421
if( m_recurseChildren && (!m_startURL.
isLocalFile() || !
dirOnlyMode()) )
00422 {
00423
bool wantRecurseUrl =
false;
00424
00425
for ( KURL::List::Iterator it = m_openChildrenURLs.begin();
00426 it != m_openChildrenURLs.end(); ++it )
00427 {
00428
00429
if( (*it).equals( url,
true ) )
00430 wantRecurseUrl =
true;
00431 }
00432
00433
KFileTreeViewItem *nextChild = 0;
00434
kdDebug(250) <<
"Recursing " << url.
prettyURL() <<
"? " << wantRecurseUrl <<
endl;
00435
00436
if( wantRecurseUrl && currParent )
00437 {
00438
00439
00440
00441
00442 nextChild = static_cast<KFileTreeViewItem*>
00443 (static_cast<QListViewItem*>(currParent)->firstChild());
00444
00445
if( ! nextChild )
00446 {
00447
00448
kdDebug( 250 ) <<
"No children to recuse" <<
endl;
00449 }
00450
00451
00452
00453
00454 m_openChildrenURLs.remove(url);
00455 }
00456
00457
if( nextChild )
00458 {
00459
00460
00461
00462
00463
00464
00465
while( nextChild )
00466 {
00467
if( nextChild->
isDir() && ! nextChild->
alreadyListed())
00468 {
00469
KFileItem *kfi = nextChild->
fileItem();
00470
if( kfi && kfi->
isReadable())
00471 {
00472
KURL recurseUrl = kfi->
url();
00473
kdDebug(250) <<
"Starting to recurse NOW " << recurseUrl.
prettyURL() <<
endl;
00474
openURL( recurseUrl,
true );
00475 }
00476 }
00477 nextChild = static_cast<KFileTreeViewItem*>(static_cast<QListViewItem*>(nextChild->nextSibling()));
00478
00479 }
00480 }
00481 }
00482
else
00483 {
00484
kdDebug(250) <<
"skipping to recurse in complete-slot" <<
endl;
00485 }
00486 }
00487
00488
00489 bool KFileTreeBranch::populate(
const KURL& url,
KFileTreeViewItem *currItem )
00490 {
00491
bool ret =
false;
00492
if( ! currItem )
00493
return ret;
00494
00495
kdDebug(250) <<
"Populating <" << url.
prettyURL() <<
">" <<
endl;
00496
00497
00498
if( m_recurseChildren )
00499 {
00500 m_openChildrenURLs.append( url );
00501
kdDebug(250) <<
"Appending to list " << url.
prettyURL() <<
endl;
00502 }
00503
00504
if( ! currItem->
alreadyListed() )
00505 {
00506
00507 ret =
openURL( url,
true );
00508 }
00509
else
00510 {
00511
kdDebug(250) <<
"Children already existing in treeview!" <<
endl;
00512 slCompleted( url );
00513 ret =
true;
00514 }
00515
return ret;
00516 }
00517
00518
void KFileTreeBranch::virtual_hook(
int id,
void* data )
00519 { KDirLister::virtual_hook(
id, data ); }
00520
00521
#include "kfiletreebranch.moc"
00522