kdirsize.cpp
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000 David Faure <faure@kde.org> 00003 00004 This library is free software; you can redistribute it and/or 00005 modify it under the terms of the GNU Library General Public 00006 License as published by the Free Software Foundation; either 00007 version 2 of the License, or (at your option) any later version. 00008 00009 This library is distributed in the hope that it will be useful, 00010 but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 Library General Public License for more details. 00013 00014 You should have received a copy of the GNU Library General Public License 00015 along with this library; see the file COPYING.LIB. If not, write to 00016 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00017 Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "kdirsize.h" 00021 #include <kdebug.h> 00022 #include <kglobal.h> 00023 #include <qapplication.h> 00024 #include <qtimer.h> 00025 #include <config-kfile.h> 00026 00027 using namespace KIO; 00028 00029 KDirSize::KDirSize( const KURL & directory ) 00030 : KIO::Job(false /*No GUI*/), m_bAsync(true), m_totalSize(0L), m_totalFiles(0L), m_totalSubdirs(0L) 00031 { 00032 startNextJob( directory ); 00033 } 00034 00035 KDirSize::KDirSize( const KFileItemList & lstItems ) 00036 : KIO::Job(false /*No GUI*/), m_bAsync(true), m_totalSize(0L), m_totalFiles(0L), m_totalSubdirs(0L), m_lstItems(lstItems) 00037 { 00038 QTimer::singleShot( 0, this, SLOT(processList()) ); 00039 } 00040 00041 void KDirSize::processList() 00042 { 00043 while (!m_lstItems.isEmpty()) 00044 { 00045 KFileItem * item = m_lstItems.first(); 00046 m_lstItems.removeFirst(); 00047 if ( !item->isLink() ) 00048 { 00049 if ( item->isDir() ) 00050 { 00051 kdDebug(kfile_area) << "KDirSize::processList dir -> listing" << endl; 00052 KURL url = item->url(); 00053 startNextJob( url ); 00054 return; // we'll come back later, when this one's finished 00055 } 00056 else 00057 { 00058 m_totalSize += item->size(); 00059 // no long long with kdDebug() 00060 // kdDebug(kfile_area) << "KDirSize::processList file -> " << m_totalSize << endl; 00061 } 00062 } 00063 } 00064 kdDebug(kfile_area) << "KDirSize::processList finished" << endl; 00065 if ( !m_bAsync ) 00066 qApp->exit_loop(); 00067 emitResult(); 00068 } 00069 00070 void KDirSize::startNextJob( const KURL & url ) 00071 { 00072 KIO::ListJob * listJob = KIO::listRecursive( url, false /* no GUI */ ); 00073 connect( listJob, SIGNAL(entries( KIO::Job *, 00074 const KIO::UDSEntryList& )), 00075 SLOT( slotEntries( KIO::Job*, 00076 const KIO::UDSEntryList& ))); 00077 addSubjob( listJob ); 00078 } 00079 00080 void KDirSize::slotEntries( KIO::Job*, const KIO::UDSEntryList & list ) 00081 { 00082 static const QString& dot = KGlobal::staticQString( "." ); 00083 static const QString& dotdot = KGlobal::staticQString( ".." ); 00084 KIO::UDSEntryListConstIterator it = list.begin(); 00085 KIO::UDSEntryListConstIterator end = list.end(); 00086 for (; it != end; ++it) { 00087 KIO::UDSEntry::ConstIterator it2 = (*it).begin(); 00088 KIO::filesize_t size = 0; 00089 bool isLink = false; 00090 bool isDir = false; 00091 QString name; 00092 for( ; it2 != (*it).end(); it2++ ) { 00093 switch( (*it2).m_uds ) { 00094 case KIO::UDS_NAME: 00095 name = (*it2).m_str; 00096 break; 00097 case KIO::UDS_LINK_DEST: 00098 isLink = !(*it2).m_str.isEmpty(); 00099 break; 00100 case KIO::UDS_SIZE: 00101 size = ((*it2).m_long); 00102 break; 00103 case KIO::UDS_FILE_TYPE: 00104 isDir = S_ISDIR((*it2).m_long); 00105 break; 00106 default: 00107 break; 00108 } 00109 } 00110 if ( name == dot ) 00111 m_totalSize += size; 00112 else if ( name != dotdot ) 00113 { 00114 if (!isLink) 00115 m_totalSize += size; 00116 if (!isDir) 00117 m_totalFiles++; 00118 else 00119 m_totalSubdirs++; 00120 //kdDebug(kfile_area) << name << ":" << size << endl; 00121 } 00122 } 00123 } 00124 00125 //static 00126 KDirSize * KDirSize::dirSizeJob( const KURL & directory ) 00127 { 00128 return new KDirSize( directory ); // useless - but consistent with other jobs 00129 } 00130 00131 //static 00132 KDirSize * KDirSize::dirSizeJob( const KFileItemList & lstItems ) 00133 { 00134 return new KDirSize( lstItems ); 00135 } 00136 00137 //static 00138 KIO::filesize_t KDirSize::dirSize( const KURL & directory ) 00139 { 00140 KDirSize * dirSize = dirSizeJob( directory ); 00141 dirSize->setSync(); 00142 qApp->enter_loop(); 00143 return dirSize->totalSize(); 00144 } 00145 00146 00147 void KDirSize::slotResult( KIO::Job * job ) 00148 { 00149 kdDebug(kfile_area) << " KDirSize::slotResult( KIO::Job * job ) m_lstItems:" << m_lstItems.count() << endl; 00150 if ( !m_lstItems.isEmpty() ) 00151 { 00152 subjobs.remove(job); // Remove job, but don't kill this job. 00153 processList(); 00154 } 00155 else 00156 { 00157 if ( !m_bAsync ) 00158 qApp->exit_loop(); 00159 KIO::Job::slotResult( job ); 00160 } 00161 } 00162 00163 void KDirSize::virtual_hook( int id, void* data ) 00164 { KIO::Job::virtual_hook( id, data ); } 00165 00166 #include "kdirsize.moc"