diff options
Diffstat (limited to 'lumina-fm')
-rw-r--r-- | lumina-fm/DirData.h | 84 | ||||
-rw-r--r-- | lumina-fm/widgets/DirWidget.cpp | 191 | ||||
-rw-r--r-- | lumina-fm/widgets/DirWidget.h | 78 | ||||
-rw-r--r-- | lumina-fm/widgets/DirWidget.ui | 122 | ||||
-rw-r--r-- | lumina-fm/widgets/SlideshowWidget.h | 4 |
5 files changed, 416 insertions, 63 deletions
diff --git a/lumina-fm/DirData.h b/lumina-fm/DirData.h index ee2c8429..cbfa1855 100644 --- a/lumina-fm/DirData.h +++ b/lumina-fm/DirData.h @@ -18,6 +18,8 @@ #include <LuminaXDG.h> #include <LuminaUtils.h> +#define ZSNAPDIR QString("/.zfs/snapshot/") + //Need some extra information not usually available by a QFileInfo class LFileInfo : public QFileInfo{ private: @@ -74,7 +76,16 @@ public: // -- Return the icon to use for this file QString iconfile(){ - return (icon.isEmpty() ? mime: icon); //Fall back on the mimetype if no icon listed + if(!icon.isEmpty()){ + return icon; + }else{ + if(!mime.isEmpty()){ + return mime.replace("/","-"); + }else if(this->isExecutable()){ + return "application-x-executable"; + } + } + return ""; //Fall back to nothing } // -- Check if this is an XDG desktop file @@ -106,6 +117,7 @@ public: 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 @@ -129,6 +141,9 @@ public: 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(); @@ -141,7 +156,26 @@ public: 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 + } } }; @@ -153,34 +187,64 @@ private: QHash<QString, LDirInfoList> HASH; //Where we cache any info for rapid access later signals: - void DirDataAvailable(QString, QList<LFileInfo>); //[ID, DATA] + void DirDataAvailable(QString, QString, QList<LFileInfo>); //[ID, Dirpath, DATA] + void SnapshotDataAvailable(QString, QString, QStringList); //[ID, BaseSnapDir, SnapNames] public: //Variables - bool showHidden; + bool showHidden; //Whether hidden files/dirs should be output + bool zfsavailable; //Whether it should even bother looking for ZFS snapshots //Functions DirData(){ showHidden = false; + zfsavailable = false; } ~DirData(){} public slots: void GetDirData(QString ID, QString dirpath){ //The ID is used when returning the info in a moment - if(!HASH.contains(dirpath)){ + //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(dirpath); + LDirInfoList info(canon); info.update(showHidden); - HASH.insert(dirpath, info); + HASH.insert(canon, info); }else{ //See if the saved info needs to be updated - if( (HASH.value(dirpath).hashidden != showHidden) || (QFileInfo(dirpath).lastModified() > HASH.value(dirpath).lastcheck) ){ - HASH[dirpath].update(showHidden); + if( (HASH.value(canon).hashidden != showHidden) || (QFileInfo(canon).lastModified() > HASH.value(canon).lastcheck) ){ + HASH[canon].update(showHidden); + } + } + emit DirDataAvailable(ID, dirpath, HASH.value(canon).list); + } + + void GetSnapshotData(QString ID, QString 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(!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 != "-"){ + //Good snapshot directory found - read off the current snapshots (can change regularly - don't cache this) + base = HASH.value(dirpath).snapdir; + QDir dir(base); + snaps = dir.entryList(QDir::Dirs | QDir::NoDotAndDotDot, QDir::Time); + //NOTE: snaps are sorted oldest -> newest } } - emit DirDataAvailable(ID, HASH.value(dirpath).list); + emit SnapshotDataAvailable(ID, base, snaps); } }; diff --git a/lumina-fm/widgets/DirWidget.cpp b/lumina-fm/widgets/DirWidget.cpp new file mode 100644 index 00000000..75a0bc79 --- /dev/null +++ b/lumina-fm/widgets/DirWidget.cpp @@ -0,0 +1,191 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "DirWidget.h" +#include "ui_DirWidget.h" + +DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){ + ui->setupUi(this); //load the designer file + setShowDetails(true); + UpdateIcons(); + UpdateText(); + setupConnections(); +} + +DirWidget::~DirWidget(){ + +} + +QString DirWidget::id(){ + return ID; +} + +void DirWidget::setShowDetails(bool show){ + showDetails = show; + ui->listWidget->setVisible(!showDetails); + ui->treeWidget->setVisible(showDetails); +} + +void DirWidget::setShowSidebar(bool show){ + this->stacked_actions->setVisible(show); +} + +void DirWidget::setDetails(QList<DETAILTYPES> list){ + listDetails = list; + LoadDir(CDIR, CLIST); //just refresh the UI +} + +// ================ +// PUBLIC SLOTS +// ================ +void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){ + if(dir.isEmpty()){ return; } //nothing to do + CLIST = list; //save for later + CDIR = dir; + //Determine if this is an internal ZFS snapshot + bool loadsnaps = false; + if( dir.contains(ZSNAPDIR) ){ + //This is a zfs snapshot - only update the saved paths necessary to rotate between snapshots/system + snaprelpath = dir.section(ZSNAPDIR,1,1000).section("/",1,1000); //the relative path inside the snapshot + normalbasedir = dir.section(ZSNAPDIR,0,0)+"/"+snaprelpath; //Update the new base directory + ui->stacked_actions->setCurrentWidget(ui->page_restore); + //See if this was a manual move to the directory, or an internal move + QString tmp = dir.section(ZSNAPDIR,0,0); + if(tmp != snapbasedir.section(ZSNAPDIR,0,0)){ + loadsnaps = true; //different snapshot loaded - need to update internally + } + }else{ + //This is a normal directory - prompt for snapshot information + normalbasedir = dir; + snapbasedir.clear(); + ui->stacked_actions->setCurrentWidget(ui->page_dir); + loadsnaps = true; + } + if(loadsnaps){ + //kick this off while still loading the dir contents + ui->group_snaps->setEnabled(false); //to prevent the snap updates to be automatically used + ui->group_snaps->setVisible(false); + ui->slider_snap->setRange(1,1); + emit findSnaps(ID, normalbasedir); + } + //Clear the display widget + if(showDetails){ + ui->treeWidget->clear(); + //Need to re-create the header item as well + QTreeWidgetItem *it = new QTreeWidgetItem(); + for(int t=0; t<listDetails.length(); t++){ + it-> + } + ui->treeWidget->setHeaderItem(it); + }else{ ui->listWidget->clear(); } + //Now fill the display widget + for(int i=0; i<list.length(); i++){ + if(showDetails){ + //Now create all the individual items + QTreeWidgetItem *it = new QTreeWidgetItem(); + it->setWhatsThis(list[i].fileName()); + for(int t=0; t<listDetails.length(); t++){ + switch(listDetails[t]){ + case NAME: + it->setText(t,list[i].fileName()); + if(list[i].isImage()){ + it->setIcon(t, QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(64) ) ); + }else{ + it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"unknown") ); + } + break; + case SIZE: + if(!list[i].isDir()){ + it->setText(t, LUtils::BytesToDisplaySize(list[i].size()) ); + } + break; + case TYPE: + it->setText(t, list[i].mimetype()); + case DATEMOD: + it->setText(t, list[i].lastModified().toString(Qt:DefaultLocaleShortDate); + break; + case DATECREATE: + it->setText(t, list[i].created().toString(Qt:DefaultLocaleShortDate); + break; + } + } + ui->treeWidget->addTopLevelItem(it); + }else{ + + } + QApplication::processEvents(); //keep the UI snappy while loading a directory + } +} + +void DirWidget::LoadSnaps(QString basedir, QStringList snaps){ + //Save these value internally for use later + snapbasedir = basedir; + snapshots = snaps; + //Now update the UI as necessary + + ui->slider_snap->setRange(1, snaps.length()+1); + if(CDIR.contains(ZSNAPDIR)){ + //The user was already within a snapshot - figure out which one and set the slider appropriately + int index = snaps.indexOf( CDIR.section(ZSNAPDIR,1,1).section("/",0,0) ); + if(index < 0){ index = snaps.length()+1; } //unknown - load the system (should never happen) + ui->slider_snap_setValue(index); + }else{ + ui->slider_snap->setValue(snaps.length()+1); //last item (normal system) + } + QApplication::processEvents(); //let the slider changed signal get thrown away before we re-enable the widget + ui->group_snaps->setEnabled(!snaps.isEmpty()); + ui->group_snaps->setVisible(!snaps.isEmpty()); + ui->tool_snap_newer->setEnabled(ui->slider_snap->value() < ui->slider_snap->maximum()); + ui->tool_snap_older->setEnabled(ui->slider_snap->value() > ui->slider_snap->minimum()); + +} + +//Theme change functions +void DirWidget::UpdateIcons(){ + //ui->tool_addNewFile->setIcon( LXDG::findIcon("document-new","")); + //ui->tool_addToDir->setIcon( LXDG::findIcon("folder-new","") ); + + //Snapshot buttons + ui->tool_snap_newer->setIcon(LXDG::findIcon("go-next-view","") ); + ui->tool_snap_older->setIcon(LXDG::findIcon("go-previous-view","") ); + //Botton-Action Buttons + ui->tool_goToImages->setIcon( LXDG::findIcon("fileview-preview","") ); + ui->tool_goToPlayer->setIcon( LXDG::findIcon("applications-multimedia","") ); + //Side-Action Buttons + ui->tool_act_run->setIcon( LXDG::findIcon("run-build-file","") ); + ui->tool_act_runwith->setIcon( LXDG::findIcon("run-build-configure","") ); + ui->tool_act_cut->setIcon( LXDG::findIcon("edit-cut","") ); + ui->tool_act_copy->setIcon( LXDG::findIcon("edit-copy","") ); + ui->tool_act_paste->setIcon( LXDG::findIcon("edit-paste","") ); + ui->tool_act_rename->setIcon( LXDG::findIcon("edit-rename","") ); + ui->tool_act_rm->setIcon( LXDG::findIcon("edit-delete","") ); + ui->tool_act_fav->setIcon( LXDG::findIcon("bookmark-toolbar","") ); + //Restore-Action Buttons + ui->tool_restore->setIcon( LXDG::findIcon("document-revert","") ); + ui->tool_restore_over->setIcon( LXDG::findIcon("document-revert","") ); +} + +void DirWidget::UpdateText(){ + ui->retranslateUi(this); +} + + +// ================= +// PRIVATE +// ================= +void DirWidget::setupConnections(){ + //Tree Widget interaction + connect(ui->tree_dir_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ItemRun(const QModelIndex&)) ); + connect(ui->list_dir_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ItemRun(const QModelIndex&)) ); + connect(ui->tree_dir_view, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu(const QPoint&)) ); + connect(ui->list_dir_view, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu(const QPoint&)) ); + connect(ui->tree_dir_view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(ItemSelectionChanged()) ); + connect(ui->list_dir_view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(ItemSelectionChanged()) ); +} + +// ================= +// PRIVATE SLOTS +// =================
\ No newline at end of file diff --git a/lumina-fm/widgets/DirWidget.h b/lumina-fm/widgets/DirWidget.h new file mode 100644 index 00000000..49e59454 --- /dev/null +++ b/lumina-fm/widgets/DirWidget.h @@ -0,0 +1,78 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#ifndef _LUMINA_FM_DIRECTORY_BROWSER_WIDGET_H +#define _LUMINA_FM_DIRECTORY_BROWSER_WIDGET_H + +#include <QList> +#include <QWidget> +#include <QObject> + +#include "../DirData.h" + +#define ZSNAPDIR QString("/.zfs/snapshot/") + +namespace Ui{ + class DirWidget; +}; + +class DirWidget : public QWidget{ + Q_OBJECT +public: + enum DETAILTYPES{ NAME, SIZE, TYPE, DATEMOD, DATECREATE}; + DirWidget(QString objID, QWidget *parent = 0); //needs a unique ID (to distinguish from other DirWidgets) + ~DirWidget(); + + QString id(); + void setShowDetails(bool show); + void setShowSidebar(bool show); + void setDetails(QList<DETAILTYPES> list); + +public slots: + void LoadDir(QString dir, QList<LFileInfo> list); + void LoadSnaps(QString basedir, QStringList snaps); + + //Theme change functions + void UpdateIcons(); + void UpdateText(); + +private: + Ui::DirWidget *ui; + QString ID, CDIR; //unique ID assigned by the parent and the current dir path + QList<LFileInfo> CLIST; //current item list (snap or not) + QString normalbasedir, snapbasedir, snaprelpath; //for maintaining direcoty context while moving between snapshots + QStringList snapshots; + bool showDetails; //which widget to use for showing items + QList<DETAILTYPES> listDetails; + + void setupConnections(); + +private slots: + //UI BUTTONS + // -- Left Action Buttons + void on_tool_act_copy_clicked(); + void on_tool_act_cut_clicked(); + void on_tool_act_fav_clicked(); + void on_tool_act_paste_clicked(); + void on_tool_act_rename_clicked(); + void on_tool_act_rm_clicked(); + void on_tool_act_run_clicked(); + void on_tool_act_runwith_clicked(); + // -- Left Restore Buttons + void on_tool_restore_clicked(); + void on_tool_restore_over_clicked(); + // -- Bottom Action Buttons + void on_tool_goToImages_clicked(); + void on_tool_goToPlayer_clicked(); + // -- Top Snapshot Buttons + void on_tool_snap_newer_clicked(); + void on_tool_snap_older_clicked(); + void on_slider_snap_valueChanged(int); +signals: + void LoadDirectory(QString, QString); //ID, dirpath + void findSnaps(QString, QString); //ID, dirpath +}; +#endif
\ No newline at end of file diff --git a/lumina-fm/widgets/DirWidget.ui b/lumina-fm/widgets/DirWidget.ui index 8c683041..9c0a73a1 100644 --- a/lumina-fm/widgets/DirWidget.ui +++ b/lumina-fm/widgets/DirWidget.ui @@ -7,7 +7,7 @@ <x>0</x> <y>0</y> <width>400</width> - <height>300</height> + <height>333</height> </rect> </property> <property name="windowTitle"> @@ -27,7 +27,7 @@ <number>0</number> </property> <item row="0" column="0"> - <widget class="QStackedWidget" name="stackedWidget"> + <widget class="QStackedWidget" name="stacked_actions"> <property name="sizePolicy"> <sizepolicy hsizetype="Minimum" vsizetype="Preferred"> <horstretch>0</horstretch> @@ -395,51 +395,71 @@ <number>1</number> </property> <item> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QLabel" name="label_snap"> - <property name="text"> - <string notr="true">Snap</string> - </property> - </widget> - </item> - <item> - <widget class="QSlider" name="slider_snap"> - <property name="minimum"> - <number>1</number> - </property> - <property name="value"> - <number>1</number> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="invertedAppearance"> - <bool>false</bool> - </property> - <property name="invertedControls"> - <bool>false</bool> - </property> - <property name="tickPosition"> - <enum>QSlider::TicksAbove</enum> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="tool_snap_older"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - <item> - <widget class="QToolButton" name="tool_snap_newer"> - <property name="text"> - <string>...</string> - </property> - </widget> - </item> - </layout> + <widget class="QGroupBox" name="group_snaps"> + <property name="title"> + <string>Snapshots Available</string> + </property> + <property name="flat"> + <bool>true</bool> + </property> + <layout class="QHBoxLayout" name="horizontalLayout_3"> + <property name="leftMargin"> + <number>1</number> + </property> + <property name="topMargin"> + <number>1</number> + </property> + <property name="rightMargin"> + <number>1</number> + </property> + <property name="bottomMargin"> + <number>1</number> + </property> + <item> + <widget class="QLabel" name="label_snap"> + <property name="text"> + <string notr="true">Snap</string> + </property> + </widget> + </item> + <item> + <widget class="QSlider" name="slider_snap"> + <property name="minimum"> + <number>1</number> + </property> + <property name="value"> + <number>1</number> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + <property name="invertedAppearance"> + <bool>false</bool> + </property> + <property name="invertedControls"> + <bool>false</bool> + </property> + <property name="tickPosition"> + <enum>QSlider::TicksAbove</enum> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="tool_snap_older"> + <property name="text"> + <string notr="true">...</string> + </property> + </widget> + </item> + <item> + <widget class="QToolButton" name="tool_snap_newer"> + <property name="text"> + <string notr="true">...</string> + </property> + </widget> + </item> + </layout> + </widget> </item> <item> <widget class="QTreeWidget" name="treeWidget"> @@ -475,16 +495,16 @@ </widget> </item> <item> - <widget class="QToolButton" name="toolButton_5"> + <widget class="QToolButton" name="tool_goToImages"> <property name="text"> - <string>...</string> + <string notr="true">img</string> </property> </widget> </item> <item> - <widget class="QToolButton" name="toolButton_6"> + <widget class="QToolButton" name="tool_goToPlayer"> <property name="text"> - <string>...</string> + <string notr="true">play</string> </property> </widget> </item> diff --git a/lumina-fm/widgets/SlideshowWidget.h b/lumina-fm/widgets/SlideshowWidget.h index 70f9a29b..bd8a671d 100644 --- a/lumina-fm/widgets/SlideshowWidget.h +++ b/lumina-fm/widgets/SlideshowWidget.h @@ -4,8 +4,8 @@ // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== -#ifndef _LUMINA_FM_SLIDWSHOW_WIDGET_H -#define _LUMINA_FM_SLIDWSHOW_WIDGET_H +#ifndef _LUMINA_FM_SLIDESHOW_WIDGET_H +#define _LUMINA_FM_SLIDESHOW_WIDGET_H #include <QList> #include <QWidget> |