feat: file iterator async support

( #8 )
This commit is contained in:
Gary Wang 2019-07-30 20:19:53 +08:00 committed by GitHub
parent 2ff601c30e
commit 5ecfcf6935
Failed to generate hash of commit
5 changed files with 147 additions and 3 deletions

View file

@ -34,6 +34,10 @@ public:
QString uri() const;
QExplicitlySharedDataPointer<DGioFileInfo> createFileSystemInfo();
QExplicitlySharedDataPointer<DGioFileIterator> createFileIterator(QString attr = "*", DGioFileQueryInfoFlags queryInfoFlags = FILE_QUERY_INFO_NONE);
void createFileIteratorAsync(QString attr = "*", DGioFileQueryInfoFlags queryInfoFlags = FILE_QUERY_INFO_NONE);
Q_SIGNALS:
void createFileIteratorReady(QExplicitlySharedDataPointer<DGioFileIterator> iter);
private:
QScopedPointer<DGioFilePrivate> d_ptr;

View file

@ -8,6 +8,43 @@ namespace Gio {
class FileEnumerator;
}
enum DGioIOPriority
{
/*! Use this for high priority event sources. It is not used within
* GLib or GTK+.<br><br>
*/
PRIORITY_HIGH = -100,
/*! Use this for default priority event sources. In glibmm this
* priority is used by default when installing timeout handlers with
* SignalTimeout::connect(). In GDK this priority is used for events
* from the X server.<br><br>
*/
PRIORITY_DEFAULT = 0,
/*! Use this for high priority idle functions. GTK+ uses
* <tt>PRIORITY_HIGH_IDLE&nbsp;+&nbsp;10</tt> for resizing operations, and
* <tt>PRIORITY_HIGH_IDLE&nbsp;+&nbsp;20</tt> for redrawing operations.
* (This is done to ensure that any pending resizes are processed before
* any pending redraws, so that widgets are not redrawn twice unnecessarily.)
* <br><br>
*/
PRIORITY_HIGH_IDLE = 100,
/*! Use this for default priority idle functions. In glibmm this priority is
* used by default when installing idle handlers with SignalIdle::connect().
* <br><br>
*/
PRIORITY_DEFAULT_IDLE = 200,
/*! Use this for very low priority background tasks. It is not used within
* GLib or GTK+.
*/
PRIORITY_LOW = 300
};
Q_ENUMS(DGioIOPriority);
class DGioFileInfo;
class DGioFileIteratorPrivate;
class DGioFileIterator : public QObject, public QSharedData
@ -18,6 +55,11 @@ public:
~DGioFileIterator();
QExplicitlySharedDataPointer<DGioFileInfo> nextFile();
void nextFilesAsync(int numberOfFiles = 1, DGioIOPriority io_priority = PRIORITY_DEFAULT);
Q_SIGNALS:
void nextFilesReady(QList<QExplicitlySharedDataPointer<DGioFileInfo> > fileInfoList);
void nextFilesCancelled();
private:
QScopedPointer<DGioFileIteratorPrivate> d_ptr;

View file

@ -26,6 +26,8 @@ private:
DGioFile *q_ptr;
void slot_enumerateChildrenAsyncResult(const Glib::RefPtr<Gio::AsyncResult>& result);
Q_DECLARE_PUBLIC(DGioFile)
};
@ -46,6 +48,20 @@ QString DGioFilePrivate::uri() const
return QString::fromStdString(m_gmmFilePtr->get_uri());
}
void DGioFilePrivate::slot_enumerateChildrenAsyncResult(const Glib::RefPtr<AsyncResult> &result)
{
Q_Q(DGioFile);
try {
Glib::RefPtr<Gio::FileEnumerator> iter = m_gmmFilePtr->enumerate_children_finish(result);
QExplicitlySharedDataPointer<DGioFileIterator> fileIterPtr(new DGioFileIterator(iter.release()));
Q_EMIT q->createFileIteratorReady(fileIterPtr);
} catch (const Glib::Error & error) {
qDebug() << QString::fromStdString(error.what().raw());
}
}
// -------------------------------------------------------------
DGioFile::DGioFile(File* gmmFilePtr, QObject *parent)
@ -168,9 +184,10 @@ QExplicitlySharedDataPointer<DGioFileIterator> DGioFile::createFileIterator(QStr
{
Q_D(DGioFile);
unsigned int flagValue = queryInfoFlags;
FileQueryInfoFlags flags = static_cast<FileQueryInfoFlags>(flagValue);
try {
unsigned int flagValue = queryInfoFlags;
FileQueryInfoFlags flags = static_cast<FileQueryInfoFlags>(flagValue);
Glib::RefPtr<FileEnumerator> gmmFileEnumerator = d->getGmmFileInstance()->enumerate_children(attr.toStdString(), flags);
QExplicitlySharedDataPointer<DGioFileIterator> fileIterPtr(new DGioFileIterator(gmmFileEnumerator.release()));
@ -181,3 +198,13 @@ QExplicitlySharedDataPointer<DGioFileIterator> DGioFile::createFileIterator(QStr
return QExplicitlySharedDataPointer<DGioFileIterator>(nullptr);
}
void DGioFile::createFileIteratorAsync(QString attr, DGioFileQueryInfoFlags queryInfoFlags)
{
Q_D(DGioFile);
unsigned int flagValue = queryInfoFlags;
FileQueryInfoFlags flags = static_cast<FileQueryInfoFlags>(flagValue);
d->getGmmFileInstance()->enumerate_children_async(sigc::mem_fun(d, &DGioFilePrivate::slot_enumerateChildrenAsyncResult),
attr.toStdString(), flags);
}

View file

@ -1,6 +1,7 @@
#include "dgiofileiterator.h"
#include "dgiofileiterator.h"
#include "dgiofileinfo.h"
#include <glibmm.h>
#include <glibmm/refptr.h>
#include <giomm/init.h>
@ -22,6 +23,8 @@ private:
DGioFileIterator *q_ptr;
void slot_nextFileAsyncResult(const Glib::RefPtr<Gio::AsyncResult>& result);
Q_DECLARE_PUBLIC(DGioFileIterator)
};
@ -37,6 +40,32 @@ Glib::RefPtr<FileEnumerator> DGioFileIteratorPrivate::getGmmFileEnumeratorInstan
return m_gmmFileEnumeratorPtr;
}
void DGioFileIteratorPrivate::slot_nextFileAsyncResult(const Glib::RefPtr<AsyncResult> &result)
{
Q_Q(DGioFileIterator);
try {
Glib::ListHandle< Glib::RefPtr<FileInfo> > files = m_gmmFileEnumeratorPtr->next_files_finish(result);
QList<QExplicitlySharedDataPointer<DGioFileInfo> > fileInfoList;
for (auto gmmFileInfoPtr : files) {
QExplicitlySharedDataPointer<DGioFileInfo> info(new DGioFileInfo(gmmFileInfoPtr.release()));
fileInfoList.append(info);
}
Q_EMIT q->nextFilesReady(fileInfoList);
} catch (const Gio::Error& error) {
if (error.code() != Gio::Error::CANCELLED) {
Q_EMIT q->nextFilesCancelled();
} else {
// should we add an error signal?
qDebug() << QString::fromStdString(error.what().raw());
}
} catch (const Glib::Error& error) {
// should we add an error signal?
qDebug() << QString::fromStdString(error.what().raw());
}
}
// -------------------------------------------------------------
@ -70,3 +99,12 @@ QExplicitlySharedDataPointer<DGioFileInfo> DGioFileIterator::nextFile()
return QExplicitlySharedDataPointer<DGioFileInfo>(nullptr);
}
void DGioFileIterator::nextFilesAsync(int numberOfFiles, DGioIOPriority io_priority)
{
Q_D(DGioFileIterator);
d->getGmmFileEnumeratorInstance()->next_files_async(sigc::mem_fun(d, &DGioFileIteratorPrivate::slot_nextFileAsyncResult),
numberOfFiles, io_priority);
}

