KIO
directorysizejob.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 2000, 2006 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 "directorysizejob.h" 00021 #include <kdebug.h> 00022 #include <QtCore/QTimer> 00023 00024 #include "jobuidelegate.h" 00025 #include "job_p.h" 00026 00027 namespace KIO 00028 { 00029 class DirectorySizeJobPrivate: public KIO::JobPrivate 00030 { 00031 public: 00032 DirectorySizeJobPrivate() 00033 : m_totalSize(0L) 00034 , m_totalFiles(0L) 00035 , m_totalSubdirs(0L) 00036 , m_currentItem(0) 00037 { 00038 } 00039 DirectorySizeJobPrivate( const KFileItemList & lstItems ) 00040 : m_totalSize(0L) 00041 , m_totalFiles(0L) 00042 , m_totalSubdirs(0L) 00043 , m_lstItems(lstItems) 00044 , m_currentItem(0) 00045 { 00046 } 00047 KIO::filesize_t m_totalSize; 00048 KIO::filesize_t m_totalFiles; 00049 KIO::filesize_t m_totalSubdirs; 00050 KFileItemList m_lstItems; 00051 int m_currentItem; 00052 QHash<long, QSet<long> > m_visitedInodes; // device -> set of inodes 00053 00054 void startNextJob( const KUrl & url ); 00055 void slotEntries( KIO::Job * , const KIO::UDSEntryList &); 00056 void processNextItem(); 00057 00058 Q_DECLARE_PUBLIC(DirectorySizeJob) 00059 00060 static inline DirectorySizeJob *newJob( const KUrl & directory ) 00061 { 00062 DirectorySizeJobPrivate *d = new DirectorySizeJobPrivate; 00063 DirectorySizeJob *job = new DirectorySizeJob(*d); 00064 job->setUiDelegate(new JobUiDelegate); 00065 d->startNextJob(directory); 00066 return job; 00067 } 00068 00069 static inline DirectorySizeJob *newJob( const KFileItemList & lstItems ) 00070 { 00071 DirectorySizeJobPrivate *d = new DirectorySizeJobPrivate(lstItems); 00072 DirectorySizeJob *job = new DirectorySizeJob(*d); 00073 job->setUiDelegate(new JobUiDelegate); 00074 QTimer::singleShot( 0, job, SLOT(processNextItem()) ); 00075 return job; 00076 } 00077 }; 00078 00079 } // namespace KIO 00080 00081 00082 using namespace KIO; 00083 00084 DirectorySizeJob::DirectorySizeJob(DirectorySizeJobPrivate &dd) 00085 : KIO::Job(dd) 00086 { 00087 } 00088 00089 DirectorySizeJob::~DirectorySizeJob() 00090 { 00091 } 00092 00093 KIO::filesize_t DirectorySizeJob::totalSize() const 00094 { 00095 return d_func()->m_totalSize; 00096 } 00097 00098 KIO::filesize_t DirectorySizeJob::totalFiles() const 00099 { 00100 return d_func()->m_totalFiles; 00101 } 00102 00103 KIO::filesize_t DirectorySizeJob::totalSubdirs() const 00104 { 00105 return d_func()->m_totalSubdirs; 00106 } 00107 00108 void DirectorySizeJobPrivate::processNextItem() 00109 { 00110 Q_Q(DirectorySizeJob); 00111 while (m_currentItem < m_lstItems.count()) 00112 { 00113 const KFileItem item = m_lstItems[m_currentItem++]; 00114 if ( !item.isLink() ) 00115 { 00116 if ( item.isDir() ) 00117 { 00118 //kDebug(7007) << "dir -> listing"; 00119 KUrl url = item.url(); 00120 startNextJob( url ); 00121 return; // we'll come back later, when this one's finished 00122 } 00123 else 00124 { 00125 m_totalSize += item.size(); 00126 m_totalFiles++; 00127 //kDebug(7007) << "file -> " << m_totalSize; 00128 } 00129 } else { 00130 m_totalFiles++; 00131 } 00132 } 00133 //kDebug(7007) << "finished"; 00134 q->emitResult(); 00135 } 00136 00137 void DirectorySizeJobPrivate::startNextJob( const KUrl & url ) 00138 { 00139 Q_Q(DirectorySizeJob); 00140 //kDebug(7007) << url; 00141 KIO::ListJob * listJob = KIO::listRecursive( url, KIO::HideProgressInfo ); 00142 listJob->addMetaData("details", "3"); 00143 q->connect( listJob, SIGNAL(entries(KIO::Job*,KIO::UDSEntryList)), 00144 SLOT(slotEntries(KIO::Job*,KIO::UDSEntryList))); 00145 q->addSubjob( listJob ); 00146 } 00147 00148 void DirectorySizeJobPrivate::slotEntries( KIO::Job*, const KIO::UDSEntryList & list ) 00149 { 00150 KIO::UDSEntryList::ConstIterator it = list.begin(); 00151 const KIO::UDSEntryList::ConstIterator end = list.end(); 00152 for (; it != end; ++it) { 00153 00154 const KIO::UDSEntry& entry = *it; 00155 const long device = entry.numberValue(KIO::UDSEntry::UDS_DEVICE_ID, 0); 00156 if (device) { 00157 // Hard-link detection (#67939) 00158 const long inode = entry.numberValue(KIO::UDSEntry::UDS_INODE, 0); 00159 QSet<long> & visitedInodes = m_visitedInodes[device]; // find or insert 00160 if (visitedInodes.contains(inode)) { 00161 continue; 00162 } 00163 visitedInodes.insert(inode); 00164 } 00165 const KIO::filesize_t size = entry.numberValue(KIO::UDSEntry::UDS_SIZE, 0); 00166 const QString name = entry.stringValue( KIO::UDSEntry::UDS_NAME ); 00167 if (name == ".") { 00168 m_totalSize += size; 00169 //kDebug(7007) << "'.': added" << size << "->" << m_totalSize; 00170 } else if (name != "..") { 00171 if (!entry.isLink()) 00172 m_totalSize += size; 00173 if (!entry.isDir()) 00174 m_totalFiles++; 00175 else 00176 m_totalSubdirs++; 00177 //kDebug(7007) << name << ":" << size << "->" << m_totalSize; 00178 } 00179 } 00180 } 00181 00182 void DirectorySizeJob::slotResult( KJob * job ) 00183 { 00184 Q_D(DirectorySizeJob); 00185 //kDebug(7007) << d->m_totalSize; 00186 removeSubjob(job); 00187 if (d->m_currentItem < d->m_lstItems.count()) 00188 { 00189 d->processNextItem(); 00190 } 00191 else 00192 { 00193 if (job->error()) { 00194 setError( job->error() ); 00195 setErrorText( job->errorText() ); 00196 } 00197 emitResult(); 00198 } 00199 } 00200 00201 //static 00202 DirectorySizeJob * KIO::directorySize( const KUrl & directory ) 00203 { 00204 return DirectorySizeJobPrivate::newJob(directory); // useless - but consistent with other jobs 00205 } 00206 00207 //static 00208 DirectorySizeJob * KIO::directorySize( const KFileItemList & lstItems ) 00209 { 00210 return DirectorySizeJobPrivate::newJob(lstItems); 00211 } 00212 00213 #include "directorysizejob.moc"
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:55:18 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Thu May 10 2012 20:55:18 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.