Skip to content

Commit

Permalink
[nemo-filemanager] Add fileCount method. Contributes to JB#47008
Browse files Browse the repository at this point in the history
  • Loading branch information
Alexey Tatarov authored and Aleksey committed Sep 27, 2019
1 parent 65002b8 commit 6dc2c1a
Show file tree
Hide file tree
Showing 5 changed files with 181 additions and 32 deletions.
20 changes: 20 additions & 0 deletions .gitignore
@@ -0,0 +1,20 @@
# ccls
.ccls-cache

# qmake
Makefile
.qmake.stash
*.pro.user

/RPMS
/installroot
/lib/pkgconfig
/*.list
moc_*
*.prl
*.o
*.moc
*.a
*.so
*.so.*
*.qm
127 changes: 110 additions & 17 deletions src/plugin/diskusage.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Jolla Ltd.
* Contact: Thomas Perl <thomas.perl@jolla.com>
* Copyright (C) 2015 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -37,11 +37,12 @@
#include <QDebug>
#include <QJSEngine>
#include <QDir>

#include <QDirIterator>

DiskUsageWorker::DiskUsageWorker(QObject *parent)
: QObject(parent)
, m_quit(false)
, m_stopCounting{false}
{
}

Expand All @@ -54,8 +55,35 @@ void DiskUsageWorker::submit(QStringList paths, QJSValue *callback)
emit finished(calculate(paths), callback);
}

QVariantMap DiskUsageWorker::calculate(QStringList paths)
void DiskUsageWorker::startCounting(const QString &path, QJSValue *callback, bool recursive)
{
emit countingFinished(counting(path, recursive), callback);
}

int DiskUsageWorker::counting(const QString &path, bool recursive)
{
m_stopCounting = false;

QFileInfo fileinfo(path);
if (!fileinfo.isDir() || !fileinfo.exists())
return 0;

QDir::Filters filters = (QDir::Files | QDir::NoDotAndDotDot);
QDirIterator it(path, filters, recursive ? QDirIterator::Subdirectories : QDirIterator::NoIteratorFlags);
int counter = 0;

while (it.hasNext()) {
if (m_stopCounting)
return counter;

it.next();
counter++;
}
return counter;
}

QVariantMap DiskUsageWorker::calculate(QStringList paths)
{
QVariantMap usage;
// expanded Path places the object in the tree so parents can have it subtracted from its total
QMap<QString, QString> expandedPaths; // input path -> expanded path
Expand Down Expand Up @@ -153,26 +181,37 @@ class DiskUsagePrivate
private:
QThread *m_thread;
DiskUsageWorker *m_worker;
bool m_working;
DiskUsage::Status m_status;
QVariantMap m_result;
};

DiskUsagePrivate::DiskUsagePrivate(DiskUsage *usage)
: q_ptr(usage)
, m_thread(new QThread())
, m_worker(new DiskUsageWorker())
, m_working(false)
, m_status(DiskUsage::Idle)
{
m_worker->moveToThread(m_thread);

QObject::connect(usage, SIGNAL(submit(QStringList, QJSValue *)),
m_worker, SLOT(submit(QStringList, QJSValue *)));
QObject::connect(usage, &DiskUsage::submit,
m_worker, &DiskUsageWorker::submit);

QObject::connect(m_worker, SIGNAL(finished(QVariantMap, QJSValue *)),
usage, SLOT(finished(QVariantMap, QJSValue *)));
QObject::connect(m_worker, &DiskUsageWorker::finished,
usage, &DiskUsage::finished);

QObject::connect(m_thread, SIGNAL(finished()),
m_worker, SLOT(deleteLater()));
QObject::connect(m_thread, &QThread::finished,
m_worker, &DiskUsageWorker::deleteLater);

QObject::connect(m_thread, SIGNAL(finished()),
m_thread, SLOT(deleteLater()));
QObject::connect(m_thread, &QThread::finished,
m_thread, &QThread::deleteLater);

QObject::connect(usage, &DiskUsage::startCounting,
m_worker, &DiskUsageWorker::startCounting);

QObject::connect(m_worker, &DiskUsageWorker::countingFinished,
usage, &DiskUsage::countingFinished);

m_thread->start();
}
Expand All @@ -181,6 +220,7 @@ DiskUsagePrivate::~DiskUsagePrivate()
{
// Make sure the worker quits as soon as possible
m_worker->scheduleQuit();
m_worker->sheduleStopCounting();

// Tell thread to shut down as early as possible
m_thread->quit();
Expand All @@ -190,7 +230,6 @@ DiskUsagePrivate::~DiskUsagePrivate()
DiskUsage::DiskUsage(QObject *parent)
: QObject(parent)
, d_ptr(new DiskUsagePrivate(this))
, m_working(false)
{
}

Expand All @@ -200,14 +239,27 @@ DiskUsage::~DiskUsage()

void DiskUsage::calculate(const QStringList &paths, QJSValue callback)
{
QJSValue *cb = 0;
QJSValue *cb = nullptr;

if (!callback.isNull() && !callback.isUndefined() && callback.isCallable()) {
cb = new QJSValue(callback);
}

setStatus(DiskUsage::Calculating);
setWorking(true);
emit submit(paths, cb);
emit submit(paths, cb, QPrivateSignal());
}

void DiskUsage::fileCount(const QString &path, QJSValue callback, bool recursive)
{
QJSValue *cb = nullptr;

if (!callback.isNull() && !callback.isUndefined() && callback.isCallable()) {
cb = new QJSValue(callback);
}

setStatus(DiskUsage::Counting);
emit startCounting(path, cb, recursive, QPrivateSignal());
}

void DiskUsage::finished(QVariantMap usage, QJSValue *callback)
Expand All @@ -218,13 +270,54 @@ void DiskUsage::finished(QVariantMap usage, QJSValue *callback)
}

// the result has been set, so emit resultChanged() even if result was not valid
m_result = usage;
Q_D(DiskUsage);
d->m_result = usage;
emit resultChanged();

setStatus(DiskUsage::Idle);
setWorking(false);
}

void DiskUsage::countingFinished(const int &counter, QJSValue *callback)
{
if (callback) {
callback->call(QJSValueList() << callback->engine()->toScriptValue(counter));
delete callback;
}

setStatus(DiskUsage::Idle);
}

bool DiskUsage::working() const {
Q_D(const DiskUsage);
return d->m_working;
}

DiskUsage::Status DiskUsage::status() const {
Q_D(const DiskUsage);
return d->m_status;
}

void DiskUsage::setWorking(bool working) {
Q_D(DiskUsage);
if (d->m_working != working) {
d->m_working = working;
emit workingChanged();
}
}

QVariantMap DiskUsage::result() const
{
return m_result;
Q_D(const DiskUsage);
return d->m_result;
}

void DiskUsage::setStatus(DiskUsage::Status status)
{
Q_D(DiskUsage);
if (d->m_status == status)
return;

d->m_status = status;
emit statusChanged(d->m_status);
}
37 changes: 22 additions & 15 deletions src/plugin/diskusage.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2015 Jolla Ltd.
* Contact: Thomas Perl <thomas.perl@jolla.com>
* Copyright (C) 2015 - 2019 Jolla Ltd.
* Copyright (c) 2019 Open Mobile Platform LLC.
*
* You may use this file under the terms of the BSD license as follows:
*
Expand Down Expand Up @@ -51,41 +51,48 @@ class FILEMANAGER_EXPORT DiskUsage: public QObject
Q_PROPERTY(bool working READ working NOTIFY workingChanged)

Q_PROPERTY(QVariantMap result READ result NOTIFY resultChanged)
Q_PROPERTY(Status status READ status WRITE setStatus NOTIFY statusChanged)


public:
explicit DiskUsage(QObject *parent=nullptr);
explicit DiskUsage(QObject *parent = nullptr);
virtual ~DiskUsage();

enum Status{
Idle,
Calculating,
Counting
};
Q_ENUM(Status)

// Calculate the disk usage of the given paths, then call
// callback with a QVariantMap (mapping paths to usages in bytes)
Q_INVOKABLE void calculate(const QStringList &paths, QJSValue callback);

Q_INVOKABLE void fileCount(const QString &path, QJSValue callback, bool recursive = false);
QVariantMap result() const;

signals:
void workingChanged();
void resultChanged();
void statusChanged(Status status);

signals:
void submit(QStringList paths, QJSValue *callback);
void submit(QStringList paths, QJSValue *callback, QPrivateSignal);
void startCounting(const QString &path, QJSValue *callback, bool recursive, QPrivateSignal);

private slots:
void finished(QVariantMap usage, QJSValue *callback);
void countingFinished(const int &counter, QJSValue *callback);

private:
bool working() const { return m_working; }
bool working() const;
Status status() const;

void setWorking(bool working) {
if (m_working != working) {
m_working = working;
emit workingChanged();
}
}
void setStatus(Status status);
void setWorking(bool working);

private:
QScopedPointer<DiskUsagePrivate> const d_ptr;
QVariantMap m_result;
bool m_working;
QScopedPointer<DiskUsagePrivate> const d_ptr;
};

#endif /* DISKUSAGE_H */
5 changes: 5 additions & 0 deletions src/plugin/diskusage_p.h
Expand Up @@ -46,20 +46,25 @@ class DiskUsageWorker : public QObject
virtual ~DiskUsageWorker();

