• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeio/tdefile
 

tdeio/tdefile

  • tdeio
  • tdefile
tdefiletreebranch.cpp
1 /* This file is part of the KDEproject
2  Copyright (C) 2000 David Faure <faure@kde.org>
3  2000 Carsten Pfeiffer <pfeiffer@kde.org>
4  2002 Klaas Freitag <freitag@suse.de>
5 
6  This library is free software; you can redistribute it and/or
7  modify it under the terms of the GNU Library General Public
8  License version 2 as published by the Free Software Foundation.
9 
10  This library is distributed in the hope that it will be useful,
11  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  Library General Public License for more details.
14 
15  You should have received a copy of the GNU Library General Public License
16  along with this library; see the file COPYING.LIB. If not, write to
17  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 
21 #include <tqfile.h>
22 
23 #include <tdefileitem.h>
24 #include <kdebug.h>
25 #include <kde_file.h>
26 
27 #include <sys/types.h>
28 #include <sys/stat.h>
29 #include <unistd.h>
30 
31 #include "tdefiletreeviewitem.h"
32 #include "tdefiletreebranch.h"
33 
34 
35 /* --- KFileTreeViewToplevelItem --- */
36 KFileTreeBranch::KFileTreeBranch( KFileTreeView *parent, const KURL& url,
37  const TQString& name,
38  const TQPixmap& pix, bool showHidden,
39  KFileTreeViewItem *branchRoot )
40 
41  : KDirLister( false ),
42  m_root( branchRoot ),
43  m_startURL( url ),
44  m_name ( name ),
45  m_rootIcon( pix ),
46  m_openRootIcon( pix ),
47  m_recurseChildren(true),
48  m_showExtensions(true)
49 {
50  kdDebug( 250) << "Creating branch for url " << url.prettyURL() << endl;
51 
52  /* if non exists, create one */
53  if( ! branchRoot )
54  {
55  m_root = new KFileTreeViewItem( parent,
56  new KFileItem( url, "inode/directory",
57  S_IFDIR ),
58  this );
59  }
60 
61  m_root->setExpandable( true );
62  m_root->setPixmap( 0, pix );
63  m_root->setText( 0, name );
64 
65  setShowingDotFiles( showHidden );
66 
67  connect( this, TQT_SIGNAL( refreshItems(const KFileItemList&)),
68  this, TQT_SLOT ( slotRefreshItems( const KFileItemList& )));
69 
70  connect( this, TQT_SIGNAL( newItems(const KFileItemList&)),
71  this, TQT_SLOT ( addItems( const KFileItemList& )));
72 
73  connect( this, TQT_SIGNAL( completed(const KURL& )),
74  this, TQT_SLOT(slCompleted(const KURL&)));
75 
76  connect( this, TQT_SIGNAL( started( const KURL& )),
77  this, TQT_SLOT( slotListerStarted( const KURL& )));
78 
79  connect( this, TQT_SIGNAL( deleteItem( KFileItem* )),
80  this, TQT_SLOT( slotDeleteItem( KFileItem* )));
81 
82  connect( this, TQT_SIGNAL( canceled(const KURL&) ),
83  this, TQT_SLOT( slotCanceled(const KURL&) ));
84 
85  connect( this, TQT_SIGNAL( clear()),
86  this, TQT_SLOT( slotDirlisterClear()));
87 
88  connect( this, TQT_SIGNAL( clear(const KURL&)),
89  this, TQT_SLOT( slotDirlisterClearURL(const KURL&)));
90 
91  connect( this, TQT_SIGNAL( redirection( const KURL& , const KURL& ) ),
92  this, TQT_SLOT( slotRedirect( const KURL&, const KURL& )));
93 
94  m_openChildrenURLs.append( url );
95 }
96 
97 void KFileTreeBranch::setOpenPixmap( const TQPixmap& pix )
98 {
99  m_openRootIcon = pix;
100 
101  if( root()->isOpen())
102  {
103  root()->setPixmap( 0, pix );
104  }
105 }
106 
107 void KFileTreeBranch::slotListerStarted( const KURL &url )
108 {
109  /* set the parent correct if it is zero. */
110  kdDebug( 250) << "Starting to list " << url.prettyURL() << endl;
111 }
112 
113 
114 KFileTreeViewItem *KFileTreeBranch::parentKFTVItem( KFileItem *item )
115 {
116  KFileTreeViewItem *parent = 0;
117 
118  if( ! item ) return 0;
119 
120  /* If it is a directory, check, if it exists in the dict. If not, go one up
121  * and check again.
122  */
123  KURL url = item->url();
124  // kdDebug(250) << "Item's url is " << url.prettyURL() << endl;
125  KURL dirUrl( url );
126  dirUrl.setFileName( TQString::null );
127  // kdDebug(250) << "Directory url is " << dirUrl.prettyURL() << endl;
128 
129  parent = findTVIByURL( dirUrl );
130  // kdDebug(250) << "Returning as parent item <" << parent << ">" << endl;
131  return( parent );
132 }
133 
134 
135 void KFileTreeBranch::slotRefreshItems( const KFileItemList& list )
136 {
137  KFileItemListIterator it( list );
138  kdDebug(250) << "Refreshing " << list.count() << " items !" << endl;
139  KFileItem *currItem;
140  KFileTreeViewItem *item = 0;
141 
142  while ( (currItem = it.current()) != 0 )
143  {
144  item = findTVIByURL(currItem->url());
145  if (item) {
146  item->setPixmap(0, item->fileItem()->pixmap( TDEIcon::SizeSmall ));
147  item->setText( 0, item->fileItem()->text());
148  }
149  ++it;
150  }
151 }
152 
153 void KFileTreeBranch::addItems( const KFileItemList& list )
154 {
155  KFileItemListIterator it( list );
156  kdDebug(250) << "Adding " << list.count() << " items !" << endl;
157  KFileItem *currItem;
158  KFileTreeViewItemList treeViewItList;
159  KFileTreeViewItem *parentItem = 0;
160 
161  while ( (currItem = it.current()) != 0 )
162  {
163  parentItem = parentKFTVItem( currItem );
164 
165 
166  /* Only create a new KFileTreeViewItem if it does not yet exist */
167  KFileTreeViewItem *newKFTVI =
168  static_cast<KFileTreeViewItem *>(currItem->extraData( this ));
169 
170  if( ! newKFTVI )
171  {
172  newKFTVI = createTreeViewItem( parentItem, currItem );
173  if (!newKFTVI)
174  {
175  // TODO: Don't fail if parentItem == 0
176  ++it;
177  continue;
178  }
179  currItem->setExtraData( this, newKFTVI );
180 
181  /* Cut off the file extension in case it is not a directory */
182  if( !m_showExtensions && !currItem->isDir() ) /* Need to cut the extension */
183  {
184  TQString name = currItem->text();
185  int mPoint = name.findRev( '.' );
186  if( mPoint > 0 )
187  name = name.left( mPoint );
188  newKFTVI->setText( 0, name );
189  }
190  }
191 
192  /* Now try to find out if there are children for dirs in the treeview */
193  /* This stats a directory on the local file system and checks the */
194  /* hardlink entry in the stat-buf. This works only for local directories. */
195  if( dirOnlyMode() && !m_recurseChildren && currItem->isLocalFile( ) && currItem->isDir() )
196  {
197  KURL url = currItem->url();
198  TQString filename = url.directory( false, true ) + url.fileName();
199  /* do the stat trick of Carsten. The problem is, that the hardlink
200  * count only contains directory links. Thus, this method only seem
201  * to work in dir-only mode */
202  kdDebug(250) << "Doing stat on " << filename << endl;
203  KDE_struct_stat statBuf;
204  if( KDE_stat( TQFile::encodeName( filename ), &statBuf ) == 0 )
205  {
206  int hardLinks = statBuf.st_nlink; /* Count of dirs */
207  kdDebug(250) << "stat succeeded, hardlinks: " << hardLinks << endl;
208  // If the link count is > 2, the directory likely has subdirs. If it's < 2
209  // it's something weird like a mounted SMB share. In that case we don't know
210  // if there are subdirs, thus show it as expandable.
211 
212  if( hardLinks != 2 )
213  {
214  newKFTVI->setExpandable(true);
215  }
216  else
217  {
218  newKFTVI->setExpandable(false);
219  }
220  if( hardLinks >= 2 ) // "Normal" directory with subdirs
221  {
222  kdDebug(250) << "Emitting for " << url.prettyURL() << endl;
223  emit( directoryChildCount( newKFTVI, hardLinks-2)); // parentItem, hardLinks-1 ));
224  }
225  }
226  else
227  {
228  kdDebug(250) << "stat of " << filename << " failed !" << endl;
229  }
230  }
231  ++it;
232 
233  treeViewItList.append( newKFTVI );
234  }
235 
236  emit newTreeViewItems( this, treeViewItList );
237 }
238 
239 KFileTreeViewItem* KFileTreeBranch::createTreeViewItem( KFileTreeViewItem *parent,
240  KFileItem *fileItem )
241 {
242  KFileTreeViewItem *tvi = 0;
243  if( parent && fileItem )
244  {
245  tvi = new KFileTreeViewItem( parent,
246  fileItem,
247  this );
248  }
249  else
250  {
251  kdDebug(250) << "createTreeViewItem: Have no parent" << endl;
252  }
253  return( tvi );
254 }
255 
256 void KFileTreeBranch::setChildRecurse( bool t )
257 {
258  m_recurseChildren = t;
259  if( t == false )
260  m_openChildrenURLs.clear();
261 }
262 
263 
264 void KFileTreeBranch::setShowExtensions( bool visible )
265 {
266  m_showExtensions = visible;
267 }
268 
269 bool KFileTreeBranch::showExtensions( ) const
270 {
271  return( m_showExtensions );
272 }
273 
274 /*
275  * The signal that tells that a directory was deleted may arrive before the signal
276  * for its children arrive. Thus, we must walk through the children of a dir and
277  * remove them before removing the dir itself.
278  */
279 void KFileTreeBranch::slotDeleteItem( KFileItem *it )
280 {
281  if( !it ) return;
282  kdDebug(250) << "Slot Delete Item hitted for " << it->url().prettyURL() << endl;
283 
284  KFileTreeViewItem *kfti = static_cast<KFileTreeViewItem*>(it->extraData(this));
285 
286  if( kfti )
287  {
288  kdDebug( 250 ) << "Child count: " << kfti->childCount() << endl;
289  if( kfti->childCount() > 0 )
290  {
291  KFileTreeViewItem *child = static_cast<KFileTreeViewItem*>(kfti->firstChild());
292 
293  while( child )
294  {
295  kdDebug(250) << "Calling child to be deleted !" << endl;
296  KFileTreeViewItem *nextChild = static_cast<KFileTreeViewItem*>(child->nextSibling());
297  slotDeleteItem( child->fileItem());
298  child = nextChild;
299  }
300  }
301 
302  kdDebug(250) << "Found corresponding KFileTreeViewItem" << endl;
303  if( m_lastFoundURL.equals(it->url(), true ))
304  {
305  m_lastFoundURL = KURL();
306  m_lastFoundItem = 0L;
307  }
308  delete( kfti );
309  }
310  else
311  {
312  kdDebug(250) << "Error: tdefiletreeviewitem: "<< kfti << endl;
313  }
314 }
315 
316 
317 void KFileTreeBranch::slotCanceled( const KURL& url )
318 {
319  // ### anything else to do?
320  // remove the url from the childrento-recurse-list
321  m_openChildrenURLs.remove( url);
322 
323  // stop animations etc.
324  KFileTreeViewItem *item = findTVIByURL(url);
325  if (!item) return; // Uh oh...
326  emit populateFinished(item);
327 }
328 
329 void KFileTreeBranch::slotDirlisterClear()
330 {
331  kdDebug(250)<< "*** Clear all !" << endl;
332  /* this slots needs to clear all listed items, but NOT the root item */
333  if( m_root )
334  deleteChildrenOf( m_root );
335 }
336 
337 void KFileTreeBranch::slotDirlisterClearURL( const KURL& url )
338 {
339  kdDebug(250)<< "*** Clear for URL !" << url.prettyURL() << endl;
340  KFileItem *item = findByURL( url );
341  if( item )
342  {
343  KFileTreeViewItem *ftvi =
344  static_cast<KFileTreeViewItem *>(item->extraData( this ));
345  deleteChildrenOf( ftvi );
346  }
347 }
348 
349 void KFileTreeBranch::deleteChildrenOf( TQListViewItem *parent )
350 {
351  // for some strange reason, slotDirlisterClearURL() sometimes calls us
352  // with a 0L parent.
353  if ( !parent )
354  return;
355 
356  while ( parent->firstChild() )
357  delete parent->firstChild();
358 }
359 
360 void KFileTreeBranch::slotRedirect( const KURL& oldUrl, const KURL&newUrl )
361 {
362  if( oldUrl.equals( m_startURL, true ))
363  {
364  m_startURL = newUrl;
365  }
366 }
367 
368 KFileTreeViewItem* KFileTreeBranch::findTVIByURL( const KURL& url )
369 {
370  KFileTreeViewItem *resultItem = 0;
371 
372  if( m_startURL.equals(url, true) )
373  {
374  kdDebug(250) << "findByURL: Returning root as a parent !" << endl;
375  resultItem = m_root;
376  }
377  else if( m_lastFoundURL.equals( url, true ))
378  {
379  kdDebug(250) << "findByURL: Returning from lastFoundURL!" << endl;
380  resultItem = m_lastFoundItem;
381  }
382  else
383  {
384  kdDebug(250) << "findByURL: searching by dirlister: " << url.url() << endl;
385 
386  KFileItem *it = findByURL( url );
387 
388  if( it )
389  {
390  resultItem = static_cast<KFileTreeViewItem*>(it->extraData(this));
391  m_lastFoundItem = resultItem;
392  m_lastFoundURL = url;
393  }
394  }
395 
396  return( resultItem );
397 }
398 
399 
400 void KFileTreeBranch::slCompleted( const KURL& url )
401 {
402  kdDebug(250) << "SlotCompleted hit for " << url.prettyURL() << endl;
403  KFileTreeViewItem *currParent = findTVIByURL( url );
404  if( ! currParent ) return;
405 
406  kdDebug(250) << "current parent " << currParent << " is already listed: "
407  << currParent->alreadyListed() << endl;
408 
409  emit( populateFinished(currParent));
410  emit( directoryChildCount(currParent, currParent->childCount()));
411 
412  /* This is a walk through the children of the last populated directory.
413  * Here we start the dirlister on every child of the dir and wait for its
414  * finish. When it has finished, we go to the next child.
415  * This must be done for non local file systems in dirOnly- and Full-Mode
416  * and for local file systems only in full mode, because the stat trick
417  * (see addItem-Method) does only work for dirs, not for files in the directory.
418  */
419  /* Set bit that the parent dir was listed completely */
420  currParent->setListed(true);
421 
422  kdDebug(250) << "recurseChildren: " << m_recurseChildren << endl;
423  kdDebug(250) << "isLocalFile: " << m_startURL.isLocalFile() << endl;
424  kdDebug(250) << "dirOnlyMode: " << dirOnlyMode() << endl;
425 
426 
427  if( m_recurseChildren && (!m_startURL.isLocalFile() || ! dirOnlyMode()) )
428  {
429  bool wantRecurseUrl = false;
430  /* look if the url is in the list for url to recurse */
431  for ( KURL::List::Iterator it = m_openChildrenURLs.begin();
432  it != m_openChildrenURLs.end(); ++it )
433  {
434  /* it is only interesting that the url _is_in_ the list. */
435  if( (*it).equals( url, true ) )
436  wantRecurseUrl = true;
437  }
438 
439  KFileTreeViewItem *nextChild = 0;
440  kdDebug(250) << "Recursing " << url.prettyURL() << "? " << wantRecurseUrl << endl;
441 
442  if( wantRecurseUrl && currParent )
443  {
444 
445  /* now walk again through the tree and populate the children to get +-signs */
446  /* This is the starting point. The visible folder has finished,
447  processing the children has not yet started */
448  nextChild = static_cast<KFileTreeViewItem*>
449  (static_cast<TQListViewItem*>(currParent)->firstChild());
450 
451  if( ! nextChild )
452  {
453  /* This happens if there is no child at all */
454  kdDebug( 250 ) << "No children to recuse" << endl;
455  }
456 
457  /* Since we have listed the children to recurse, we can remove the entry
458  * in the list of the URLs to see the children.
459  */
460  m_openChildrenURLs.remove(url);
461  }
462 
463  if( nextChild ) /* This implies that idx > -1 */
464  {
465  /* Next child is defined. We start a dirlister job on every child item
466  * which is a directory to find out how much children are in the child
467  * of the last opened dir
468  */
469 
470  /* Skip non directory entries */
471  while( nextChild )
472  {
473  if( nextChild->isDir() && ! nextChild->alreadyListed())
474  {
475  KFileItem *kfi = nextChild->fileItem();
476  if( kfi && kfi->isReadable())
477  {
478  KURL recurseUrl = kfi->url();
479  kdDebug(250) << "Starting to recurse NOW " << recurseUrl.prettyURL() << endl;
480  openURL( recurseUrl, true );
481  }
482  }
483  nextChild = static_cast<KFileTreeViewItem*>(static_cast<TQListViewItem*>(nextChild->nextSibling()));
484  // kdDebug(250) << "Next child " << m_nextChild << endl;
485  }
486  }
487  }
488  else
489  {
490  kdDebug(250) << "skipping to recurse in complete-slot" << endl;
491  }
492 }
493 
494 /* This slot is called when a treeviewitem is expanded in the gui */
495 bool KFileTreeBranch::populate( const KURL& url, KFileTreeViewItem *currItem )
496 {
497  bool ret = false;
498  if( ! currItem )
499  return ret;
500 
501  kdDebug(250) << "Populating <" << url.prettyURL() << ">" << endl;
502 
503  /* Add this url to the list of urls to recurse for children */
504  if( m_recurseChildren )
505  {
506  m_openChildrenURLs.append( url );
507  kdDebug(250) << "Appending to list " << url.prettyURL() << endl;
508  }
509 
510  if( ! currItem->alreadyListed() )
511  {
512  /* start the lister */
513  ret = openURL( url, true );
514  }
515  else
516  {
517  kdDebug(250) << "Children already existing in treeview!" << endl;
518  slCompleted( url );
519  ret = true;
520  }
521  return ret;
522 }
523 
524 void KFileTreeBranch::virtual_hook( int id, void* data )
525 { KDirLister::virtual_hook( id, data ); }
526 
527 #include "tdefiletreebranch.moc"
528 
KFileTreeViewItem::setListed
void setListed(bool wasListed)
set the flag if the directory was already listed.
Definition: tdefiletreeviewitem.cpp:65
KFileTreeBranch::name
TQString name() const
Definition: tdefiletreebranch.h:87
KFileTreeBranch::populate
virtual bool populate(const KURL &url, KFileTreeViewItem *currItem)
populates a branch.
Definition: tdefiletreebranch.cpp:495
KFileTreeViewItem::fileItem
KFileItem * fileItem() const
Definition: tdefiletreeviewitem.h:55
KFileTreeView
The filetreeview offers a treeview on the file system which behaves like a QTreeView showing files an...
Definition: tdefiletreeview.h:66
KFileTreeViewItem
An item for a KFileTreeView that knows about its own KFileItem.
Definition: tdefiletreeviewitem.h:40
KFileTreeViewItem::alreadyListed
bool alreadyListed() const
Definition: tdefiletreeviewitem.cpp:60
KFileTreeBranch::root
KFileTreeViewItem * root()
Definition: tdefiletreebranch.h:82
KFileTreeBranch::showExtensions
bool showExtensions() const
Definition: tdefiletreebranch.cpp:269
KFileTreeBranch::createTreeViewItem
virtual KFileTreeViewItem * createTreeViewItem(KFileTreeViewItem *parent, KFileItem *fileItem)
allocates a KFileTreeViewItem for the branch for new items.
Definition: tdefiletreebranch.cpp:239
KFileTreeBranch::populateFinished
void populateFinished(KFileTreeViewItem *)
emitted with the item of a directory which was finished to populate
KFileTreeBranch::newTreeViewItems
void newTreeViewItems(KFileTreeBranch *, const KFileTreeViewItemList &)
emitted with a list of new or updated KFileTreeViewItem which were found in a branch.
KFileTreeBranch::KFileTreeBranch
KFileTreeBranch(KFileTreeView *, const KURL &url, const TQString &name, const TQPixmap &pix, bool showHidden=false, KFileTreeViewItem *branchRoot=0)
constructs a branch for KFileTreeView.
Definition: tdefiletreebranch.cpp:36
KFileTreeViewItem::isDir
bool isDir() const
Definition: tdefiletreeviewitem.cpp:80
KFileTreeBranch::setShowExtensions
virtual void setShowExtensions(bool visible=true)
sets printing of the file extensions on or off.
Definition: tdefiletreebranch.cpp:264
KFileTreeBranch::findTVIByURL
virtual KFileTreeViewItem * findTVIByURL(const KURL &)
find the according KFileTreeViewItem by an url
Definition: tdefiletreebranch.cpp:368
KFileTreeBranch::setChildRecurse
void setChildRecurse(bool t=true)
sets if children recursion is wanted or not.
Definition: tdefiletreebranch.cpp:256
KFileTreeBranch::directoryChildCount
void directoryChildCount(KFileTreeViewItem *item, int count)
emitted with the exact count of children for a directory.
KFileTreeViewItem::url
KURL url() const
Definition: tdefiletreeviewitem.cpp:70

tdeio/tdefile

Skip menu "tdeio/tdefile"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

tdeio/tdefile

Skip menu "tdeio/tdefile"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  •     tdecore
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  • tdeioslave
  •   http
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeio/tdefile by doxygen 1.8.8
This website is maintained by Timothy Pearson.