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