View file

@ -26,6 +26,39 @@ int main(int argc, char * argv[])
}
}
}
delete networkFile;
}
// // Can't do asynchronous next_files() on a file enumerator created synchronously
// DGioFile *recentFile1 = DGioFile::createFromUri("recent:///");
// QExplicitlySharedDataPointer<DGioFileIterator> iter1;
// if (recentFile1) {
// iter1 = recentFile1->createFileIterator("standard::*");
// if (iter1) {
// iter1->nextFilesAsync(5);
// QObject::connect(iter1.data(), &DGioFileIterator::nextFilesReady, [](QList<QExplicitlySharedDataPointer<DGioFileInfo> > fileInfoList){
// for (auto fi : fileInfoList) {
// qDebug() << "xxxxxx" << fi->displayName() << fi->fileType();
// }
// });
// }
// }
DGioFile *recentFile = DGioFile::createFromUri("recent:///");
QExplicitlySharedDataPointer<DGioFileIterator> iter;
if (recentFile) {
recentFile->createFileIteratorAsync("standard::*");
QObject::connect(recentFile, &DGioFile::createFileIteratorReady, [&iter](QExplicitlySharedDataPointer<DGioFileIterator> iterr){
iter = iterr;
if (iter) {
iter->nextFilesAsync(5);
QObject::connect(iter.data(), &DGioFileIterator::nextFilesReady, [](QList<QExplicitlySharedDataPointer<DGioFileInfo> > fileInfoList){
for (auto fi : fileInfoList) {
qDebug() << "under recent:" << fi->displayName() << fi->fileType();
}
});
}
});
}
qDebug() << "----------------------";