diff options
author | Ken Moore <moorekou@gmail.com> | 2016-04-25 13:08:12 -0400 |
---|---|---|
committer | Ken Moore <moorekou@gmail.com> | 2016-04-25 13:08:12 -0400 |
commit | ed5ecf7ea7a482b4649e66ecb35fbc60af680684 (patch) | |
tree | acc0fa17d228259e847f55c678db9fb0a9b50f0c /src-qt5/desktop-utils/lumina-fm/DirData.h | |
parent | Merge branch 'master' of github.com:pcbsd/lumina (diff) | |
download | lumina-ed5ecf7ea7a482b4649e66ecb35fbc60af680684.tar.gz lumina-ed5ecf7ea7a482b4649e66ecb35fbc60af680684.tar.bz2 lumina-ed5ecf7ea7a482b4649e66ecb35fbc60af680684.zip |
Rearrange the Lumina source tree quite a bit:
Now the utilites are arranged by category (core, core-utils, desktop-utils), so all the -utils may be excluded by a package system (or turned into separate packages) as needed.
Diffstat (limited to 'src-qt5/desktop-utils/lumina-fm/DirData.h')
-rw-r--r-- | src-qt5/desktop-utils/lumina-fm/DirData.h | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/src-qt5/desktop-utils/lumina-fm/DirData.h b/src-qt5/desktop-utils/lumina-fm/DirData.h new file mode 100644 index 00000000..c3ace5a4 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/DirData.h @@ -0,0 +1,188 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +// This is the backend classes for fetching directory information/contents +//=========================================== +#ifndef _LUMINA_FM_BACKGROUND_DATA_CLASSES_H +#define _LUMINA_FM_BACKGROUND_DATA_CLASSES_H + +#include <QObject> +#include <QList> +#include <QString> +#include <QFileInfo> +#include <QDir> + +#include <LuminaXDG.h> +#include <LuminaUtils.h> + +#define ZSNAPDIR QString("/.zfs/snapshot/") + +#define DIR_DEBUG 0 + +//Class used for keeping track of directory information in the HASH +class LDirInfoList{ +public: + //Internal variables + QDateTime lastcheck; + QList<LFileInfo> list; + QStringList fileNames; //list of filenames for comparison/checking sorting + QString dirpath; //directory this structure was reading + QString snapdir; //base snapshot directory (if one was requested/found) + bool hashidden; + + //Access Functions + LDirInfoList(QString path = ""){ + dirpath = path; + list.clear(); + fileNames.clear(); + hashidden = false; + } + ~LDirInfoList(){} + + //(re)Load a directory contents + void update(bool showhidden = false){ + if(dirpath.isEmpty()){ return; } //nothing to do + //Assemble the structures + QDir dir(dirpath); + hashidden = showhidden; + if(!dir.exists()){ + list.clear(); + fileNames.clear(); + dirpath.clear(); //invalid directory now + return; + } + if(dirpath.contains(ZSNAPDIR) && snapdir.isEmpty()){ + snapdir = dirpath.section(ZSNAPDIR,0,0)+ZSNAPDIR; //no need to go looking for it later + } + QFileInfoList dirlist; + //Fill the structure + list.clear(); + fileNames.clear(); + lastcheck = QDateTime::currentDateTime().addMSecs(-500); //prevent missing any simultaneous dir changes + if(showhidden){ dirlist = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot | QDir::Hidden , QDir::Name | QDir::DirsFirst); } + else{ dirlist = dir.entryInfoList(QDir::AllEntries | QDir::NoDotAndDotDot , QDir::Name | QDir::DirsFirst); } + //Simple add routine - can make it more dynamic/selective about updating individual items later + for(int i=0; i<dirlist.length(); i++){ + list << LFileInfo(dirlist[i]); //generate the extra information for this file + fileNames << dirlist[i].fileName(); //add the filename to the list + } + } + + void findSnapDir(){ + //Search the filesystem + if(dirpath.contains(ZSNAPDIR)){ + snapdir = dirpath.section(ZSNAPDIR,0,0)+ZSNAPDIR; //no need to go looking for it + }else{ + //Need to backtrack + QDir dir(dirpath); + bool found = false; + while(dir.canonicalPath()!="/" && !found){ + //qDebug() << " -- Checking for snapshot dir:" << dir.canonicalPath(); + if(dir.exists(".zfs/snapshot")){ + snapdir = dir.canonicalPath()+ZSNAPDIR; + found = true; + }else{ + dir.cdUp(); + } + }//end loop + } + } + +}; + +//This class is designed to be run in a background thread and get all the necessary info for a directory listing +class DirData : public QObject{ + Q_OBJECT +private: + QHash<QString, LDirInfoList> HASH; //Where we cache any info for rapid access later + +signals: + void DirDataAvailable(QString, QString, LFileInfoList); //[ID, Dirpath, DATA] + void SnapshotDataAvailable(QString, QString, QStringList); //[ID, BaseSnapDir, SnapNames] + +public: + //Variables + bool showHidden; //Whether hidden files/dirs should be output + bool zfsavailable; //Whether it should even bother looking for ZFS snapshots + bool pauseData; //When paused - this will ignore any requests for information (need to manually refresh browsers after unpause) + + //Functions + DirData(){ + showHidden = false; + zfsavailable = false; + pauseData = false; + } + ~DirData(){} + +public slots: + void GetDirData(QString ID, QString dirpath){ + if(pauseData){ return; } + if(DIR_DEBUG){ qDebug() << "GetDirData:" << ID << dirpath; } + //The ID is used when returning the info in a moment + //Make sure to use the canonical path in the HASH search - don't use + QString canon = QFileInfo(dirpath).canonicalFilePath(); + if(!HASH.contains(canon)){ + //New directory (not previously loaded) + LDirInfoList info(canon); + info.update(showHidden); + HASH.insert(canon, info); + }else{ + //See if the saved info needs to be updated + //if( (HASH.value(canon).hashidden != showHidden) || (QFileInfo(canon).lastModified() > HASH.value(canon).lastcheck) ){ + HASH[canon].update(showHidden); + //} + } + if(DIR_DEBUG){ qDebug() << " -- Dir Data Found:" << ID << dirpath << HASH.value(canon).list.length(); } + emit DirDataAvailable(ID, dirpath, HASH.value(canon).list); + } + + void GetSnapshotData(QString ID, QString dirpath){ + if(pauseData){ return; } + if(DIR_DEBUG){ qDebug() << "GetSnapshotData:" << ID << dirpath; } + QString base; QStringList snaps; + //Only check if ZFS is flagged as available + if(zfsavailable){ + //First find if the hash already has an entry for this directory + if(false){ //!HASH.contains(dirpath)){ + LDirInfoList info(dirpath); + HASH.insert(dirpath,info); + } + //Now see if a snapshot directory has already been located + if(HASH.value(dirpath).snapdir.isEmpty()){ + HASH[dirpath].findSnapDir(); + } + //Now read off all the available snapshots + if(HASH.value(dirpath).snapdir != "-" && !HASH.value(dirpath).snapdir.isEmpty()){ + //Good snapshot directory found - read off the current snapshots (can change regularly - don't cache this) + base = HASH.value(dirpath).snapdir; + QDir dir(base); + QString canon = QFileInfo(dirpath).canonicalFilePath(); + QString dcanon = QString(dir.canonicalPath()+"/").section(ZSNAPDIR,0,0); + QString relpath = canon.section( dcanon+"/" ,-1); + //qDebug() << "Snapshot Dir:" << base << dcanon << "Dir:" << dirpath << canon << "Relpath:" << relpath; + snaps = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time |QDir::Reversed ); + //Also remove any "empty" snapshots (might be leftover by tools like "zfsnap") + for(int i=0; i<snaps.length(); i++){ + dir.cd(base+"/"+snaps[i]); + if(relpath.isEmpty()){ + //Make sure the snapshot is not empty + if(dir.count() < 3 && dir.exists() ){ snaps.removeAt(i); i--; } // "." and ".." are always in the count + //Make sure the snapshot contains the directory we are looking for + }else if(!dir.exists(relpath)){ snaps.removeAt(i); i--; } + } + //NOTE: snaps are sorted oldest -> newest + } + + } + //if(DIR_DEBUG){ qDebug() << " -- Snap Data Found:" << ID << base << snaps; } + if(!base.isEmpty() && !snaps.isEmpty()){ + emit SnapshotDataAvailable(ID, base, snaps); + } + } + +}; + +#endif |