kio: reimplement KDirLister

has to be done to fix the caching issues, bonus points for being much
simpler and cleaner

Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
Ivailo Monev 2023-06-30 18:51:02 +03:00
parent 82998dfd97
commit fd93fbbecc
19 changed files with 505 additions and 6262 deletions

View file

@ -49,7 +49,6 @@
7001 kio (KDirWatch)
7002 kio (Slave)
7003 kio (KDirLister)
7004 kio (KDirListerCache)
7006 kio (Scheduler)
7007 kio (KIOJob)
7008 kio (KDirModel)

View file

@ -220,7 +220,7 @@ public:
void _k_slotToggleDirsFirst();
void _k_slotToggleIgnoreCase();
void _k_slotStarted();
void _k_slotProgress(int);
void _k_slotProgress(ulong);
void _k_slotShowProgress();
void _k_slotIOFinished();
void _k_slotCanceled();
@ -553,7 +553,7 @@ bool KDirOperator::isSelected(const KFileItem &item) const
int KDirOperator::numDirs() const
{
return (d->dirLister == 0) ? 0 : d->dirLister->directories().count();
return (d->dirLister == 0) ? 0 : 1;
}
int KDirOperator::numFiles() const
@ -1016,7 +1016,7 @@ void KDirOperator::setUrl(const KUrl& _newurl, bool clearforward)
void KDirOperator::updateDir()
{
QApplication::setOverrideCursor(Qt::WaitCursor);
d->dirLister->emitChanges();
d->dirLister->updateDirectory();
QApplication::restoreOverrideCursor();
}
@ -1576,16 +1576,15 @@ void KDirOperator::setDirLister(KDirLister *lister)
d->dirLister->setMainWindow(mainWidget);
kDebug(kfile_area) << "mainWidget=" << mainWidget;
connect(d->dirLister, SIGNAL(percent(int)),
SLOT(_k_slotProgress(int)));
connect(d->dirLister, SIGNAL(started(KUrl)), SLOT(_k_slotStarted()));
connect(d->dirLister, SIGNAL(percent(ulong)),
SLOT(_k_slotProgress(ulong)));
connect(d->dirLister, SIGNAL(started()), SLOT(_k_slotStarted()));
connect(d->dirLister, SIGNAL(completed()), SLOT(_k_slotIOFinished()));
connect(d->dirLister, SIGNAL(canceled()), SLOT(_k_slotCanceled()));
connect(d->dirLister, SIGNAL(redirection(KUrl)),
SLOT(_k_slotRedirected(KUrl)));
connect(d->dirLister, SIGNAL(newItems(KFileItemList)), SLOT(_k_slotItemsChanged()));
connect(d->dirLister, SIGNAL(itemsAdded(KFileItemList)), SLOT(_k_slotItemsChanged()));
connect(d->dirLister, SIGNAL(itemsDeleted(KFileItemList)), SLOT(_k_slotItemsChanged()));
connect(d->dirLister, SIGNAL(itemsFilteredByMime(KFileItemList)), SLOT(_k_slotItemsChanged()));
connect(d->dirLister, SIGNAL(clear()), SLOT(_k_slotItemsChanged()));
}
@ -2168,7 +2167,7 @@ void KDirOperator::Private::_k_slotShowProgress()
QApplication::flush();
}
void KDirOperator::Private::_k_slotProgress(int percent)
void KDirOperator::Private::_k_slotProgress(ulong percent)
{
progressBar->setValue(percent);
// we have to redraw this as fast as possible

View file

@ -895,7 +895,7 @@ private:
Q_PRIVATE_SLOT( d, void _k_slotToggleDirsFirst() )
Q_PRIVATE_SLOT( d, void _k_slotToggleIgnoreCase() )
Q_PRIVATE_SLOT( d, void _k_slotStarted() )
Q_PRIVATE_SLOT( d, void _k_slotProgress(int) )
Q_PRIVATE_SLOT( d, void _k_slotProgress(ulong) )
Q_PRIVATE_SLOT( d, void _k_slotShowProgress() )
Q_PRIVATE_SLOT( d, void _k_slotIOFinished() )
Q_PRIVATE_SLOT( d, void _k_slotCanceled() )

View file

@ -438,7 +438,7 @@ KFilePreviewGenerator::Private::Private(KFilePreviewGenerator* parent,
m_previewShown = false;
} else {
KDirModel* dirModel = m_dirModel.data();
connect(dirModel->dirLister(), SIGNAL(newItems(KFileItemList)),
connect(dirModel->dirLister(), SIGNAL(itemsAdded(KFileItemList)),
q, SLOT(updateIcons(KFileItemList)));
connect(dirModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)),
q, SLOT(updateIcons(QModelIndex,QModelIndex)));
@ -619,11 +619,9 @@ void KFilePreviewGenerator::Private::addToPreviewQueue(const KFileItem& item, co
KUrl itemParentDir(item.url());
itemParentDir.setPath(itemParentDir.directory());
foreach (const KUrl& dir, dirModel->dirLister()->directories()) {
if (dir == itemParentDir || !dir.hasPath()) {
isOldPreview = false;
break;
}
const KUrl dirUrl = dirModel->dirLister()->url();
if (dirUrl == itemParentDir || !dirUrl.hasPath()) {
isOldPreview = false;
}
if (isOldPreview) {
return;
@ -683,13 +681,8 @@ void KFilePreviewGenerator::Private::updateCutItems()
DataChangeObtainer obt(this);
clearCutItemsCache();
KFileItemList items;
KDirLister* dirLister = dirModel->dirLister();
const KUrl::List dirs = dirLister->directories();
foreach (const KUrl& url, dirs) {
items << dirLister->itemsForDir(url);
}
applyCutItemEffect(items);
applyCutItemEffect(dirLister->items());
}
void KFilePreviewGenerator::Private::clearCutItemsCache()

View file

@ -724,17 +724,6 @@ void CopyJobPrivate::statCurrentSrc()
return;
}
// Let's see if we can skip stat'ing, for the case where a directory view has the info already
const KFileItem cachedItem = KDirLister::cachedItemForUrl(m_currentSrcURL);
KIO::UDSEntry entry;
if (!cachedItem.isNull()) {
entry = cachedItem.entry();
if (destinationState != DEST_DOESNT_EXIST) { // only resolve src if we could resolve dest (#218719)
bool dummyIsLocal;
m_currentSrcURL = cachedItem.mostLocalUrl(dummyIsLocal); // #183585
}
}
if (m_mode == CopyJob::Move && (
// Don't go renaming right away if we need a stat() to find out the destination filename
KProtocolManager::fileNameUsedForCopying(m_currentSrcURL) == KProtocolInfo::FromUrl ||
@ -774,15 +763,6 @@ void CopyJobPrivate::statCurrentSrc()
m_bOnlyRenames = false;
// Testing for entry.count()>0 here is not good enough; KFileItem inserts
// entries for UDS_USER and UDS_GROUP even on initially empty UDSEntries (#192185)
if (entry.contains(KIO::UDSEntry::UDS_NAME)) {
kDebug(7007) << "fast path! found info about" << m_currentSrcURL << "in KDirLister";
// sourceStated(entry, m_currentSrcURL); // don't recurse, see #319747, use queued invokeMethod instead
QMetaObject::invokeMethod(q, "sourceStated", Qt::QueuedConnection, Q_ARG(KIO::UDSEntry, entry), Q_ARG(KUrl, m_currentSrcURL));
return;
}
// Stat the next src url
Job * job = KIO::stat( m_currentSrcURL, StatJob::SourceSide, 2, KIO::HideProgressInfo );
//kDebug(7007) << "KIO::stat on" << m_currentSrcURL;

View file

@ -211,17 +211,6 @@ void DeleteJobPrivate::statNextSrc()
// Stat it
state = DELETEJOB_STATE_STATING;
// Fast path for KFileItems in directory views
while(m_currentStat != m_srcList.end()) {
m_currentURL = (*m_currentStat);
const KFileItem cachedItem = KDirLister::cachedItemForUrl(m_currentURL);
if (cachedItem.isNull())
break;
//kDebug(7007) << "Found cached info about" << m_currentURL << "isDir=" << cachedItem.isDir() << "isLink=" << cachedItem.isLink();
currentSourceStated(cachedItem.isDir(), cachedItem.isLink());
++m_currentStat;
}
// Hook for unit test to disable the fast path.
if (!kio_resolve_local_urls) {

File diff suppressed because it is too large Load diff

View file

@ -22,13 +22,13 @@
#define KDIRLISTER_H
#include "kfileitem.h"
#include "kdirnotify.h"
#include <kurl.h>
class KJob;
namespace KIO { class Job; class ListJob; }
class KDirListerPrivate;
/**
* @short Helper class for the kiojob used to list and update a directory.
*
@ -116,17 +116,6 @@ public:
*/
virtual void stop();
/**
* Stop listing the given directory.
*
* Emits canceled() if the killed job was the last running one.
* Emits canceled( const KUrl& ) for the killed job if
* there are at least two directories being watched by KDirLister.
* No signal is emitted if there was no job running for @p url.
* @param url the directory URL
*/
virtual void stop(const KUrl &url);
/**
* @return true if the "delayed mimetypes" feature was enabled
* @see setDelayedMimeTypes
@ -143,7 +132,6 @@ public:
*/
void setDelayedMimeTypes(bool delayedMimeTypes);
/**
* Checks whether KDirWatch will automatically update directories. This is
* enabled by default.
@ -155,6 +143,7 @@ public:
* Enable/disable automatic directory updating, when a directory changes
* (using KDirWatch).
* @param enable true to enable, false to disable
* @note Call updateDirectory() afterwards for the changes to take effect.
*/
virtual void setAutoUpdate(bool enable);
@ -176,7 +165,7 @@ public:
* top-level
* @see autoErrorHandlingEnabled()
*/
void setAutoErrorHandlingEnabled( bool enable, QWidget *parent );
void setAutoErrorHandlingEnabled(bool enable, QWidget *parent);
/**
* Checks whether hidden files (files beginning with a dot) will be
@ -189,10 +178,10 @@ public:
/**
* Changes the "is viewing dot files" setting.
* You need to call emitChanges() afterwards.
* By default this option is disabled (hidden files will not be shown).
* @param showDotFiles true to enable showing hidden files, false to
* disable
* @note Call updateDirectory() afterwards for the changes to take effect.
* @see showingDotFiles()
*/
virtual void setShowingDotFiles(bool showDotFiles);
@ -207,9 +196,9 @@ public:
/**
* Call this to list only directories.
* You need to call emitChanges() afterwards.
* By default this option is disabled (all files will be shown).
* @param dirsOnly true to list only directories
* @note Call updateDirectory() afterwards for the changes to take effect.
*/
virtual void setDirOnlyMode(bool dirsOnly);
@ -224,33 +213,15 @@ public:
KUrl url() const;
/**
* Returns all URLs that are listed by this KDirLister. This is only
* useful if you called openUrl() with OpenUrlFlag::Keep, as it happens in a
* treeview, for example. (Note that the base url is included in the list
* as well, of course.)
*
* @return the list of all listed URLs
*/
KUrl::List directories() const;
/**
* Actually emit the changes made with setShowingDotFiles, setDirOnlyMode,
* setNameFilter and setMimeFilter.
*/
virtual void emitChanges();
/**
* Update the directory @p url. This method causes KDirLister to _only_ emit
* Update the directory. This method causes KDirLister to _only_ emit
* the items of @p url that actually changed compared to the current state in the
* cache and updates the cache.
*
* The current implementation calls updateDirectory automatically for
* local files, using KDirWatch (if autoUpdate() is true), but it might be
* useful to force an update manually.
*
* @param url the directory URL
*/
virtual void updateDirectory(const KUrl &url);
virtual void updateDirectory();
/**
* Returns true if no io operation is currently in progress.
@ -285,10 +256,9 @@ public:
*
* You can set more than one filter by separating them with whitespace, e.g
* "*.cpp *.h".
* Note: the directory is not automatically reloaded.
* You need to call emitChanges() afterwards.
*
* @param filter the new filter, QString() to disable filtering
* @note Call updateDirectory() afterwards for the changes to take effect.
* @see matchesFilter
*/
virtual void setNameFilter(const QString &filter);
@ -306,36 +276,18 @@ public:
* NOTE: setting the filter does not automatically reload directory.
* Also calling this function will not affect any named filter already set.
*
* You need to call emitChanges() afterwards.
*
* @param mimeList a list of mime-types.
*
* @note Call updateDirectory() afterwards for the changes to take effect.
* @see clearMimeFilter
* @see matchesMimeFilter
*/
virtual void setMimeFilter(const QStringList &mimeList);
/**
* Filtering should be done with KFileFilter. This will be implemented in a later
* revision of KDirLister. This method may be removed then.
*
* Set mime-based exclude filter to only list items not matching the given mimetypes
*
* NOTE: setting the filter does not automatically reload directory.
* Also calling this function will not affect any named filter already set.
*
* @param mimeList a list of mime-types.
* @see clearMimeFilter
* @see matchesMimeFilter
* @internal
*/
void setMimeExcludeFilter(const QStringList &mimeList);
/**
* Clears the mime based filter.
*
* You need to call emitChanges() afterwards.
*
* @note Call updateDirectory() afterwards for the changes to take effect.
* @see setMimeFilter
*/
virtual void clearMimeFilter();
@ -377,8 +329,8 @@ public:
QWidget* mainWindow();
/**
* Used by items() and itemsForDir() to specify whether you want
* all items for a directory or just the filtered ones.
* Used by items() to specify whether you want all items for a directory
* or just the filtered ones.
*/
enum WhichItems
{
@ -403,74 +355,24 @@ public:
*/
KFileItemList items(WhichItems which = FilteredItems) const;
/**
* Returns the items listed for the given @p dir.
* This method will NOT start listing @p dir, you should only call
* this when receiving the finished() signal.
*
* The items in the KFileItemList are copies of the items used
* by KDirLister.
*
* @param dir specifies the url for which the items should be returned. This
* is only useful if you use KDirLister with multiple URLs
* i.e. using bool OpenUrlFlag::Keep in openUrl().
* @param which specifies whether the returned list will contain all entries
* or only the ones that passed the nameFilter, mimeFilter, etc.
* Note that the latter causes iteration over all the items,
* filtering them. If this is too slow for you, use the
* newItems() signal, sending out filtered items in chunks.
* @return the items listed for @p dir.
*/
KFileItemList itemsForDir(const KUrl& dir, WhichItems which = FilteredItems ) const;
/**
* Return the KFileItem for the given URL, if we listed it recently
* and it's still in the cache - which is always the case if a directory
* view is currently showing this item. If not, then it might be in the
* cache, or it might not, in which case you get a null KFileItem.
* If you really need a KFileItem for this URL in all cases, then use
* KIO::stat() instead.
*
* @since 4.2
*/
static KFileItem cachedItemForUrl(const KUrl &url);
Q_SIGNALS:
/**
* Tell the view that we started to list @p url. NOTE: this does _not_ imply that there
* Tell the view that we started to list the url. NOTE: this does _not_ imply that there
* is really a job running! I.e. KDirLister::jobs() may return an empty list. In this case
* the items are taken from the cache.
*
* The view knows that openUrl should start it, so it might seem useless,
* but the view also needs to know when an automatic update happens.
* @param url the URL to list
*/
void started(const KUrl & url);
void started();
/**
* Tell the view that listing is finished. There are no jobs running anymore.
*/
void completed();
/**
* Tell the view that the listing of the directory @p url is finished.
* There might be other running jobs left.
* @param url the directory URL
*/
void completed(const KUrl &url);
/**
* Tell the view that the user canceled the listing. No running jobs are left.
*/
void canceled();
/**
* Tell the view that the listing of the directory @p url was canceled.
* There might be other running jobs left.
* @param url the directory URL
*/
void canceled(const KUrl &url);
/**
* Signal a redirection.
* Only emitted if there's just one directory to list, i.e. most
@ -479,33 +381,12 @@ Q_SIGNALS:
*/
void redirection(const KUrl &url);
/**
* Signal a redirection.
* @param oldUrl the original URL
* @param newUrl the new URL
*/
void redirection(const KUrl &oldUrl, const KUrl &newUrl);
/**
* Signal to clear all items.
* Make sure to connect to this signal to avoid doubled items.
*/
void clear();
/**
* Signal to empty the directory @p url.
* It is only emitted if the lister is holding more than one directory.
* @param url the directory that will be emptied
*/
void clear(const KUrl &url);
/**
* Signal new items.
*
* @param items a list of new items
*/
void newItems(const KFileItemList &items);
/**
* Signal that new items were found during directory listing.
* Alternative signal emitted at the same time as newItems(),
@ -514,13 +395,7 @@ Q_SIGNALS:
* @param items a list of new items
* @since 4.2
*/
void itemsAdded(const KUrl &directoryUrl, const KFileItemList &items);
/**
* Send a list of items filtered-out by mime-type.
* @param items the list of filtered items
*/
void itemsFilteredByMime(const KFileItemList &items);
void itemsAdded(const KFileItemList &items);
/**
* Signal that items have been deleted.
@ -552,25 +427,25 @@ Q_SIGNALS:
* This allows using a progress bar very easily. (see QProgressBar)
* @param percent the progress in percent
*/
void percent(int percent);
void percent(ulong percent);
/**
* Emitted when we know the size of the jobs.
* @param size the total size in bytes
*/
void totalSize(KIO::filesize_t size);
void totalSize(qulonglong size);
/**
* Regularly emitted to show the progress of this KDirLister.
* @param size the processed size in bytes
*/
void processedSize(KIO::filesize_t size);
void processedSize(qulonglong size);
/**
* Emitted to display information about the speed of the jobs.
* @param bytes_per_second the speed in bytes/s
*/
void speed(int bytes_per_second);
void speed(ulong bytes_per_second);
protected:
/**
@ -623,21 +498,26 @@ protected:
virtual void handleError(KIO::Job *job);
private:
class Private;
Private* const d;
friend class Private;
friend class KDirListerCache;
friend struct KDirListerCacheDirectoryData;
KDirListerPrivate* const d;
friend KDirListerPrivate;
Q_PRIVATE_SLOT(d, void _k_slotInfoMessage(KJob *job, const QString &msg))
Q_PRIVATE_SLOT(d, void _k_slotPercent(KJob *job, unsigned long value))
Q_PRIVATE_SLOT(d, void _k_slotPercent(KJob *job, ulong value))
Q_PRIVATE_SLOT(d, void _k_slotTotalSize(KJob *job, qulonglong value))
Q_PRIVATE_SLOT(d, void _k_slotProcessedSize(KJob *job, qulonglong value))
Q_PRIVATE_SLOT(d, void _k_slotSpeed(KJob *job, unsigned long value))
Q_PRIVATE_SLOT(d, void _k_slotSpeed(KJob *job, ulong value))
Q_PRIVATE_SLOT(d, void _k_slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries));
Q_PRIVATE_SLOT(d, void _k_slotRedirection(KIO::Job *job, const KUrl &url));
Q_PRIVATE_SLOT(d, void _k_slotResult(KJob *job));
Q_PRIVATE_SLOT(d, void _k_slotDirty(const QString &path));
Q_PRIVATE_SLOT(d, void _k_slotFileRenamed(const QString &path, const QString &path2));
Q_PRIVATE_SLOT(d, void _k_slotFilesAdded(const QString &path));
Q_PRIVATE_SLOT(d, void _k_slotFilesChanged(const QStringList &paths));
Q_PRIVATE_SLOT(d, void _k_slotFilesRemoved(const QStringList &paths));
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KDirLister::OpenUrlFlags)
#endif
#endif // KDIRLISTER_H

View file

@ -21,471 +21,54 @@
#define KDIRLISTER_P_H
#include "kfileitem.h"
#include <QtCore/QCache>
#include <QtCore/QTimer>
#include <QtGui/QWidget>
#include <QtCore/qfileinfo.h>
#include <kurl.h>
#include <kdebug.h>
#include <kio/global.h>
#include <kdirwatch.h>
#include <kdirnotify.h>
class KDirLister;
namespace KIO { class Job; class ListJob; }
class OrgKdeKDirNotifyInterface;
struct KDirListerCacheDirectoryData;
class KDirLister::Private
class KDirListerPrivate
{
public:
Private(KDirLister *parent)
: m_parent(parent)
{
complete = false;
KDirListerPrivate(KDirLister *parent);
autoUpdate = false;
autoErrorHandling = false;
errorParent = 0;
delayedMimeTypes = false;
rootFileItem = KFileItem();
lstNewItems = 0;
lstRefreshItems = 0;
lstMimeFilteredItems = 0;
lstRemoveItems = 0;
hasPendingChanges = false;
window = 0;
}
void _k_emitCachedItems(const KUrl&, bool, bool);
void _k_slotInfoMessage( KJob*, const QString& );
void _k_slotPercent( KJob*, unsigned long );
void _k_slotTotalSize( KJob*, qulonglong );
void _k_slotProcessedSize( KJob*, qulonglong );
void _k_slotSpeed( KJob*, unsigned long );
bool doMimeExcludeFilter( const QString& mimeExclude, const QStringList& filters ) const;
void jobStarted( KIO::ListJob * );
void connectJob( KIO::ListJob * );
void jobDone( KIO::ListJob * );
uint numJobs();
void addNewItem(const KUrl& directoryUrl, const KFileItem& item);
void addNewItems(const KUrl& directoryUrl, const KFileItemList& items);
void addRefreshItem(const KUrl& directoryUrl, const KFileItem& oldItem, const KFileItem& item);
void emitItems();
void emitItemsDeleted(const KFileItemList &items);
/**
* Redirect this dirlister from oldUrl to newUrl.
* @param keepItems if true, keep the fileitems (e.g. when renaming an existing dir);
* if false, clear out everything (e.g. when redirecting during listing).
*/
void redirect(const KUrl& oldUrl, const KUrl& newUrl, bool keepItems);
/**
* Should this item be visible according to the current filter settings?
*/
bool isItemVisible(const KFileItem& item) const;
void prepareForSettingsChange() {
if (!hasPendingChanges) {
hasPendingChanges = true;
oldSettings = settings;
}
}
void emitChanges();
class CachedItemsJob;
CachedItemsJob* cachedItemsJobForUrl(const KUrl& url) const;
KDirLister *m_parent;
/**
* List of dirs handled by this dirlister. The first entry is the base URL.
* For a tree view, it contains all the dirs shown.
*/
KUrl::List lstDirs;
// toplevel URL
KUrl url;
bool complete:1;
bool autoUpdate:1;
bool delayedMimeTypes:1;
bool hasPendingChanges:1; // i.e. settings != oldSettings
bool autoErrorHandling:2;
QWidget *errorParent;
struct JobData {
long unsigned int percent, speed;
KIO::filesize_t processedSize, totalSize;
};
QMap<KIO::ListJob *, JobData> jobData;
// file item for the root itself (".")
KFileItem rootFileItem;
typedef QHash<KUrl, KFileItemList> NewItemsHash;
NewItemsHash *lstNewItems;
QList<QPair<KFileItem,KFileItem> > *lstRefreshItems;
KFileItemList *lstMimeFilteredItems, *lstRemoveItems;
QWidget *window; // Main window this lister is associated with
QList<CachedItemsJob*> m_cachedItemsJobs;
QString nameFilter; // parsed into lstFilters
struct FilterSettings {
FilterSettings() : isShowingDotFiles(false), dirOnlyMode(false) {}
bool isShowingDotFiles;
bool dirOnlyMode;
QList<QRegExp> lstFilters;
QStringList mimeFilter;
QStringList mimeExcludeFilter;
};
FilterSettings settings;
FilterSettings oldSettings;
friend class KDirListerCache;
};
/**
* Design of the cache:
* There is a single KDirListerCache for the whole process.
* It holds all the items used by the dir listers (itemsInUse)
* as well as a cache of the recently used items (itemsCached).
* Those items are grouped by directory (a DirItem represents a whole directory).
*
* KDirListerCache also runs all the jobs for listing directories, whether they are for
* normal listing or for updates.
* For faster lookups, it also stores a hash table, which gives for a directory URL:
* - the dirlisters holding that URL (listersCurrentlyHolding)
* - the dirlisters currently listing that URL (listersCurrentlyListing)
*/
class KDirListerCache : public QObject
{
Q_OBJECT
public:
KDirListerCache(); // only called by K_GLOBAL_STATIC
~KDirListerCache();
void updateDirectory( const KUrl& dir );
KFileItem itemForUrl( const KUrl& url ) const;
KFileItemList *itemsForDir(const KUrl& dir) const;
bool listDir( KDirLister *lister, const KUrl& _url, bool _keep, bool _reload );
// stop all running jobs for lister
void stop( KDirLister *lister, bool silent = false );
// stop just the job listing url for lister
void stopListingUrl( KDirLister *lister, const KUrl &_url, bool silent = false );
void setAutoUpdate( KDirLister *lister, bool enable );
void forgetDirs( KDirLister *lister );
void forgetDirs( KDirLister *lister, const KUrl &_url, bool notify );
KFileItem findByName( const KDirLister *lister, const QString &_name ) const;
// findByUrl returns a pointer so that it's possible to modify the item.
// See itemForUrl for the version that returns a readonly kfileitem.
// @param lister can be 0. If set, it is checked that the url is held by the lister
KFileItem *findByUrl(const KDirLister *lister, const KUrl &url) const;
// Called by CachedItemsJob:
// Emits the cached items, for this lister and this url
void emitItemsFromCache(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
const KUrl& _url, bool _reload, bool _emitCompleted);
// Called by CachedItemsJob:
void forgetCachedItemsJob(KDirLister::Private::CachedItemsJob* job, KDirLister* lister,
const KUrl& url);
public Q_SLOTS:
/**
* Notify that files have been added in @p directory
* The receiver will list that directory again to find
* the new items (since it needs more than just the names anyway).
* Connected to the DBus signal from the KDirNotify interface.
*/
void slotFilesAdded( const QString& urlDirectory );
/**
* Notify that files have been deleted.
* This call passes the exact urls of the deleted files
* so that any view showing them can simply remove them
* or be closed (if its current dir was deleted)
* Connected to the DBus signal from the KDirNotify interface.
*/
void slotFilesRemoved( const QStringList& fileList );
/**
* Notify that files have been changed.
* At the moment, this is only used for new icon, but it could be
* used for size etc. as well.
* Connected to the DBus signal from the KDirNotify interface.
*/
void slotFilesChanged( const QStringList& fileList );
void slotFileRenamed( const QString& srcUrl, const QString& dstUrl );
private Q_SLOTS:
void slotFileDirty( const QString &_file );
void slotEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
void slotResult( KJob *j );
void slotRedirection( KIO::Job *job, const KUrl &url );
void slotUpdateEntries( KIO::Job *job, const KIO::UDSEntryList &entries );
void slotUpdateResult( KJob *job );
void processPendingUpdates();
private:
class DirItem;
DirItem* dirItemForUrl(const KUrl& dir) const;
bool validUrl( const KDirLister *lister, const KUrl& _url ) const;
void stopListJob(const QString& url, bool silent);
KIO::ListJob *jobForUrl( const QString& url, KIO::ListJob *not_job = 0 );
const KUrl& joburl( KIO::ListJob *job );
void killJob( KIO::ListJob *job );
// Called when something tells us that the directory @p url has changed.
// Returns true if @p url is held by some lister (meaning: do the update now)
// otherwise mark the cached item as not-up-to-date for later and return false
bool checkUpdate( const QString& url );
// Helper method for slotFileDirty
void handleFileDirty(const KUrl& url);
void handleDirDirty(const KUrl& url);
// when there were items deleted from the filesystem all the listers holding
// the parent directory need to be notified, the unmarked items have to be deleted
// and removed from the cache including all the children.
void deleteUnmarkedItems( const QList<KDirLister *>&, KFileItemList & );
// Helper method called when we know that a list of items was deleted
void itemsDeleted(const QList<KDirLister *>& listers, const KFileItemList& deletedItems);
void slotFilesRemoved(const KUrl::List& urls);
// common for slotRedirection and slotFileRenamed
void renameDir( const KUrl &oldUrl, const KUrl &url );
// common for deleteUnmarkedItems and slotFilesRemoved
void deleteDir( const KUrl& dirUrl );
// remove directory from cache (itemsCached), including all child dirs
void removeDirFromCache( const KUrl& dir );
// helper for renameDir
void emitRedirections( const KUrl &oldUrl, const KUrl &url );
/**
* Emits refreshItem() in the directories that cared for oldItem.
* The caller has to remember to call emitItems in the set of dirlisters returned
* (but this allows to buffer change notifications)
*/
QSet<KDirLister *> emitRefreshItem(const KFileItem& oldItem, const KFileItem& fileitem);
/**
* When KDirWatch tells us that something changed in "dir", we need to
* also notify the dirlisters that are listing a symlink to "dir" (#213799)
*/
QStringList directoriesForCanonicalPath(const QString& dir) const;
#ifndef NDEBUG
void printDebug();
#endif
class DirItem
{
public:
DirItem(const KUrl &dir, const QString& canonicalPath)
: url(dir), m_canonicalPath(canonicalPath)
{
autoUpdates = 0;
complete = false;
watchedWhileInCache = false;
}
~DirItem()
{
if ( autoUpdates )
{
if ( KDirWatch::self() && url.isLocalFile() )
KDirWatch::self()->removeDir(m_canonicalPath);
sendSignal( false, url );
}
lstItems.clear();
}
void sendSignal( bool entering, const KUrl& url )
{
// Note that "entering" means "start watching", and "leaving" means "stop watching"
// (i.e. it's not when the user leaves the directory, it's when the directory is removed from the cache)
if (entering)
org::kde::KDirNotify::emitEnteredDirectory( url.url() );
else
org::kde::KDirNotify::emitLeftDirectory( url.url() );
}
void redirect( const KUrl& newUrl )
{
if ( autoUpdates )
{
if ( url.isLocalFile() )
KDirWatch::self()->removeDir(m_canonicalPath);
sendSignal( false, url );
if (newUrl.isLocalFile()) {
m_canonicalPath = QFileInfo(newUrl.toLocalFile()).canonicalFilePath();
KDirWatch::self()->addDir(m_canonicalPath);
}
sendSignal( true, newUrl );
}
url = newUrl;
if ( !rootItem.isNull() )
rootItem.setUrl( newUrl );
}
void incAutoUpdate()
{
if ( autoUpdates++ == 0 )
{
if ( url.isLocalFile() )
KDirWatch::self()->addDir(m_canonicalPath);
sendSignal( true, url );
}
}
void decAutoUpdate()
{
if ( --autoUpdates == 0 )
{
if ( url.isLocalFile() )
KDirWatch::self()->removeDir(m_canonicalPath);
sendSignal( false, url );
}
else if ( autoUpdates < 0 )
autoUpdates = 0;
}
// number of KDirListers using autoUpdate for this dir
short autoUpdates;
// this directory is up-to-date
bool complete;
// the directory is watched while being in the cache (useful for proper incAutoUpdate/decAutoUpdate count)
bool watchedWhileInCache;
// the complete url of this directory
// toplevel URL
KUrl url;
bool autoUpdate;
bool delayedMimeTypes;
bool autoErrorHandling;
bool showingDotFiles;
bool dirOnlyMode;
bool complete;
QWidget* window;
KIO::ListJob* listJob;
// file item for the root itself (".")
KFileItem rootFileItem;
KFileItemList allItems;
KFileItemList filteredItems;
QString nameFilter;
QStringList mimeFilter;
QList<QRegExp> nameFilters;
// the local path, with symlinks resolved, so that KDirWatch works
QString m_canonicalPath;
void _k_slotInfoMessage(KJob *job, const QString &msg);
void _k_slotPercent(KJob *job, ulong value);
void _k_slotTotalSize(KJob *job, qulonglong value);
void _k_slotProcessedSize(KJob *job, qulonglong value);
void _k_slotSpeed(KJob *job, ulong value);
// KFileItem representing the root of this directory.
// Remember that this is optional. FTP sites don't return '.' in
// the list, so they give no root item
KFileItem rootItem;
KFileItemList lstItems;
};
void _k_slotEntries(KIO::Job *job, const KIO::UDSEntryList &entries);
void _k_slotRedirection(KIO::Job *job, const KUrl &url);
void _k_slotResult(KJob *job);
//static const unsigned short MAX_JOBS_PER_LISTER;
QMap<KIO::ListJob *, KIO::UDSEntryList> runningListJobs;
// an item is a complete directory
QHash<QString /*url*/, DirItem*> itemsInUse;
QCache<QString /*url*/, DirItem> itemsCached;
typedef QHash<QString /*url*/, KDirListerCacheDirectoryData> DirectoryDataHash;
DirectoryDataHash directoryData;
// Symlink-to-directories are registered here so that we can
// find the url that changed, when kdirwatch tells us about
// changes in the canonical url. (#213799)
QHash<QString /*canonical path*/, QStringList /*dirlister urls*/> canonicalUrls;
// Set of local files that we have changed recently (according to KDirWatch)
// We temporize the notifications by keeping them 500ms in this list.
QSet<QString /*path*/> pendingUpdates;
// The timer for doing the delayed updates
QTimer pendingUpdateTimer;
// Set of remote files that have changed recently -- but we can't emit those
// changes yet, we need to wait for the "update" directory listing.
// The cmp() call can't differ mimetypes since they are determined on demand,
// this is why we need to remember those files here.
QSet<KFileItem*> pendingRemoteUpdates;
// the KDirNotify signals
OrgKdeKDirNotifyInterface *kdirnotify;
struct ItemInUseChange;
};
// Data associated with a directory url
// This could be in DirItem but only in the itemsInUse dict...
struct KDirListerCacheDirectoryData
{
// A lister can be EITHER in listersCurrentlyListing OR listersCurrentlyHolding
// but NOT in both at the same time.
// But both lists can have different listers at the same time; this
// happens if more listers are requesting url at the same time and
// one lister was stopped during the listing of files.
// Listers that are currently listing this url
QList<KDirLister *> listersCurrentlyListing;
// Listers that are currently holding this url
QList<KDirLister *> listersCurrentlyHolding;
void moveListersWithoutCachedItemsJob(const KUrl& url);
};
//const unsigned short KDirListerCache::MAX_JOBS_PER_LISTER = 5;
// This job tells KDirListerCache to emit cached items asynchronously from listDir()
// to give the KDirLister user enough time for connecting to its signals, and so
// that KDirListerCache behaves just like when a real KIO::Job is used: nothing
// is emitted during the openUrl call itself.
class KDirLister::Private::CachedItemsJob : public KJob {
Q_OBJECT
public:
CachedItemsJob(KDirLister* lister, const KUrl& url, bool reload);
/*reimp*/ void start() { QMetaObject::invokeMethod(this, "done", Qt::QueuedConnection); }
// For updateDirectory() to cancel m_emitCompleted;
void setEmitCompleted(bool b) { m_emitCompleted = b; }
KUrl url() const { return m_url; }
protected:
virtual bool doKill();
public Q_SLOTS:
void done();
void _k_slotDirty(const QString &path);
void _k_slotFileRenamed(const QString &path, const QString &path2);
void _k_slotFilesAdded(const QString &path);
void _k_slotFilesChanged(const QStringList &paths);
void _k_slotFilesRemoved(const QStringList &paths);
private:
KDirLister* m_lister;
KUrl m_url;
bool m_reload;
bool m_emitCompleted;
KDirLister *m_parent;
KDirWatch* m_dirwatch;
OrgKdeKDirNotifyInterface* m_dirnotify;
};
#endif
#endif // KDIRLISTER_P_H

View file

@ -143,11 +143,11 @@ public:
delete m_rootNode;
}
void _k_slotNewItems(const KUrl& directoryUrl, const KFileItemList&);
void _k_slotAddedItems(const KFileItemList&);
void _k_slotDeleteItems(const KFileItemList&);
void _k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&);
void _k_slotClear();
void _k_slotRedirection(const KUrl& oldUrl, const KUrl& newUrl);
void _k_slotRedirection(const KUrl& newUrl);
void _k_slotJobUrlsChanged(const QStringList& urlList);
void clear() {
@ -348,16 +348,16 @@ void KDirModel::setDirLister(KDirLister* dirLister)
}
d->m_dirLister = dirLister;
d->m_dirLister->setParent(this);
connect( d->m_dirLister, SIGNAL(itemsAdded(KUrl,KFileItemList)),
this, SLOT(_k_slotNewItems(KUrl,KFileItemList)) );
connect( d->m_dirLister, SIGNAL(itemsAdded(KFileItemList)),
this, SLOT(_k_slotAddedItems(KFileItemList)) );
connect( d->m_dirLister, SIGNAL(itemsDeleted(KFileItemList)),
this, SLOT(_k_slotDeleteItems(KFileItemList)) );
connect( d->m_dirLister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)),
this, SLOT(_k_slotRefreshItems(QList<QPair<KFileItem,KFileItem> >)) );
connect( d->m_dirLister, SIGNAL(clear()),
this, SLOT(_k_slotClear()) );
connect(d->m_dirLister, SIGNAL(redirection(KUrl,KUrl)),
this, SLOT(_k_slotRedirection(KUrl,KUrl)));
connect(d->m_dirLister, SIGNAL(redirection(KUrl)),
this, SLOT(_k_slotRedirection(KUrl)));
}
KDirLister* KDirModel::dirLister() const
@ -365,8 +365,9 @@ KDirLister* KDirModel::dirLister() const
return d->m_dirLister;
}
void KDirModelPrivate::_k_slotNewItems(const KUrl& directoryUrl, const KFileItemList& items)
void KDirModelPrivate::_k_slotAddedItems(const KFileItemList& items)
{
const KUrl directoryUrl = m_dirLister->url();
//kDebug(7008) << "directoryUrl=" << directoryUrl;
KDirModelNode* result = nodeForUrl(directoryUrl); // O(depth)
@ -589,8 +590,9 @@ void KDirModelPrivate::_k_slotRefreshItems(const QList<QPair<KFileItem, KFileIte
// Called when a kioslave redirects (e.g. smb:/Workgroup -> smb://workgroup)
// and when renaming a directory.
void KDirModelPrivate::_k_slotRedirection(const KUrl& oldUrl, const KUrl& newUrl)
void KDirModelPrivate::_k_slotRedirection(const KUrl& newUrl)
{
const KUrl oldUrl = m_dirLister->url();
KDirModelNode* node = nodeForUrl(oldUrl);
if (!node)
return;

View file

@ -52,14 +52,14 @@ public:
/**
* @param parent parent qobject
*/
explicit KDirModel( QObject* parent = 0 );
explicit KDirModel(QObject *parent = nullptr);
~KDirModel();
/**
* Set the directory lister to use by this model, instead of the default KDirLister created internally.
* The model takes ownership.
*/
void setDirLister( KDirLister* dirLister );
void setDirLister(KDirLister* dirLister);
/**
* Return the directory lister used by this model.
@ -69,17 +69,17 @@ public:
/**
* Return the fileitem for a given index. This is O(1), i.e. fast.
*/
KFileItem itemForIndex( const QModelIndex& index ) const;
KFileItem itemForIndex(const QModelIndex &index) const;
/**
* Return the index for a given kfileitem. This can be slow.
*/
QModelIndex indexForItem( const KFileItem& ) const;
QModelIndex indexForItem(const KFileItem &item) const;
/**
* Return the index for a given url. This can be slow.
*/
QModelIndex indexForUrl(const KUrl& url) const;
QModelIndex indexForUrl(const KUrl &url) const;
/**
* @short Lists subdirectories using fetchMore() as needed until the given @p url exists in the model.
@ -94,7 +94,7 @@ public:
* to the treeview in order to let it open that index.
* @param url the url of a subdirectory of the directory model (or a file in a subdirectory)
*/
void expandToUrl(const KUrl& url);
void expandToUrl(const KUrl &url);
/**
* Notify the model that the item at this index has changed.
@ -102,7 +102,7 @@ public:
* This makes the model emit its dataChanged signal at this index, so that views repaint.
* Note that for most things (renaming, changing size etc.), KDirLister's signals tell the model already.
*/
void itemChanged( const QModelIndex& index );
void itemChanged(const QModelIndex &index);
/***
* Useful "default" columns. Views can use a proxy to have more control over this.
@ -170,7 +170,7 @@ public:
virtual int rowCount ( const QModelIndex & parent = QModelIndex() ) const;
/// Reimplemented from QAbstractItemModel.
/// Call this to set a new icon, e.g. a preview
virtual bool setData ( const QModelIndex & index, const QVariant & value, int role = Qt::EditRole );
virtual bool setData ( const QModelIndex &index, const QVariant & value, int role = Qt::EditRole );
/// Reimplemented from QAbstractItemModel. Not implemented. @see KDirSortFilterProxyModel
virtual void sort ( int column, Qt::SortOrder order = Qt::AscendingOrder );
@ -185,7 +185,7 @@ public:
* @return the list @p urls without parented urls inside.
* @since 4.2
*/
static KUrl::List simplifiedUrlList( const KUrl::List & urls );
static KUrl::List simplifiedUrlList( const KUrl::List &urls);
/**
* This emits the needSequenceIcon signal, requesting another sequence icon
@ -198,7 +198,7 @@ public:
* For higher indices, arbitrary different meaningful icons will be generated.
* @since 4.3
*/
void requestSequenceIcon(const QModelIndex& index, int sequenceIndex);
void requestSequenceIcon(const QModelIndex &index, int sequenceIndex);
/**
* Enable/Disable the displaying of an animated overlay that is shown for any destination
@ -231,7 +231,7 @@ Q_SIGNALS:
* Also emitted for the final file, if expandToUrl is called with a file
* (for instance so that it can be selected).
*/
void expand(const QModelIndex& index);
void expand(const QModelIndex &index);
/**
* Emitted when another icon sequence index is requested
* @param index Index of the item that should get another icon
@ -241,18 +241,18 @@ Q_SIGNALS:
* If no meaningful alternative icons can be generated, this should be ignored.
* @since 4.3
*/
void needSequenceIcon(const QModelIndex& index, int sequenceIndex);
void needSequenceIcon(const QModelIndex &index, int sequenceIndex);
private:
friend class KDirModelPrivate;
KDirModelPrivate *const d;
Q_PRIVATE_SLOT( d, void _k_slotNewItems(const KUrl&, const KFileItemList&) )
Q_PRIVATE_SLOT( d, void _k_slotDeleteItems(const KFileItemList&) )
Q_PRIVATE_SLOT( d, void _k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&) )
Q_PRIVATE_SLOT( d, void _k_slotClear() )
Q_PRIVATE_SLOT( d, void _k_slotRedirection(const KUrl&, const KUrl&) )
Q_PRIVATE_SLOT( d, void _k_slotJobUrlsChanged(const QStringList&))
Q_PRIVATE_SLOT(d, void _k_slotAddedItems(const KFileItemList &))
Q_PRIVATE_SLOT(d, void _k_slotDeleteItems(const KFileItemList &))
Q_PRIVATE_SLOT(d, void _k_slotRefreshItems(const QList<QPair<KFileItem, KFileItem> > &))
Q_PRIVATE_SLOT(d, void _k_slotClear())
Q_PRIVATE_SLOT(d, void _k_slotRedirection(const KUrl &))
Q_PRIVATE_SLOT(d, void _k_slotJobUrlsChanged(const QStringList &))
};
Q_DECLARE_OPERATORS_FOR_FLAGS(KDirModel::DropsAllowed)

View file

@ -40,14 +40,12 @@ KIO_EXECUTABLE_TESTS(
kruntest
kioslavetest
speed
kdirlistertest_gui
previewtest
kionetrctest
kpropsdlgtest
kmfitest
ksycocaupdatetest
netaccesstest
kdirmodeltest_gui
kmimetypechoosertest_gui
kurlrequestertest
kopenwithtest

File diff suppressed because it is too large Load diff

View file

@ -29,116 +29,17 @@
Q_DECLARE_METATYPE(KFileItemList)
class GlobalInits
{
public:
GlobalInits() {
// Must be done before the QSignalSpys connect
qRegisterMetaType<KUrl>();
qRegisterMetaType<KFileItem>();
qRegisterMetaType<KFileItemList>();
}
};
class MyDirLister : public KDirLister, GlobalInits
{
public:
MyDirLister()
: spyStarted(this, SIGNAL(started(KUrl))),
spyClear(this, SIGNAL(clear())),
spyClearKUrl(this, SIGNAL(clear(KUrl))),
spyCompleted(this, SIGNAL(completed())),
spyCompletedKUrl(this, SIGNAL(completed(KUrl))),
spyCanceled(this, SIGNAL(canceled())),
spyCanceledKUrl(this, SIGNAL(canceled(KUrl))),
spyRedirection(this, SIGNAL(redirection(KUrl))),
spyItemsDeleted(this, SIGNAL(itemsDeleted(KFileItemList)))
{}
void clearSpies()
{
spyStarted.clear();
spyClear.clear();
spyClearKUrl.clear();
spyCompleted.clear();
spyCompletedKUrl.clear();
spyCanceled.clear();
spyCanceledKUrl.clear();
spyRedirection.clear();
spyItemsDeleted.clear();
}
QSignalSpy spyStarted;
QSignalSpy spyClear;
QSignalSpy spyClearKUrl;
QSignalSpy spyCompleted;
QSignalSpy spyCompletedKUrl;
QSignalSpy spyCanceled;
QSignalSpy spyCanceledKUrl;
QSignalSpy spyRedirection;
QSignalSpy spyItemsDeleted;
protected:
virtual void handleError(KIO::Job* job);
};
class KDirListerTest : public QObject
{
Q_OBJECT
private Q_SLOTS:
void initTestCase();
void cleanup();
void testOpenUrl();
void testOpenUrlFromCache();
void testNewItems();
void testNewItemByCopy();
void testNewItemsInSymlink();
void testRefreshItems();
void testRefreshRootItem();
void testDeleteItem();
void testRenameItem();
void testRenameAndOverwrite();
void testConcurrentListing();
void testConcurrentHoldingListing();
void testConcurrentListingAndStop();
void testDeleteListerEarly();
void testOpenUrlTwice();
void testOpenUrlTwiceWithKeep();
void testOpenAndStop();
void testBug211472();
void testRenameCurrentDir();
void testRedirection();
void testWatchingAfterCopyJob();
void testRemoveWatchedDirectory();
void testDirPermissionChange();
void testDeleteCurrentDir(); // must be last!
protected Q_SLOTS: // 'more private than private slots' - i.e. not seen by qtestlib
void exitLoop();
void slotNewItems(const KFileItemList&);
void slotNewItems2(const KFileItemList&);
void slotRefreshItems(const QList<QPair<KFileItem, KFileItem> >&);
void slotRefreshItems2(const QList<QPair<KFileItem, KFileItem> >&);
Q_SIGNALS:
void refreshItemsReceived();
private:
void enterLoop(int exitCount = 1);
int fileCount() const;
QString path() const { return m_tempDir.name(); }
void waitForRefreshedItems();
void createSimpleFile(const QString& fileName);
void fillDirLister2(MyDirLister& lister, const QString& path);
private:
int m_exitCount;
QEventLoop m_eventLoop;
QTimer m_eventTimer;
KTempDir m_tempDir;
MyDirLister m_dirLister;
KFileItemList m_items;
KFileItemList m_items2;
QList<QPair<KFileItem, KFileItem> > m_refreshedItems, m_refreshedItems2;
};

View file

@ -1,162 +0,0 @@
/* This file is part of the KDE desktop environment
Copyright (C) 2001, 2002 Michael Brade <brade@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#include <QtGui/QLayout>
#include <QtGui/QPushButton>
#include <QtCore/QDir>
#include <kapplication.h>
#include <kdirlister.h>
#include <kdebug.h>
#include <kcmdlineargs.h>
#include "kdirlistertest_gui.h"
#include <cstdlib>
KDirListerTest::KDirListerTest( QWidget *parent )
: QWidget( parent )
{
lister = new KDirLister(this);
debug = new PrintSignals;
QVBoxLayout* layout = new QVBoxLayout( this );
QPushButton* startH = new QPushButton( "Start listing Home", this );
QPushButton* startR= new QPushButton( "Start listing Root", this );
QPushButton* test = new QPushButton( "Many", this );
QPushButton* startT = new QPushButton( "tarfile", this );
layout->addWidget( startH );
layout->addWidget( startR );
layout->addWidget( startT );
layout->addWidget( test );
resize( layout->sizeHint() );
connect( startR, SIGNAL(clicked()), SLOT(startRoot()) );
connect( startH, SIGNAL(clicked()), SLOT(startHome()) );
connect( startT, SIGNAL(clicked()), SLOT(startTar()) );
connect( test, SIGNAL(clicked()), SLOT(test()) );
connect( lister, SIGNAL(started(KUrl)),
debug, SLOT(started(KUrl)) );
connect( lister, SIGNAL(completed()),
debug, SLOT(completed()) );
connect( lister, SIGNAL(completed(KUrl)),
debug, SLOT(completed(KUrl)) );
connect( lister, SIGNAL(canceled()),
debug, SLOT(canceled()) );
connect( lister, SIGNAL(canceled(KUrl)),
debug, SLOT(canceled(KUrl)) );
connect( lister, SIGNAL(redirection(KUrl)),
debug, SLOT(redirection(KUrl)) );
connect( lister, SIGNAL(redirection(KUrl,KUrl)),
debug, SLOT(redirection(KUrl,KUrl)) );
connect( lister, SIGNAL(clear()),
debug, SLOT(clear()) );
connect( lister, SIGNAL(newItems(KFileItemList)),
debug, SLOT(newItems(KFileItemList)) );
connect( lister, SIGNAL(itemsFilteredByMime(KFileItemList)),
debug, SLOT(itemsFilteredByMime(KFileItemList)) );
connect( lister, SIGNAL(itemsDeleted(KFileItemList)),
debug, SLOT(itemsDeleted(KFileItemList)) );
connect( lister, SIGNAL(refreshItems(QList<QPair<KFileItem,KFileItem> >)),
debug, SLOT(refreshItems(QList<QPair<KFileItem,KFileItem> >)) );
connect( lister, SIGNAL(infoMessage(QString)),
debug, SLOT(infoMessage(QString)) );
connect( lister, SIGNAL(percent(int)),
debug, SLOT(percent(int)) );
connect( lister, SIGNAL(totalSize(KIO::filesize_t)),
debug, SLOT(totalSize(KIO::filesize_t)) );
connect( lister, SIGNAL(processedSize(KIO::filesize_t)),
debug, SLOT(processedSize(KIO::filesize_t)) );
connect( lister, SIGNAL(speed(int)),
debug, SLOT(speed(int)) );
connect( lister, SIGNAL(completed()),
this, SLOT(completed()) );
}
KDirListerTest::~KDirListerTest()
{
}
void KDirListerTest::startHome()
{
KUrl home( QDir::homePath() );
lister->openUrl( home, KDirLister::NoFlags );
// lister->stop();
}
void KDirListerTest::startRoot()
{
KUrl root( QDir::rootPath() );
lister->openUrl( root, KDirLister::Keep | KDirLister::Reload );
// lister->stop( root );
}
void KDirListerTest::startTar()
{
KUrl root( QDir::homePath()+"/aclocal_1.tgz" );
lister->openUrl( root, KDirLister::Keep | KDirLister::Reload );
// lister->stop( root );
}
void KDirListerTest::test()
{
KUrl home( QDir::homePath() );
KUrl root( QDir::rootPath() );
/* lister->openUrl( home, KDirLister::Keep );
lister->openUrl( root, KDirLister::Keep | KDirLister::Reload );
lister->openUrl( KUrl("file:/etc"), KDirLister::Keep | KDirLister::Reload );
lister->openUrl( root, KDirLister::Keep | KDirLister::Reload );
lister->openUrl( KUrl("file:/dev"), KDirLister::Keep | KDirLister::Reload );
lister->openUrl( KUrl("file:/tmp"), KDirLister::Keep | KDirLister::Reload );
lister->openUrl( KUrl("file:/usr/include"), KDirLister::Keep | KDirLister::Reload );
lister->updateDirectory( KUrl("file:/usr/include") );
lister->updateDirectory( KUrl("file:/usr/include") );
lister->openUrl( KUrl("file:/usr/"), KDirLister::Keep | KDirLister::Reload );
*/
lister->openUrl( KUrl("file:/dev"), KDirLister::Keep | KDirLister::Reload );
}
void KDirListerTest::completed()
{
if ( lister->url().toLocalFile() == QDir::rootPath() )
{
const KFileItem item = lister->findByUrl( KUrl( QDir::tempPath() ) );
if ( !item.isNull() )
kDebug() << "Found " << QDir::tempPath() << ": " << item.name();
else
kWarning() << QDir::tempPath() << " not found! Bug in findByURL?";
}
}
int main ( int argc, char *argv[] )
{
KCmdLineArgs::init( argc, argv, "kdirlistertest", 0, ki18n("kdirlistertest"), 0);
KApplication app;
KDirListerTest *test = new KDirListerTest( 0 );
test->show();
return app.exec();
}
#include "moc_kdirlistertest_gui.cpp"

View file

@ -1,122 +0,0 @@
/* This file is part of the KDE desktop environment
Copyright (C) 2001, 2002 Michael Brade <brade@kde.org>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Library General Public
License as published by the Free Software Foundation; either
version 2 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Library General Public License for more details.
You should have received a copy of the GNU Library General Public License
along with this library; see the file COPYING.LIB. If not, write to
the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA.
*/
#ifndef _KDIRLISTERTEST_GUI_H_
#define _KDIRLISTERTEST_GUI_H_
#include <QtGui/QWidget>
#include <QtCore/QString>
#include <kurl.h>
#include <kfileitem.h>
#include <iostream>
using namespace std;
class PrintSignals : public QObject
{
Q_OBJECT
public:
PrintSignals() : QObject() { }
public Q_SLOTS:
void started( const KUrl &url )
{
cout << "*** started( " << url.url().toLocal8Bit().data() << " )" << endl;
}
void canceled() { cout << "canceled()" << endl; }
void canceled( const KUrl& url )
{
cout << "*** canceled( " << url.prettyUrl().toLocal8Bit().data() << " )" << endl;
}
void completed() { cout << "*** completed()" << endl; }
void completed( const KUrl& url )
{
cout << "*** completed( " << url.prettyUrl().toLocal8Bit().data() << " )" << endl;
}
void redirection( const KUrl& url )
{
cout << "*** redirection( " << url.prettyUrl().toLocal8Bit().data() << " )" << endl;
}
void redirection( const KUrl& src, const KUrl& dest )
{
cout << "*** redirection( " << src.prettyUrl().toLocal8Bit().data() << ", "
<< dest.prettyUrl().toLocal8Bit().data() << " )" << endl;
}
void clear() { cout << "*** clear()" << endl; }
void newItems( const KFileItemList& items )
{
cout << "*** newItems: " << endl;
KFileItemList::const_iterator it, itEnd = items.constEnd();
for ( it = items.constBegin() ; it != itEnd ; ++it )
cout << (*it).name().toLocal8Bit().data() << endl;
}
void itemsDeleted( const KFileItemList& items )
{
cout << "*** itemsDeleted: " << endl;
// TODO
}
void itemsFilteredByMime( const KFileItemList& )
{
cout << "*** itemsFilteredByMime: " << endl;
// TODO
}
void refreshItems( const QList<QPair<KFileItem, KFileItem> >& )
{
cout << "*** refreshItems: " << endl;
// TODO
}
void infoMessage( const QString& msg )
{ cout << "*** infoMessage: " << msg.toLocal8Bit().data() << endl; }
void percent( int percent )
{ cout << "*** percent: " << percent << endl; }
void totalSize( KIO::filesize_t size )
{ cout << "*** totalSize: " << (long)size << endl; }
void processedSize( KIO::filesize_t size )
{ cout << "*** processedSize: " << (long)size << endl; }
void speed( int bytes_per_second )
{ cout << "*** speed: " << bytes_per_second << endl; }
};
class KDirListerTest : public QWidget
{
Q_OBJECT
public:
KDirListerTest( QWidget *parent=0 );
~KDirListerTest();
public Q_SLOTS:
void startRoot();
void startHome();
void startTar();
void test();
void completed();
private:
KDirLister *lister;
PrintSignals *debug;
};
#endif

File diff suppressed because it is too large Load diff

View file

@ -23,7 +23,6 @@
#include <ktempdir.h>
#include <QtCore/qdatetime.h>
#include <kdirmodel.h>
#include <QtCore/QEventLoop>
#include <QtTest/QtTest>
// If you disable this, you need to change all exitLoop into quit in connect() statements...
@ -35,80 +34,14 @@ class KDirModelTest : public QObject
private Q_SLOTS:
void initTestCase();
void cleanupTestCase();
void cleanup();
void testRowCount();
void testIndex();
void testNames();
void testItemForIndex();
void testIndexForItem();
void testData();
void testReload();
void testModifyFile();
void testRenameFile();
void testMoveDirectory();
void testRenameDirectory();
void testRenameDirectoryInCache();
void testChmodDirectory();
void testExpandToUrl_data();
void testExpandToUrl();
void testFilter();
void testMimeFilter();
void testShowHiddenFiles();
void testMultipleSlashes();
void testUrlWithRef();
void testRemoteUrlWithHost();
void testZipFile();
void testBug196695();
// These tests must be done last
void testDeleteFile();
void testDeleteFileWhileListing();
void testOverwriteFileWithDir();
void testDeleteFiles();
void testRenameFileToHidden();
void testDeleteDirectory();
void testDeleteCurrentDirectory();
// Somewhat unrelated
void testKUrlHash();
protected Q_SLOTS: // 'more private than private slots' - i.e. not seen by qtestlib
void slotListingCompleted();
void slotExpand(const QModelIndex& index);
void slotRowsInserted(const QModelIndex& index, int, int);
private:
void recreateTestData();
void enterLoop();
void fillModel(bool reload, bool expectAllIndexes = true);
void collectKnownIndexes();
void testMoveDirectory(const QString& srcdir);
void testUpdateParentAfterExpand();
private:
#ifdef USE_QTESTEVENTLOOP
QTestEventLoop m_eventLoop;
#else
QEventLoop m_eventLoop;
#endif
KTempDir* m_tempDir;
KDirLister* m_dirLister;
KDirModel* m_dirModel;
QModelIndex m_fileIndex;
QModelIndex m_specialFileIndex;
QModelIndex m_secondFileIndex;
QModelIndex m_dirIndex;
QModelIndex m_fileInDirIndex;
QModelIndex m_fileInSubdirIndex;
QStringList m_topLevelFileNames; // files only
// for slotExpand
QStringList m_expectedExpandSignals;
int m_nextExpectedExpandSignals; // index into m_expectedExpandSignals
KDirModel* m_dirModelForExpand;
KUrl m_urlToExpandTo;
bool m_rowsInsertedEmitted;
bool m_expectRowsInserted;
KTempDir* m_tempDir;
};
#endif

