aboutsummaryrefslogtreecommitdiff
path: root/lumina-fm
diff options
context:
space:
mode:
Diffstat (limited to 'lumina-fm')
-rw-r--r--lumina-fm/DirData.h84
-rw-r--r--lumina-fm/widgets/DirWidget.cpp191
-rw-r--r--lumina-fm/widgets/DirWidget.h78
-rw-r--r--lumina-fm/widgets/DirWidget.ui122
-rw-r--r--lumina-fm/widgets/SlideshowWidget.h4
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>
bgstack15