void scheduleQuit() { m_quit = true; }
void sheduleStopCounting() { m_stopCounting = true; }

public slots:
void submit(QStringList paths, QJSValue *callback);
void startCounting(const QString &path, QJSValue *callback, bool recursive);

signals:
void finished(QVariantMap usage, QJSValue *callback);
void countingFinished(const int &counter, QJSValue *callback);

private:
QVariantMap calculate(QStringList paths);
quint64 calculateSize(QString directory, QString *expandedPath, bool androidHomeExists);
quint64 calculateRpmSize(const QString &glob);
quint64 calculateApkdSize(const QString &rest);
int counting(const QString &path, bool recursive);

bool m_quit;
bool m_stopCounting;

friend class Ut_DiskUsage;
};
Expand Down
24 changes: 24 additions & 0 deletions src/plugin/plugins.qmltypes
Expand Up @@ -13,8 +13,21 @@ Module {
prototype: "QObject"
exports: ["Nemo.FileManager/DiskUsage 1.0"]
exportMetaObjectRevisions: [0]
Enum {
name: "Status"
values: {
"Idle": 0,
"Calculating": 1,
"Counting": 2
}
}
Property { name: "working"; type: "bool"; isReadonly: true }
Property { name: "result"; type: "QVariantMap"; isReadonly: true }
Property { name: "status"; type: "Status" }
Signal {
name: "statusChanged"
Parameter { name: "status"; type: "Status" }
}
Signal {
name: "submit"
Parameter { name: "paths"; type: "QStringList" }
Expand All @@ -25,6 +38,17 @@ Module {
Parameter { name: "paths"; type: "QStringList" }
Parameter { name: "callback"; type: "QJSValue" }
}
Method {
name: "fileCount"
Parameter { name: "path"; type: "string" }
Parameter { name: "callback"; type: "QJSValue" }
Parameter { name: "recursive"; type: "bool" }
}
Method {
name: "fileCount"
Parameter { name: "path"; type: "string" }
Parameter { name: "callback"; type: "QJSValue" }
}
}
Component {
name: "FileEngine"
Expand Down

0 comments on commit 6dc2c1a

Please sign in to comment.