View file

@ -1,116 +0,0 @@
/*
* Copyright (C) 2006 David Faure <faure@kde.org>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License version 2 as published by the Free Software Foundation;
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/
#include <kdebug.h>
#include <kcmdlineargs.h>
#include <kapplication.h>
#include <kdirlister.h>
#include <kdirmodel.h>
#include <kurl.h>
#include <QtGui/QTreeView>
#include <QtGui/QListView>
#include <QtCore/QDir>
#include <QtCore/QFile>
#include <kfileitemdelegate.h>
// Test controller for making the view open up while expandToUrl lists subdirs
class TreeController : public QObject
{
Q_OBJECT
public:
explicit TreeController(QTreeView* view, KDirModel* model)
: QObject(view), m_treeView(view), m_model(model)
{
connect(model, SIGNAL(expand(QModelIndex)),
this, SLOT(slotExpand(QModelIndex)));
}
private Q_SLOTS:
void slotExpand(const QModelIndex& index)
{
KFileItem item = m_model->itemForIndex(index);
kDebug() << "slotListingCompleted" << item.url();
m_treeView->setExpanded(index, true);
// The scrollTo call doesn't seem to work.
// We probably need to delay this until everything's listed and layouted...
m_treeView->scrollTo(index);
}
private:
QTreeView* m_treeView;
KDirModel* m_model;
};
int main (int argc, char **argv)
{
KCmdLineOptions options;
options.add("+[directory ...]", ki18n("Directory(ies) to model"));
KCmdLineArgs::init(argc, argv, "kdirmodeltest", 0, ki18n("KDirModelTest"),
"1.0", ki18n("Test for KDirModel"));
KCmdLineArgs::addCmdLineOptions( options );
KCmdLineArgs::addStdCmdLineOptions();
KApplication a;
KCmdLineArgs *args = KCmdLineArgs::parsedArgs();
KDirModel *dirmodel = new KDirModel(0);
dirmodel->dirLister()->setDelayedMimeTypes(true);
#if 1
QTreeView* treeView = new QTreeView(0);
treeView->setModel(dirmodel);
treeView->setUniformRowHeights(true); // makes visualRect() much faster
treeView->resize(500, 500);
treeView->show();
treeView->setItemDelegate( new KFileItemDelegate(treeView) );
#endif
#if 0
QListView* listView = new QListView(0);
listView->setModel(dirmodel);
listView->setUniformItemSizes(true); // true in list mode, not in icon mode.
listView->show();
#endif
#if 1
QListView* iconView = new QListView(0);
iconView->setModel(dirmodel);
iconView->setSelectionMode(QListView::ExtendedSelection);
iconView->setViewMode(QListView::IconMode);
iconView->show();
iconView->setItemDelegate( new KFileItemDelegate(iconView) );
#endif
if (args->count() == 0) {
dirmodel->dirLister()->openUrl(KUrl("/"));
const KUrl url("/usr/share/applications/kde");
dirmodel->expandToUrl(url);
new TreeController(treeView, dirmodel);
}
for(int i = 0; i < args->count(); i++) {
kDebug() << "Adding: " << args->url(i);
dirmodel->dirLister()->openUrl( args->url(i), KDirLister::Keep );
}
return a.exec();
}
#include "kdirmodeltest_gui.moc"