From 9fe8cb1f455f5c0c029a1340076cb2cae4e2716d Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Sep 2016 14:24:25 -0400 Subject: Get the new backend functional. This is still disabled for the moment, but the initial tests seem to indicate that the new backend is faster and more stable than the current system. --- src-qt5/desktop-utils/lumina-fm/Browser.cpp | 86 ++++++++++++++++++----- src-qt5/desktop-utils/lumina-fm/Browser.h | 28 +++++++- src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp | 44 ++++++++++-- src-qt5/desktop-utils/lumina-fm/BrowserWidget.h | 16 +++-- src-qt5/desktop-utils/lumina-fm/lumina-fm.pro | 8 ++- src-qt5/desktop-utils/lumina-fm/main.cpp | 12 ++++ 6 files changed, 157 insertions(+), 37 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-fm') diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp index b207604c..1312aca0 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp +++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp @@ -6,11 +6,20 @@ //=========================================== #include "Browser.h" +#include +#include +#include +#include + +#include + Browser::Browser(QObject *parent) : QObject(parent){ watcher = new QFileSystemWatcher(this); connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(fileChanged(QString)) ); connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) ); showHidden = false; + imageFormats = LUtils::imageExtensions(false); //lowercase suffixes + connect(this, SIGNAL(threadDone(QString, QByteArray)), this, SLOT(futureFinished(QString, QByteArray)), Qt::QueuedConnection); //will always be between different threads } Browser::~Browser(){ @@ -30,20 +39,30 @@ bool Browser::showingHiddenFiles(){ } // PRIVATE -void Browser::loadItem(QFileInfo info){ - LFileInfo linfo(info); - QIcon ico; - if(linfo.isImage()){ - QPixmap pix; - if(pix.load(info.absoluteFilePath()) ){ - if(pix.height()>128){ pix = pix.scaled(128, 128, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); } - ico.addPixmap(pix); +void Browser::loadItem(QString info){ + //qDebug() << "LoadItem:" << info; + ////FileItem item; + //itemame = info; + QByteArray bytes; + if(imageFormats.contains(info.section(".",-1).toLower()) ){ + QFile file(info); + if(file.open(QIODevice::ReadOnly)){ + bytes = file.readAll(); + file.close(); } - }else if(linfo.isDirectory()){ - ico = LXDG::findIcon("folder","inode/directory"); + + /*QPixmap pix; + if(pix.load(item.info.absoluteFilePath()) ){ + if(pix.height()>128){ pix = pix.scaled(128, 128, Qt::KeepAspectRatioByExpanding, Qt::SmoothTransformation); } + item.icon.addPixmap(pix); + }*/ + }/*else if(item.info.isDir()){ + item.icon = LXDG::findIcon("folder","inode/directory"); } - if(ico.isNull()){ ico = LXDG::findIcon(linfo.mimetype(), "unknown"); } - emit ItemDataAvailable(ico, linfo); + if(item.icon.isNull()){ item.icon = LXDG::findIcon(item.info.mimetype(), "unknown"); }*/ + //qDebug() << " - done with item:" << info; + emit threadDone(info, bytes); + //return item; } // PRIVATE SLOTS @@ -57,24 +76,53 @@ void Browser::dirChanged(QString dir){ else if(dir.startsWith(currentDir)){ emit itemUpdated(dir); } } +void Browser::futureFinished(QString name, QByteArray icon){ + //Note: this will be called once for every item that loads + qDebug() << "Future Finished" << name; + //for(int i=0; iisFinished()){ + //FileItem FI = fwatchers[i]->result(); + //qDebug() << "Found finished:" << FI.name << i; + //disconnect(fwatchers[i]); + //fwatchers.takeAt(i)->deleteLater(); + //fwatchers.removeAt(i); + QIcon ico; + LFileInfo info(name); + if(!icon.isEmpty()){ + QPixmap pix; + if(pix.loadFromData(icon) ){ ico.addPixmap(pix); } + }else if(info.isDir()){ + ico = LXDG::findIcon("folder","inode/directory"); + } + if(ico.isNull()){ ico = LXDG::findIcon( info.mimetype(), "unknown" ); } + this->emit itemDataAvailable( ico, info ); + qDebug() << "- done"; + //i--; + //return; + //} + //} +} + // PUBLIC SLOTS -QString Browser::loadDirectory(QString dir){ +void Browser::loadDirectory(QString dir){ + qDebug() << "Load Directory" << dir; if(dir.isEmpty()){ dir = currentDir; } //reload current directory if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded //clean up the watcher first QStringList watched; watched << watcher->files() << watcher->directories(); if(!watched.isEmpty()){ watcher->removePaths(watched); } emit clearItems(); //let the main widget know to clear all current items - //QApplication::processEvents(); // read the given directory QDir directory(dir); if(directory.exists()){ - QFileInfoList files; - if(showHidden){ files = directory.entryInfoList( QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotOrDotDot, QDir::NoSort); } - else{ files = directory.entryInfoList( QDir::Dirs | QDir::Files | QDir::NoDotOrDotDot, QDir::NoSort); } + QStringList files; + if(showHidden){ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::NoSort); } + else{ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); } for(int i=0; iaddPath(files[i].absoluteFilePath()); - QtConcurrent::run(this, &Browser::loadDirectory, files[i]); + watcher->addPath(directory.absoluteFilePath(files[i])); + //qDebug() << "Future Starting:" << files[i]; + QString path = directory.absoluteFilePath(files[i]); + QtConcurrent::run(this, &Browser::loadItem, path ); } watcher->addPath(directory.absolutePath()); } diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.h b/src-qt5/desktop-utils/lumina-fm/Browser.h index ccc10c02..870e9fe1 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.h +++ b/src-qt5/desktop-utils/lumina-fm/Browser.h @@ -9,6 +9,22 @@ #ifndef _LUMINA_FM_BROWSE_BACKEND_H #define _LUMINA_FM_BROWSE_BACKEND_H +#include +#include +#include +#include +#include + +#include +class FileItem{ +public: + QString name; + QByteArray icon; + + FileItem(){} + ~FileItem(){}; +}; + class Browser : public QObject{ Q_OBJECT public: @@ -19,19 +35,25 @@ public: void showHiddenFiles(bool); bool showingHiddenFiles(); + //FileItem loadItem(QString info); //this is the main loader class - multiple instances each run in a separate thread + private: QString currentDir; QFileSystemWatcher *watcher; + QList< QFutureWatcher* > fwatchers; bool showHidden; + QStringList imageFormats; - void loadItem(QFileInfo info); //this is the main loader class - multiple instances each run in a separate thread + void loadItem(QString info); //this is the main loader class - multiple instances each run in a separate thread private slots: void fileChanged(QString); //tied into the watcher - for file change notifications void dirChanged(QString); // tied into the watcher - for new/removed files in the current dir + void futureFinished(QString, QByteArray); + public slots: - QString loadDirectory(QString dir = ""); + void loadDirectory(QString dir = ""); signals: //Main Signals @@ -42,6 +64,8 @@ signals: //Start/Stop signals for loading of data void itemsLoading(int); //number of items which are getting loaded + //Internal signal for the alternate threads + void threadDone(QString, QByteArray); }; #endif diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp index 12fd36fe..e6017e77 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp @@ -5,17 +5,21 @@ // See the LICENSE file for full details //=========================================== #include "BrowserWidget.h" + +#include +#include + BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){ //Setup the Widget/UI this->setLayout( new QVBoxLayout(this) ); - + this->setWhatsThis(objID); //Setup the backend browser object BROWSER = new Browser(this); connect(BROWSER, SIGNAL(clearItems()), this, SLOT(clearItems()) ); connect(BROWSER, SIGNAL(itemUpdated(QString)), this, SLOT(itemUpdated(QString)) ); - connect(BROWSER, SIGNAL(itemUpdated(QString)), this, SLOT(itemUpdated(QString)) ); - connect(BROWSER, SIGNAL(itemUpdated(QString)), this, SLOT(itemUpdated(QString)) ); - + connect(BROWSER, SIGNAL(itemDataAvailable(QIcon, LFileInfo)), this, SLOT(itemDataAvailable(QIcon, LFileInfo)) ); + connect(BROWSER, SIGNAL(itemsLoading(int)), this, SLOT(itemsLoading(int)) ); + connect(this, SIGNAL(dirChange(QString)), BROWSER, SLOT(loadDirectory(QString)) ); listWidget = 0; treeWidget = 0; } @@ -26,7 +30,33 @@ BrowserWidget::~BrowserWidget(){ void BrowserWidget::changeDirectory(QString dir){ if(BROWSER->currentDirectory()==dir){ return; } //already on this directory - BROWSER->loadDirectory(dir); + emit dirChange(dir); +} + +void BrowserWidget::showDetails(bool show){ + //Clean up widgets first + if(show && listWidget!=0){ + //Clean up list widget + listWidget->deleteLater(); + listWidget = 0; + }else if(!show && treeWidget!=0){ + treeWidget->deleteLater(); + treeWidget = 0; + } + //Now create any new widgets + if(show && treeWidget == 0){ + treeWidget = new DDTreeWidget(this); + this->layout()->addWidget(treeWidget); + if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } + }else if(!show && listWidget==0){ + listWidget = new DDListWidget(this); + this->layout()->addWidget(listWidget); + if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } + } +} + +bool BrowserWidget::hasDetails(){ + return (treeWidget!=0); } // ================= @@ -43,11 +73,12 @@ void BrowserWidget::itemUpdated(QString item){ qDebug() << "item updated" << item; QList found = treeWidget->findItems(item.section("/",-1), Qt::MatchExactly, 0); //look for exact name match if(found.isEmpty()){ return; } //no match - QTreeWidgetItem *it = found[0]; //onlyp update the first match (should only ever be one - duplicate file names are disallowed) + QTreeWidgetItem *it = found[0]; //only update the first match (should only ever be one - duplicate file names are disallowed) //it->setText( } void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ + qDebug() << "Item Data Available:" << info.fileName(); int num = 0; if(listWidget!=0){ listWidget->addItem( new QListWidgetItem(ico, info.fileName(), listWidget) ); @@ -67,4 +98,3 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ void BrowserWidget::itemsLoading(int total){ numItems = total; //save this for later } - diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h index a0dc535a..e438c4dc 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h @@ -8,14 +8,16 @@ #ifndef _LUMINA_FM_BROWSE_FRONTEND_H #define _LUMINA_FM_BROWSE_FRONTEND_H +#include +#include + #include "Browser.h" #include "widgets/DDListWidgets.h" class BrowserWidget : public QWidget{ Q_OBJECT private: - Browser *DIR: - QString ID; + Browser *BROWSER; int numItems; //used for checking if all the items have loaded yet bool details; //show details or not @@ -27,7 +29,7 @@ public: BrowserWidget(QString objID, QWidget *parent = 0); ~BrowserWidget(); - QString id(){ return ID; } + QString id(){ return this->whatsThis(); } void changeDirectory(QString dir); @@ -37,7 +39,7 @@ public: public slots: private slots: - //Brower connections + //Browser connections void clearItems(); void itemUpdated(QString); void itemDataAvailable(QIcon, LFileInfo); @@ -45,7 +47,7 @@ private slots: signals: //void activated(QString); //current dir path - void dirChanged(QString); //current dir path + void dirChange(QString); //current dir path }; @@ -56,7 +58,7 @@ signals: * On this class, we overwrite the function operator<. */ -class CQTreeWidgetItem : public QTreeWidgetItem { +/*class CQTreeWidgetItem : public QTreeWidgetItem { public: CQTreeWidgetItem(int type = Type) : QTreeWidgetItem(type) {} CQTreeWidgetItem(const QStringList & strings, int type = Type) : QTreeWidgetItem(strings, type) {} @@ -93,5 +95,5 @@ public: // In other cases, we trust base class implementation return QTreeWidgetItem::operator<(tmp); } -}; +};*/ #endif diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro index 91e2952c..487a6421 100644 --- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro +++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro @@ -17,7 +17,9 @@ SOURCES += main.cpp \ widgets/SlideshowWidget.cpp \ widgets/DirWidget.cpp \ gitCompat.cpp \ - gitWizard.cpp + gitWizard.cpp \ + Browser.cpp \ + BrowserWidget.cpp HEADERS += MainUI.h \ FODialog.h \ @@ -29,7 +31,9 @@ HEADERS += MainUI.h \ widgets/SlideshowWidget.h \ widgets/DirWidget.h \ gitCompat.h \ - gitWizard.h + gitWizard.h \ + Browser.h \ + BrowserWidget.h FORMS += MainUI.ui \ FODialog.ui \ diff --git a/src-qt5/desktop-utils/lumina-fm/main.cpp b/src-qt5/desktop-utils/lumina-fm/main.cpp index b05c4016..eaaf182c 100644 --- a/src-qt5/desktop-utils/lumina-fm/main.cpp +++ b/src-qt5/desktop-utils/lumina-fm/main.cpp @@ -9,6 +9,8 @@ #include #include +#include "BrowserWidget.h" + int main(int argc, char ** argv) { LTHEME::LoadCustomEnvSettings(); @@ -28,6 +30,16 @@ int main(int argc, char ** argv) w.OpenDirs(in); w.show(); + // TESTING CODE FOR NEW BACKEND + /*QMainWindow W; + BrowserWidget B("",&W); + W.setCentralWidget( &B); + B.showDetails(false); + B.changeDirectory(in.first()); + qDebug() << "Show Window"; + W.show(); + */ + int retCode = a.exec(); return retCode; } -- cgit From 4f90da22cb075252d9cbb0e797a656ed8cd065bd Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Tue, 27 Sep 2016 16:34:15 -0400 Subject: More work on the new backend: still disabled for now. --- src-qt5/desktop-utils/lumina-fm/Browser.cpp | 6 +- src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp | 124 +++++++++++++++++++-- src-qt5/desktop-utils/lumina-fm/BrowserWidget.h | 17 ++- .../lumina-fm/widgets/DDListWidgets.h | 50 ++++++++- .../desktop-utils/lumina-fm/widgets/DirWidget.cpp | 2 +- .../desktop-utils/lumina-fm/widgets/DirWidget.h | 45 -------- 6 files changed, 181 insertions(+), 63 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-fm') diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp index 1312aca0..8c9b27c3 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp +++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp @@ -78,7 +78,7 @@ void Browser::dirChanged(QString dir){ void Browser::futureFinished(QString name, QByteArray icon){ //Note: this will be called once for every item that loads - qDebug() << "Future Finished" << name; + //qDebug() << "Future Finished" << name; //for(int i=0; iisFinished()){ //FileItem FI = fwatchers[i]->result(); @@ -96,7 +96,7 @@ void Browser::futureFinished(QString name, QByteArray icon){ } if(ico.isNull()){ ico = LXDG::findIcon( info.mimetype(), "unknown" ); } this->emit itemDataAvailable( ico, info ); - qDebug() << "- done"; + //qDebug() << "- done"; //i--; //return; //} @@ -105,7 +105,7 @@ void Browser::futureFinished(QString name, QByteArray icon){ // PUBLIC SLOTS void Browser::loadDirectory(QString dir){ - qDebug() << "Load Directory" << dir; + //qDebug() << "Load Directory" << dir; if(dir.isEmpty()){ dir = currentDir; } //reload current directory if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded //clean up the watcher first diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp index e6017e77..bec99667 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp @@ -8,11 +8,15 @@ #include #include +#include + +#include BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){ //Setup the Widget/UI this->setLayout( new QVBoxLayout(this) ); - this->setWhatsThis(objID); + ID = objID; + //this->setWhatsThis(objID); //Setup the backend browser object BROWSER = new Browser(this); connect(BROWSER, SIGNAL(clearItems()), this, SLOT(clearItems()) ); @@ -22,6 +26,7 @@ BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){ connect(this, SIGNAL(dirChange(QString)), BROWSER, SLOT(loadDirectory(QString)) ); listWidget = 0; treeWidget = 0; + readDateFormat(); } BrowserWidget::~BrowserWidget(){ @@ -47,6 +52,7 @@ void BrowserWidget::showDetails(bool show){ if(show && treeWidget == 0){ treeWidget = new DDTreeWidget(this); this->layout()->addWidget(treeWidget); + retranslate(); if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } }else if(!show && listWidget==0){ listWidget = new DDListWidget(this); @@ -59,6 +65,74 @@ bool BrowserWidget::hasDetails(){ return (treeWidget!=0); } +void BrowserWidget::setThumbnailSize(int px){ + bool larger = true; + if(listWidget!=0){ + larger = listWidget->iconSize().height() < px; + listWidget->setIconSize(QSize(px,px)); + }else if(treeWidget!=0){ + larger = treeWidget->iconSize().height() < px; + treeWidget->setIconSize(QSize(px,px)); + } + if(BROWSER->currentDirectory().isEmpty() || !larger ){ return; } //don't need to reload icons unless the new size is larger + emit dirChange(""); +} + +QStringList BrowserWidget::getDateFormat() { + return date_format; +} + +// This function is only called if user changes sessionsettings. By doing so, operations like sorting by date +// are faster because the date format is already stored in DirWidget::date_format static variable +void BrowserWidget::readDateFormat() { + if(!date_format.isEmpty()) + date_format.clear(); + QSettings settings("lumina-desktop","sessionsettings"); + // If value doesn't exist or is not setted, empty string is returned + date_format << settings.value("DateFormat").toString(); + date_format << settings.value("TimeFormat").toString(); +} + +// ================= +// PUBLIC SLOTS +// ================= +void BrowserWidget::retranslate(){ + if(listWidget!=0){ + + }else if(treeWidget!=0){ + QTreeWidgetItem *it = new QTreeWidgetItem(); + it->setText(0,tr("Name")); + it->setText(1,tr("Size")); + it->setText(2, tr("Type")); + it->setText(3, tr("Date Modified") ); + it->setText(4, tr("Date Created") ); + treeWidget->setHeaderItem(it); + //Now reset the sorting (alphabetically, dirs first) + treeWidget->sortItems(0, Qt::AscendingOrder); // sort by name + treeWidget->sortItems(1, Qt::AscendingOrder); //sort by type + } +} + +// ================= +// PRIVATE +// ================= +QString BrowserWidget::DTtoString(QDateTime dt){ + QStringList fmt = getDateFormat(); + if(fmt.isEmpty() || fmt.length()!=2 || (fmt[0].isEmpty() && fmt[1].isEmpty()) ){ + //Default formatting + return dt.toString(Qt::DefaultLocaleShortDate); + }else if(fmt[0].isEmpty()){ + //Time format only + return (dt.date().toString(Qt::DefaultLocaleShortDate)+" "+dt.time().toString(fmt[1])); + }else if(fmt[1].isEmpty()){ + //Date format only + return (dt.date().toString(fmt[0])+" "+dt.time().toString(Qt::DefaultLocaleShortDate)); + }else{ + //both date/time formats set + return dt.toString(fmt.join(" ")); + } +} + // ================= // PRIVATE SLOTS // ================= @@ -68,23 +142,53 @@ void BrowserWidget::clearItems(){ this->setEnabled(false); } -void BrowserWidget::itemUpdated(QString item){ - if(treeWidget==0){ return; } //only used for the tree widget/details - qDebug() << "item updated" << item; - QList found = treeWidget->findItems(item.section("/",-1), Qt::MatchExactly, 0); //look for exact name match - if(found.isEmpty()){ return; } //no match - QTreeWidgetItem *it = found[0]; //only update the first match (should only ever be one - duplicate file names are disallowed) - //it->setText( +void BrowserWidget::itemRemoved(QString item){ + //qDebug() << "item removed" << item; + if(treeWidget!=0){ + QList found = treeWidget->findItems(item.section("/",-1), Qt::MatchExactly, 0); //look for exact name match + if(found.isEmpty()){ return; } //no match + delete found[0]; + }else if(listWidget!=0){ + QList found = listWidget->findItems(item.section("/",-1), Qt::MatchExactly); //look for exact name match + if(found.isEmpty()){ return; } + delete found[0]; + } } void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ qDebug() << "Item Data Available:" << info.fileName(); int num = 0; if(listWidget!=0){ - listWidget->addItem( new QListWidgetItem(ico, info.fileName(), listWidget) ); + //LIST WIDGET - name and icon only + if(!listWidget->findItems(info.fileName(), Qt::MatchExactly).isEmpty()){ + //Update existing item + QListWidgetItem *it = listWidget->findItems(info.fileName(), Qt::MatchExactly).first(); + it->setText(info.fileName()); + it->setWhatsThis(info.absoluteFilePath()); + it->setIcon(ico); + }else{ + //New item + listWidget->addItem( new QListWidgetItem(ico, info.fileName(), listWidget) ); + } num = listWidget->count(); }else if(treeWidget!=0){ - //TODO + QTreeWidgetItem *it = 0; + if( ! treeWidget->findItems(info.fileName(), Qt::MatchExactly, 0).isEmpty() ){ it = treeWidget->findItems(info.fileName(), Qt::MatchExactly, 0).first(); } + else{ + it = new CQTreeWidgetItem(treeWidget); + it->setText(0, info.fileName() ); //name (0) + treeWidget->addTopLevelItem(it); + } + //Now set/update all the data + it->setText(1, LUtils::BytesToDisplaySize(info.size()) ); //size (1) + it->setText(2, info.mimetype() ); //type (2) + it->setText(3, DTtoString(info.lastModified() )); //modification date (3) + it->setText(4, DTtoString(info.created()) ); //creation date (4) + //Now all the hidden data + it->setWhatsThis(0, info.absoluteFilePath()); + it->setWhatsThis(3, info.lastModified().toString("yyyyMMddhhmmsszzz") ); //sorts by this actually + it->setWhatsThis(4, info.created().toString("yyyyMMddhhmmsszzz") ); //sorts by this actually + num = treeWidget->topLevelItemCount(); } if(num < numItems){ //Still loading items diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h index e438c4dc..84b68b2c 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h @@ -19,29 +19,40 @@ class BrowserWidget : public QWidget{ private: Browser *BROWSER; int numItems; //used for checking if all the items have loaded yet - bool details; //show details or not + QString ID; + QStringList date_format; //The drag and drop brower widgets DDListWidget *listWidget; DDTreeWidget *treeWidget; + QString DTtoString(QDateTime dt); //QDateTime to string simplification routine + public: BrowserWidget(QString objID, QWidget *parent = 0); ~BrowserWidget(); - QString id(){ return this->whatsThis(); } + QString id(){ return ID; } void changeDirectory(QString dir); + QString currentDirectory(){ return BROWSER->currentDirectory(); } void showDetails(bool show); bool hasDetails(); + void setThumbnailSize(int px); + + //Date format for show items + QStringList getDateFormat(); + void readDateFormat(); + public slots: + void retranslate(); private slots: //Browser connections void clearItems(); - void itemUpdated(QString); + void itemRemoved(QString); void itemDataAvailable(QIcon, LFileInfo); void itemsLoading(int total); diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h index e3de9b0e..e7dfb4d1 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h @@ -24,6 +24,8 @@ #include #include +#include + //============== // LIST WIDGET //============== @@ -237,4 +239,50 @@ protected: else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget }*/ }; -#endif \ No newline at end of file + +/* + * Virtual class for managing the sort of folders/files items. The problem with base class is that it only manages texts fields and + * we have dates and sizes. + * + * On this class, we overwrite the function operator<. + */ + +class CQTreeWidgetItem : public QTreeWidgetItem { +public: + CQTreeWidgetItem(int type = Type) : QTreeWidgetItem(type) {} + CQTreeWidgetItem(const QStringList & strings, int type = Type) : QTreeWidgetItem(strings, type) {} + CQTreeWidgetItem(QTreeWidget * parent, int type = Type) : QTreeWidgetItem(parent, type) {} + CQTreeWidgetItem(QTreeWidget * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} + CQTreeWidgetItem(QTreeWidget * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} + CQTreeWidgetItem(QTreeWidgetItem * parent, int type = Type) : QTreeWidgetItem(parent, type) {} + CQTreeWidgetItem(QTreeWidgetItem * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} + CQTreeWidgetItem(QTreeWidgetItem * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} + virtual ~CQTreeWidgetItem() {} + inline virtual bool operator<(const QTreeWidgetItem &tmp) const { + int column = this->treeWidget()->sortColumn(); + // We are in date text + if(column == 3 || column == 4) + return this->whatsThis(column) < tmp.whatsThis(column); + // We are in size text + else if(column == 1) { + QString text = this->text(column); + QString text_tmp = tmp.text(column); + double filesize, filesize_tmp; + // On folders, text is empty so we check for that + // In case we are in folders, we put -1 for differentiate of regular files with 0 bytes. + // Doing so, all folders we'll be together instead of mixing with files with 0 bytes. + if(text.isEmpty()) + filesize = -1; + else + filesize = LUtils::DisplaySizeToBytes(text); + if(text_tmp.isEmpty()) + filesize_tmp = -1; + else + filesize_tmp = LUtils::DisplaySizeToBytes(text_tmp); + return filesize < filesize_tmp; + } + // In other cases, we trust base class implementation + return QTreeWidgetItem::operator<(tmp); + } +}; +#endif diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.cpp index d5f15a50..d729d608 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.cpp @@ -181,7 +181,7 @@ QStringList DirWidget::getDateFormat() { void DirWidget::setDateFormat() { if(!date_format.isEmpty()) date_format.clear(); - QSettings settings("LuminaDE","sessionsettings"); + QSettings settings("lumina-desktop","sessionsettings"); // If value doesn't exist or is not setted, empty string is returned date_format << settings.value("DateFormat").toString(); date_format << settings.value("TimeFormat").toString(); diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.h b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.h index afbb98cc..fecd6180 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget.h @@ -181,49 +181,4 @@ protected: }; -/* - * Virtual class for managing the sort of folders/files items. The problem with base class is that it only manages texts fields and - * we have dates and sizes. - * - * On this class, we overwrite the function operator<. - */ - -class CQTreeWidgetItem : public QTreeWidgetItem { -public: - CQTreeWidgetItem(int type = Type) : QTreeWidgetItem(type) {} - CQTreeWidgetItem(const QStringList & strings, int type = Type) : QTreeWidgetItem(strings, type) {} - CQTreeWidgetItem(QTreeWidget * parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CQTreeWidgetItem(QTreeWidget * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} - CQTreeWidgetItem(QTreeWidget * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} - virtual ~CQTreeWidgetItem() {} - inline virtual bool operator<(const QTreeWidgetItem &tmp) const { - int column = this->treeWidget()->sortColumn(); - // We are in date text - if(column == DirWidget::DATEMOD || column == DirWidget::DATECREATE) - return this->whatsThis(column) < tmp.whatsThis(column); - // We are in size text - else if(column == DirWidget::SIZE) { - QString text = this->text(column); - QString text_tmp = tmp.text(column); - double filesize, filesize_tmp; - // On folders, text is empty so we check for that - // In case we are in folders, we put -1 for differentiate of regular files with 0 bytes. - // Doing so, all folders we'll be together instead of mixing with files with 0 bytes. - if(text.isEmpty()) - filesize = -1; - else - filesize = LUtils::DisplaySizeToBytes(text); - if(text_tmp.isEmpty()) - filesize_tmp = -1; - else - filesize_tmp = LUtils::DisplaySizeToBytes(text_tmp); - return filesize < filesize_tmp; - } - // In other cases, we trust base class implementation - return QTreeWidgetItem::operator<(tmp); - } -}; #endif -- cgit From 04b5af3c9996f24764fddb4819f38e178c5dff4a Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 30 Sep 2016 14:40:40 -0400 Subject: Commit a large update to lumina-fm: The entire backend has been rewritten around multi-threading, and is much faster and more responsive now. The entire browsing widget has been redesigned for a better workflow and cleaner UI. The tabs/columns "group modes" have been removed. Instead, tabs are always used, but each browser supports a single/dual columns *within* each tab (via a couple simple buttons on the toolbar). Each column within a tab will share the same interface buttons (toolbar actions, ZFS snapshot slider,etc) - and they will reflect the settings on the "Active" column (with appropriate visual changes to indicate which one is active). The icon size options have also been removed from the menu bar and are now a couple small "zoom" buttons on the browsing widgets instead. KNOWN REGRESSION: Keyboard shortcuts have not been tested and re-added as necessary yet. --- src-qt5/desktop-utils/lumina-fm/Browser.cpp | 43 +++-- src-qt5/desktop-utils/lumina-fm/Browser.h | 11 +- src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp | 195 +++++++++++++++++++-- src-qt5/desktop-utils/lumina-fm/BrowserWidget.h | 82 ++++----- src-qt5/desktop-utils/lumina-fm/DirData.h | 35 ++-- src-qt5/desktop-utils/lumina-fm/MainUI.cpp | 176 +++++++++---------- src-qt5/desktop-utils/lumina-fm/MainUI.h | 21 +-- src-qt5/desktop-utils/lumina-fm/MainUI.ui | 29 +-- src-qt5/desktop-utils/lumina-fm/lumina-fm.pro | 6 +- .../lumina-fm/widgets/DDListWidgets.h | 41 ++++- 10 files changed, 397 insertions(+), 242 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-fm') diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp index 8c9b27c3..7455e5ea 100644 --- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp +++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp @@ -67,25 +67,17 @@ void Browser::loadItem(QString info){ // PRIVATE SLOTS void Browser::fileChanged(QString file){ - if(file.startsWith(currentDir+"/")){ emit itemUpdated(file); } + if(file.startsWith(currentDir+"/")){ QtConcurrent::run(this, &Browser::loadItem, file ); } else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } } void Browser::dirChanged(QString dir){ if(dir==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } - else if(dir.startsWith(currentDir)){ emit itemUpdated(dir); } + else if(dir.startsWith(currentDir)){ QtConcurrent::run(this, &Browser::loadItem, dir ); } } void Browser::futureFinished(QString name, QByteArray icon){ //Note: this will be called once for every item that loads - //qDebug() << "Future Finished" << name; - //for(int i=0; iisFinished()){ - //FileItem FI = fwatchers[i]->result(); - //qDebug() << "Found finished:" << FI.name << i; - //disconnect(fwatchers[i]); - //fwatchers.takeAt(i)->deleteLater(); - //fwatchers.removeAt(i); QIcon ico; LFileInfo info(name); if(!icon.isEmpty()){ @@ -94,13 +86,11 @@ void Browser::futureFinished(QString name, QByteArray icon){ }else if(info.isDir()){ ico = LXDG::findIcon("folder","inode/directory"); } - if(ico.isNull()){ ico = LXDG::findIcon( info.mimetype(), "unknown" ); } + if(ico.isNull()){ + //qDebug() << "MimeType:" << info.fileName() << info.mimetype(); + ico = LXDG::findIcon( info.iconfile(), "unknown" ); + } this->emit itemDataAvailable( ico, info ); - //qDebug() << "- done"; - //i--; - //return; - //} - //} } // PUBLIC SLOTS @@ -108,22 +98,41 @@ void Browser::loadDirectory(QString dir){ //qDebug() << "Load Directory" << dir; if(dir.isEmpty()){ dir = currentDir; } //reload current directory if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded + if(currentDir != dir){ //let the main widget know to clear all current items (completely different dir) + oldFiles.clear(); + emit clearItems(); + } + currentDir = dir; //save this for later //clean up the watcher first QStringList watched; watched << watcher->files() << watcher->directories(); if(!watched.isEmpty()){ watcher->removePaths(watched); } - emit clearItems(); //let the main widget know to clear all current items + QStringList old = oldFiles; //copy this over for the moment (both lists will change in a moment) + oldFiles.clear(); //get ready for re-creating this list // read the given directory QDir directory(dir); if(directory.exists()){ QStringList files; if(showHidden){ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::Hidden | QDir::NoDotAndDotDot, QDir::NoSort); } else{ files = directory.entryList( QDir::Dirs | QDir::Files | QDir::NoDotAndDotDot, QDir::NoSort); } + emit itemsLoading(files.length()); + QCoreApplication::processEvents(); for(int i=0; iaddPath(directory.absoluteFilePath(files[i])); //qDebug() << "Future Starting:" << files[i]; QString path = directory.absoluteFilePath(files[i]); + if(old.contains(path)){ old.removeAll(path); } + oldFiles << path; //add to list for next time QtConcurrent::run(this, &Browser::loadItem, path ); + QCoreApplication::sendPostedEvents(); } watcher->addPath(directory.absolutePath()); + if(!old.isEmpty()){ + old.removeAll(directory.absolutePath()); + for(int i=0; i #include #include -#include +//#include #include -class FileItem{ +/*class FileItem{ public: QString name; QByteArray icon; FileItem(){} ~FileItem(){}; -}; +};*/ class Browser : public QObject{ Q_OBJECT @@ -40,9 +40,8 @@ public: private: QString currentDir; QFileSystemWatcher *watcher; - QList< QFutureWatcher* > fwatchers; bool showHidden; - QStringList imageFormats; + QStringList imageFormats, oldFiles; void loadItem(QString info); //this is the main loader class - multiple instances each run in a separate thread @@ -57,7 +56,7 @@ public slots: signals: //Main Signals - void itemUpdated(QString item); //emitted if a file changes after the initial scan + void itemRemoved(QString item); //emitted if a file was removed from the underlying void clearItems(); //emitted when dirs change for example void itemDataAvailable(QIcon, LFileInfo); diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp index bec99667..e007b974 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp @@ -11,22 +11,25 @@ #include #include +#include BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){ //Setup the Widget/UI this->setLayout( new QVBoxLayout(this) ); ID = objID; - //this->setWhatsThis(objID); //Setup the backend browser object BROWSER = new Browser(this); connect(BROWSER, SIGNAL(clearItems()), this, SLOT(clearItems()) ); - connect(BROWSER, SIGNAL(itemUpdated(QString)), this, SLOT(itemUpdated(QString)) ); + connect(BROWSER, SIGNAL(itemRemoved(QString)), this, SLOT(itemRemoved(QString)) ); connect(BROWSER, SIGNAL(itemDataAvailable(QIcon, LFileInfo)), this, SLOT(itemDataAvailable(QIcon, LFileInfo)) ); connect(BROWSER, SIGNAL(itemsLoading(int)), this, SLOT(itemsLoading(int)) ); connect(this, SIGNAL(dirChange(QString)), BROWSER, SLOT(loadDirectory(QString)) ); listWidget = 0; treeWidget = 0; readDateFormat(); + freshload = true; //nothing loaded yet + numItems = 0; + } BrowserWidget::~BrowserWidget(){ @@ -34,37 +37,75 @@ BrowserWidget::~BrowserWidget(){ } void BrowserWidget::changeDirectory(QString dir){ + qDebug() << "Change Directory:" << dir << historyList; if(BROWSER->currentDirectory()==dir){ return; } //already on this directory + + if( !dir.contains("/.zfs/snapshot/") ){ + if(historyList.isEmpty() || !dir.isEmpty()){ historyList << dir; } + }else{ + //Need to remove the zfs snapshot first and ensure that it is not the same dir (just a diff snapshot) + QString cleaned = dir.replace( QRegExp("/\\.zfs/snapshot/(.)+/"), "/" ); + if( (historyList.isEmpty() || historyList.last()!=cleaned) && !cleaned.isEmpty() ){ historyList << cleaned; } + } + qDebug() << "History:" << historyList; emit dirChange(dir); } void BrowserWidget::showDetails(bool show){ //Clean up widgets first + QSize iconsize; if(show && listWidget!=0){ //Clean up list widget + iconsize = listWidget->iconSize(); + this->layout()->removeWidget(listWidget); listWidget->deleteLater(); listWidget = 0; }else if(!show && treeWidget!=0){ + iconsize = treeWidget->iconSize(); + this->layout()->removeWidget(treeWidget); treeWidget->deleteLater(); treeWidget = 0; } + qDebug() << "Create Widget: details:" << show; //Now create any new widgets if(show && treeWidget == 0){ treeWidget = new DDTreeWidget(this); + treeWidget->setContextMenuPolicy(Qt::CustomContextMenu); + if(!iconsize.isNull()){ treeWidget->setIconSize(iconsize); } this->layout()->addWidget(treeWidget); + connect(treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SIGNAL(itemsActivated()) ); + connect(treeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(contextMenuRequested()) ); + connect(treeWidget, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(DataDropped(QString, QStringList)) ); + connect(treeWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) ); retranslate(); + treeWidget->sortItems(0, Qt::AscendingOrder); if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } }else if(!show && listWidget==0){ listWidget = new DDListWidget(this); + listWidget->setContextMenuPolicy(Qt::CustomContextMenu); + if(!iconsize.isNull()){ listWidget->setIconSize(iconsize); } this->layout()->addWidget(listWidget); + connect(listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this, SIGNAL(itemsActivated()) ); + connect(listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SIGNAL(contextMenuRequested()) ); + connect(listWidget, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(DataDropped(QString, QStringList)) ); + connect(listWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) ); if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); } } + qDebug() << " Done making widget"; } bool BrowserWidget::hasDetails(){ return (treeWidget!=0); } +void BrowserWidget::showHiddenFiles(bool show){ + BROWSER->showHiddenFiles(show); +} + +bool BrowserWidget::hasHiddenFiles(){ + return BROWSER->showingHiddenFiles(); +} + void BrowserWidget::setThumbnailSize(int px){ bool larger = true; if(listWidget!=0){ @@ -74,12 +115,31 @@ void BrowserWidget::setThumbnailSize(int px){ larger = treeWidget->iconSize().height() < px; treeWidget->setIconSize(QSize(px,px)); } + //qDebug() << "Changing Icon Size:" << px << larger; if(BROWSER->currentDirectory().isEmpty() || !larger ){ return; } //don't need to reload icons unless the new size is larger emit dirChange(""); } -QStringList BrowserWidget::getDateFormat() { - return date_format; +int BrowserWidget::thumbnailSize(){ + if(listWidget!=0){ return listWidget->iconSize().height(); } + else if(treeWidget!=0){ return treeWidget->iconSize().height(); } + return 0; +} + +void BrowserWidget::setHistory(QStringList paths){ + //NOTE: later items are used first + historyList = paths; +} + +QStringList BrowserWidget::history(){ + return historyList; +} + +void BrowserWidget::setShowActive(bool show){ + if(!show){ this->setStyleSheet("QAbstractScrollArea{ background-color: rgba(10,10,10,10); }"); } + else{ + this->setStyleSheet( "QAbstractScrollArea{ background-color: white; }"); + } } // This function is only called if user changes sessionsettings. By doing so, operations like sorting by date @@ -93,6 +153,51 @@ void BrowserWidget::readDateFormat() { date_format << settings.value("TimeFormat").toString(); } + +QStringList BrowserWidget::currentSelection(){ + QStringList out; + if(listWidget!=0){ + QList sel = listWidget->selectedItems(); + //qDebug() << "Selection number:" << sel.length(); + //if(sel.isEmpty() && listWidget->currentItem()!=0){ sel << listWidget->currentItem(); } + //qDebug() << "Selection number:" << sel.length(); + for(int i=0; iwhatsThis(); qDebug() << "Selection:" << sel[i]->text() << sel[i]->whatsThis(); } + }else if(treeWidget!=0){ + QList sel = treeWidget->selectedItems(); + //if(sel.isEmpty() && treeWidget->currentItem()!=0){ sel << treeWidget->currentItem(); } + for(int i=0; iwhatsThis(0); } + } + out.removeDuplicates(); //just in case - tree widgets sometimes "select" each column as an individual item + return out; +} + +QStringList BrowserWidget::currentItems(int type){ + //type: 0=all, -1=files, +1=dirs + QStringList paths; + if(listWidget!=0){ + for(int i=0; icount(); i++){ + if(i<0 && (listWidget->item(i)->data(Qt::UserRole).toString()=="file") ){ //FILES + paths << listWidget->item(i)->whatsThis(); + }else if(i>0 && (listWidget->item(i)->data(Qt::UserRole).toString()=="dir")){ //DIRS + paths << listWidget->item(i)->whatsThis(); + }else if(i==0){ //ALL + paths << listWidget->item(i)->whatsThis(); + } + } + }else if(treeWidget!=0){ + for(int i=0; itopLevelItemCount(); i++){ + if(i<0 && !treeWidget->topLevelItem(i)->text(1).isEmpty()){ //FILES + paths << treeWidget->topLevelItem(i)->whatsThis(0); + }else if(i>0 && treeWidget->topLevelItem(i)->text(1).isEmpty()){ //DIRS + paths << treeWidget->topLevelItem(i)->whatsThis(0); + }else if(i==0){ //ALL + paths << treeWidget->topLevelItem(i)->whatsThis(0); + } + } + } + return paths; +} + // ================= // PUBLIC SLOTS // ================= @@ -117,7 +222,7 @@ void BrowserWidget::retranslate(){ // PRIVATE // ================= QString BrowserWidget::DTtoString(QDateTime dt){ - QStringList fmt = getDateFormat(); + QStringList fmt = date_format; if(fmt.isEmpty() || fmt.length()!=2 || (fmt[0].isEmpty() && fmt[1].isEmpty()) ){ //Default formatting return dt.toString(Qt::DefaultLocaleShortDate); @@ -137,9 +242,10 @@ QString BrowserWidget::DTtoString(QDateTime dt){ // PRIVATE SLOTS // ================= void BrowserWidget::clearItems(){ + //qDebug() << "Clear Items"; if(listWidget!=0){ listWidget->clear(); } else if(treeWidget!=0){ treeWidget->clear(); } - this->setEnabled(false); + freshload = true; } void BrowserWidget::itemRemoved(QString item){ @@ -156,7 +262,7 @@ void BrowserWidget::itemRemoved(QString item){ } void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ - qDebug() << "Item Data Available:" << info.fileName(); + //qDebug() << "Item Data Available:" << info.fileName(); int num = 0; if(listWidget!=0){ //LIST WIDGET - name and icon only @@ -168,7 +274,10 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ it->setIcon(ico); }else{ //New item - listWidget->addItem( new QListWidgetItem(ico, info.fileName(), listWidget) ); + QListWidgetItem *it = new CQListWidgetItem(ico, info.fileName(), listWidget); + it->setWhatsThis(info.absoluteFilePath()); + it->setData(Qt::UserRole, (info.isDir() ? "dir" : "file")); //used for sorting + listWidget->addItem(it); } num = listWidget->count(); }else if(treeWidget!=0){ @@ -180,7 +289,8 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ treeWidget->addTopLevelItem(it); } //Now set/update all the data - it->setText(1, LUtils::BytesToDisplaySize(info.size()) ); //size (1) + it->setIcon(0, ico); + it->setText(1, info.isDir() ? "" : LUtils::BytesToDisplaySize(info.size()) ); //size (1) it->setText(2, info.mimetype() ); //type (2) it->setText(3, DTtoString(info.lastModified() )); //modification date (3) it->setText(4, DTtoString(info.created()) ); //creation date (4) @@ -194,11 +304,74 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo info){ //Still loading items //this->setEnabled(false); }else{ + if(freshload && treeWidget!=0){ + //qDebug() << "Resize Tree Widget Contents"; + for(int i=0; icolumnCount(); i++){ treeWidget->resizeColumnToContents(i); } + } + freshload = false; //any further changes are updates - not a fresh load of a dir //Done loading items - this->setEnabled(true); - } + //this->setEnabled(true); + //Assemble any status message + QString stats = QString(tr("Capacity: %1")).arg(LOS::FileSystemCapacity(BROWSER->currentDirectory())); + int nF, nD; + double bytes = 0; + nF = nD = 0; + if(listWidget!=0){ + bytes = -1; //not supported for this widget + for(int i=0; icount(); i++){ + if(listWidget->item(i)->data(Qt::UserRole).toString()=="dir"){ nD++; } //directory + else{ nF++; } //file + } + }else if(treeWidget!=0){ + for(int i=0; itopLevelItemCount(); i++){ + if(treeWidget->topLevelItem(i)->text(1).isEmpty()){ + nD++; //directory + }else{ + nF++; //file + bytes+=LUtils::DisplaySizeToBytes(treeWidget->topLevelItem(i)->text(1)); + } + } + } + + if( (nF+nD) >0){ + stats.prepend("\t"); + if(nF>0){ + //Has Files + if(bytes>0){ + stats.prepend( QString(tr("Files: %1 (%2)")).arg(QString::number(nF), LUtils::BytesToDisplaySize(bytes)) ); + }else{ + stats.prepend( QString(tr("Files: %1")).arg(QString::number(nF)) ); + } + } + if(nD > 0){ + //Has Dirs + if(nF>0){ stats.prepend(" / "); }//has files output already + stats.prepend( QString(tr("Dirs: %1")).arg(QString::number(nD)) ); + } + } + emit updateDirectoryStatus( stats.simplified() ); + statustip = stats.simplified(); //save for later + }//end check for finished loading items } void BrowserWidget::itemsLoading(int total){ + //qDebug() << "Got number of items loading:" << total; numItems = total; //save this for later + if(total<1){ + emit updateDirectoryStatus( tr("No Directory Contents") ); + this->setEnabled(true); + } +} + +void BrowserWidget::selectionChanged(){ + emit hasFocus(ID); //let the parent know the widget is "active" with the user +} + +void BrowserWidget::resizeEvent(QResizeEvent *ev){ + QWidget::resizeEvent(ev); //do the normal processing first + //The list widget needs to be poked to rearrange the items to fit the new size + // tree widget does this fine at the moment. + if(listWidget!=0){ + listWidget->sortItems(Qt::AscendingOrder); + } } diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h index 84b68b2c..803a036d 100644 --- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h +++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h @@ -10,6 +10,7 @@ #include #include +#include #include "Browser.h" #include "widgets/DDListWidgets.h" @@ -18,9 +19,11 @@ class BrowserWidget : public QWidget{ Q_OBJECT private: Browser *BROWSER; + //QThread *bThread; //browserThread int numItems; //used for checking if all the items have loaded yet - QString ID; - QStringList date_format; + QString ID, statustip; + QStringList date_format, historyList; + bool freshload; //The drag and drop brower widgets DDListWidget *listWidget; @@ -40,12 +43,26 @@ public: void showDetails(bool show); bool hasDetails(); + void showHiddenFiles(bool show); + bool hasHiddenFiles(); + void setThumbnailSize(int px); + int thumbnailSize(); + + void setHistory(QStringList); + QStringList history(); + + void setShowActive(bool show); //used for accenting if the widget is "active" + + QString status(){ return statustip; } //Date format for show items - QStringList getDateFormat(); void readDateFormat(); + //Return all the items which are currently selected + QStringList currentSelection(); + QStringList currentItems(int type = 0); //type: 0=all, -1=files, +1=dirs + public slots: void retranslate(); @@ -55,56 +72,21 @@ private slots: void itemRemoved(QString); void itemDataAvailable(QIcon, LFileInfo); void itemsLoading(int total); + void selectionChanged(); + +protected: + void resizeEvent(QResizeEvent *ev); signals: - //void activated(QString); //current dir path + //External signals + void itemsActivated(); + void updateDirectoryStatus(QString); + void contextMenuRequested(); + void DataDropped(QString, QStringList); + void hasFocus(QString); //ID output + + //Internal signal void dirChange(QString); //current dir path }; - -/* - * Virtual class for managing the sort of folders/files items. The problem with base class is that it only manages texts fields and - * we have dates and sizes. - * - * On this class, we overwrite the function operator<. - */ - -/*class CQTreeWidgetItem : public QTreeWidgetItem { -public: - CQTreeWidgetItem(int type = Type) : QTreeWidgetItem(type) {} - CQTreeWidgetItem(const QStringList & strings, int type = Type) : QTreeWidgetItem(strings, type) {} - CQTreeWidgetItem(QTreeWidget * parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CQTreeWidgetItem(QTreeWidget * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} - CQTreeWidgetItem(QTreeWidget * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, int type = Type) : QTreeWidgetItem(parent, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, const QStringList & strings, int type = Type) : QTreeWidgetItem(parent, strings, type) {} - CQTreeWidgetItem(QTreeWidgetItem * parent, QTreeWidgetItem * preceding, int type = Type) : QTreeWidgetItem(parent, preceding, type) {} - virtual ~CQTreeWidgetItem() {} - inline virtual bool operator<(const QTreeWidgetItem &tmp) const { - int column = this->treeWidget()->sortColumn(); - // We are in date text - if(column == DirWidget::DATEMOD || column == DirWidget::DATECREATE) - return this->whatsThis(column) < tmp.whatsThis(column); - // We are in size text - else if(column == DirWidget::SIZE) { - QString text = this->text(column); - QString text_tmp = tmp.text(column); - double filesize, filesize_tmp; - // On folders, text is empty so we check for that - // In case we are in folders, we put -1 for differentiate of regular files with 0 bytes. - // Doing so, all folders we'll be together instead of mixing with files with 0 bytes. - if(text.isEmpty()) - filesize = -1; - else - filesize = LUtils::DisplaySizeToBytes(text); - if(text_tmp.isEmpty()) - filesize_tmp = -1; - else - filesize_tmp = LUtils::DisplaySizeToBytes(text_tmp); - return filesize < filesize_tmp; - } - // In other cases, we trust base class implementation - return QTreeWidgetItem::operator<(tmp); - } -};*/ #endif diff --git a/src-qt5/desktop-utils/lumina-fm/DirData.h b/src-qt5/desktop-utils/lumina-fm/DirData.h index c3ace5a4..546dd6c5 100644 --- a/src-qt5/desktop-utils/lumina-fm/DirData.h +++ b/src-qt5/desktop-utils/lumina-fm/DirData.h @@ -32,6 +32,7 @@ public: QString dirpath; //directory this structure was reading QString snapdir; //base snapshot directory (if one was requested/found) bool hashidden; + QStringList mntpoints; //Access Functions LDirInfoList(QString path = ""){ @@ -39,6 +40,11 @@ public: list.clear(); fileNames.clear(); hashidden = false; + //Generate the list of all mountpoints if possible + if(LUtils::isValidBinary("zfs")){ + mntpoints = LUtils::getCmdOutput("zfs list -H -o mountpoint").filter("/"); + mntpoints.removeDuplicates(); + } } ~LDirInfoList(){} @@ -72,23 +78,21 @@ public: } void findSnapDir(){ - //Search the filesystem + //Search the filesystem if(dirpath.contains(ZSNAPDIR)){ snapdir = dirpath.section(ZSNAPDIR,0,0)+ZSNAPDIR; //no need to go looking for it + }else if(mntpoints.isEmpty()){ + snapdir.clear(); //no zfs dirs available }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 - } + //Only check the mountpoint associated with this directory + QString mnt; + for(int i=0; imnt.length()){ mnt = mntpoints[i]; } + } + if(QFile::exists(mnt+ZSNAPDIR)){ snapdir = mnt+ZSNAPDIR; } + else{ snapdir.clear(); } //none found + } } }; @@ -119,6 +123,7 @@ public: public slots: void GetDirData(QString ID, QString dirpath){ + return; if(pauseData){ return; } if(DIR_DEBUG){ qDebug() << "GetDirData:" << ID << dirpath; } //The ID is used when returning the info in a moment @@ -146,7 +151,7 @@ public slots: //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)){ + if(!HASH.contains(dirpath)){ LDirInfoList info(dirpath); HASH.insert(dirpath,info); } diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp index 59b671b5..bac365e1 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp @@ -15,11 +15,11 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ //for Signal/slot we must register the Typedef of QFileInfoList - qRegisterMetaType("QFileInfoList"); + //qRegisterMetaType("QFileInfoList"); qRegisterMetaType< LFileInfoList >("LFileInfoList"); //just to silence/fix some Qt connect warnings in QtConcurrent - qRegisterMetaType< QVector >("QVector"); - qRegisterMetaType< QList >("QList"); + //qRegisterMetaType< QVector >("QVector"); + //qRegisterMetaType< QList >("QList"); ui->setupUi(this); @@ -27,9 +27,6 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ if(DEBUG){ qDebug() << "Initilization:"; } settings = new QSettings( QSettings::UserScope, "lumina-desktop", "lumina-fm", this); - //syncTimer = new QTimer(this); - //syncTimer->setInterval(200); //1/5 second (collect as many signals/slots as necessary - //syncTimer->setSingleShot(true); //Reset the UI to the previously used size (if possible) QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize(); if(!orig.isEmpty() && orig.isValid()){ @@ -56,34 +53,29 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize(); workThread->setObjectName("Lumina-fm filesystem worker"); worker = new DirData(); worker->zfsavailable = LUtils::isValidBinary("zfs"); - connect(worker, SIGNAL(DirDataAvailable(QString, QString, LFileInfoList)), this, SLOT(DirDataAvailable(QString, QString, LFileInfoList)) ); + //connect(worker, SIGNAL(DirDataAvailable(QString, QString, LFileInfoList)), this, SLOT(DirDataAvailable(QString, QString, LFileInfoList)) ); connect(worker, SIGNAL(SnapshotDataAvailable(QString, QString, QStringList)), this, SLOT(SnapshotDataAvailable(QString, QString, QStringList)) ); worker->moveToThread(workThread); - //if(DEBUG){ qDebug() << " - File System Model"; } - //fsmod = new QFileSystemModel(this); - //fsmod->setRootPath(QDir::homePath()); - //dirCompleter = new QCompleter(fsmod, this); - //dirCompleter->setModelSorting( QCompleter::CaseInsensitivelySortedModel ); if(DEBUG){ qDebug() << " - Context Menu"; } contextMenu = new QMenu(this); radio_view_details = new QRadioButton(tr("Detailed List"), this); radio_view_list = new QRadioButton(tr("Basic List"), this); - radio_view_tabs = new QRadioButton(tr("Prefer Tabs"), this); - radio_view_cols = new QRadioButton(tr("Prefer Columns"), this); + //radio_view_tabs = new QRadioButton(tr("Prefer Tabs"), this); + //radio_view_cols = new QRadioButton(tr("Prefer Columns"), this); ui->menuView_Mode->clear(); - ui->menuGroup_Mode->clear(); + //ui->menuGroup_Mode->clear(); detWA = new QWidgetAction(this); detWA->setDefaultWidget(radio_view_details); listWA = new QWidgetAction(this); listWA->setDefaultWidget(radio_view_list); - tabsWA = new QWidgetAction(this); - tabsWA->setDefaultWidget(radio_view_tabs); - colsWA = new QWidgetAction(this); - colsWA->setDefaultWidget(radio_view_cols); + //tabsWA = new QWidgetAction(this); + //tabsWA->setDefaultWidget(radio_view_tabs); + //colsWA = new QWidgetAction(this); + //colsWA->setDefaultWidget(radio_view_cols); ui->menuView_Mode->addAction(detWA); ui->menuView_Mode->addAction(listWA); - ui->menuGroup_Mode->addAction(tabsWA); - ui->menuGroup_Mode->addAction(colsWA); + //ui->menuGroup_Mode->addAction(tabsWA); + //ui->menuGroup_Mode->addAction(colsWA); //Setup the pages //ui->BrowserLayout->clear(); ui->page_player->setLayout(new QVBoxLayout()); @@ -113,8 +105,6 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize(); if(DEBUG){ qDebug() << " - Devices"; } RebuildDeviceMenu(); //Make sure we start on the browser page - if(DEBUG){ qDebug() << " - Load Browser Page"; } - //goToBrowserPage(); if(DEBUG){ qDebug() << " - Done with init"; } } @@ -149,7 +139,7 @@ void MainUI::OpenDirs(QStringList dirs){ DWLIST << DW; //Connect the signals/slots for it connect(DW, SIGNAL(OpenDirectories(QStringList)), this, SLOT(OpenDirs(QStringList)) ); - connect(DW, SIGNAL(LoadDirectory(QString, QString)), worker, SLOT(GetDirData(QString, QString)) ); + //connect(DW, SIGNAL(LoadDirectory(QString, QString)), worker, SLOT(GetDirData(QString, QString)) ); connect(DW, SIGNAL(findSnaps(QString, QString)), worker, SLOT(GetSnapshotData(QString, QString)) ); connect(DW, SIGNAL(PlayFiles(LFileInfoList)), this, SLOT(OpenPlayer(LFileInfoList)) ); connect(DW, SIGNAL(ViewFiles(LFileInfoList)), this, SLOT(OpenImages(LFileInfoList)) ); @@ -161,12 +151,13 @@ void MainUI::OpenDirs(QStringList dirs){ connect(DW, SIGNAL(RemoveFiles(QStringList)), this, SLOT(RemoveFiles(QStringList)) ); connect(DW, SIGNAL(PasteFiles(QString,QStringList)), this, SLOT(PasteFiles(QString, QStringList)) ); connect(DW, SIGNAL(CloseBrowser(QString)), this, SLOT(CloseBrowser(QString)) ); + connect(DW, SIGNAL(TabNameChanged(QString,QString)), this, SLOT(TabNameChanged(QString, QString)) ); //Now create the tab for this - if(radio_view_tabs->isChecked()){ + //if(radio_view_tabs->isChecked()){ int index = tabBar->addTab( LXDG::findIcon("folder-open",""), dirs[i].section("/",-1) ); tabBar->setTabWhatsThis( index, "DW-"+QString::number(id) ); tabBar->setCurrentIndex(index); - }else{ + /*}else{ //Just make sure the browser tab is visible bool found = false; for(int i=0; icount() && !found; i++){ @@ -178,17 +169,11 @@ void MainUI::OpenDirs(QStringList dirs){ tabBar->setTabWhatsThis( index, "browser" ); tabBar->setCurrentIndex(index); } - } + }*/ //Initialize the widget with the proper settings - DW->setShowDetails(radio_view_details->isChecked()); - DW->setShowSidebar(ui->actionShow_Action_Buttons->isChecked()); - QList details; details <setDetails(details); //Which details to show and in which order (L->R) - DW->setShowThumbnails(ui->actionShow_Thumbnails->isChecked()); + DW->setShowDetails(radio_view_details->isChecked()); DW->setThumbnailSize(settings->value("iconsize", 32).toInt()); - //DW->setDirCompleter(dirCompleter); - DW->setShowCloseButton(!radio_view_tabs->isChecked()); //Now load the directory DW->ChangeDir(dirs[i]); //kick off loading the directory info } @@ -225,9 +210,6 @@ void MainUI::setupIcons(){ // View menu ui->actionRefresh->setIcon( LXDG::findIcon("view-refresh","") ); ui->menuView_Mode->setIcon( LXDG::findIcon("view-choose","") ); - ui->menuGroup_Mode->setIcon( LXDG::findIcon("tab-duplicate","") ); - ui->actionLarger_Icons->setIcon( LXDG::findIcon("zoom-in","") ); - ui->actionSmaller_Icons->setIcon( LXDG::findIcon("zoom-out", "") ); // Bookmarks menu ui->actionManage_Bookmarks->setIcon( LXDG::findIcon("bookmarks-organize","") ); @@ -253,8 +235,8 @@ void MainUI::setupConnections(){ //Radio Buttons connect(radio_view_details, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool)) ); connect(radio_view_list, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool)) ); - connect(radio_view_tabs, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); - connect(radio_view_cols, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); + //connect(radio_view_tabs, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); + //connect(radio_view_cols, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); //Special Keyboard Shortcuts connect(nextTabLShort, SIGNAL(activated()), this, SLOT( prevTab() ) ); @@ -280,25 +262,28 @@ void MainUI::togglehiddenfiles() void MainUI::loadSettings(){ //Note: make sure this is run after all the UI elements are created and connected to slots // but before the first directory gets loaded - ui->actionView_Hidden_Files->setChecked( settings->value("showhidden", false).toBool() ); + QSettings SET("lumina-desktop","lumina-fm"); + ui->actionView_Hidden_Files->setChecked( SET.value("showhidden", false).toBool() ); on_actionView_Hidden_Files_triggered(); //make sure to update the models too - ui->actionShow_Action_Buttons->setChecked(settings->value("showactions", true).toBool() ); - on_actionShow_Action_Buttons_triggered(); //make sure to update the UI - ui->actionShow_Thumbnails->setChecked( settings->value("showthumbnails", true).toBool() ); + //ui->actionShow_Action_Buttons->setChecked(settings->value("showactions", true).toBool() ); + //on_actionShow_Action_Buttons_triggered(); //make sure to update the UI + //ui->actionShow_Thumbnails->setChecked( settings->value("showthumbnails", true).toBool() ); //View Type - bool showDetails = (settings->value("viewmode","details").toString()=="details"); + //qDebug() << "View Mode:" << SET.value("viewmode","details").toString(); + bool showDetails = (SET.value("viewmode","details").toString()=="details"); if(showDetails){ radio_view_details->setChecked(true); } else{ radio_view_list->setChecked(true); } //Grouping type - bool usetabs = (settings->value("groupmode","tabs").toString()=="tabs"); - if(usetabs){ radio_view_tabs->setChecked(true); } - else{ radio_view_cols->setChecked(true); } + //bool usetabs = (SET.value("groupmode","tabs").toString()=="tabs"); + //if(usetabs){ radio_view_tabs->setChecked(true); } + // else{ radio_view_cols->setChecked(true); } } void MainUI::RebuildBookmarksMenu(){ //Create the bookmarks menu - QStringList BM = settings->value("bookmarks", QStringList()).toStringList(); + QSettings SET("lumina-desktop","lumina-fm"); + QStringList BM = SET.value("bookmarks", QStringList()).toStringList(); ui->menuBookmarks->clear(); ui->menuBookmarks->addAction(ui->actionManage_Bookmarks); ui->menuBookmarks->addAction(ui->actionAdd_Bookmark); @@ -306,18 +291,19 @@ void MainUI::RebuildBookmarksMenu(){ bool changed = false; BM.sort(); //Sort alphabetically for(int i=0; isetWhatsThis(BM[i].section("::::",1,1)); ui->menuBookmarks->addAction(act); - }else{ + /*}else{ //Invalid directory - remove the bookmark BM.removeAt(i); i--; changed = true; - } + }*/ } - if(changed){ settings->setValue("bookmarks",BM); } + if(changed){ SET.setValue("bookmarks",BM); } ui->actionManage_Bookmarks->setEnabled(BM.length()>0); } @@ -434,16 +420,16 @@ void MainUI::on_actionClose_triggered(){ this->close(); } -void MainUI::on_actionRename_triggered(){ +/*void MainUI::on_actionRename_triggered(){ DirWidget *dir = FindActiveBrowser(); if(DEBUG){ qDebug() << "Rename Shortcut Pressed:" << dir << dir->currentDir(); } - if(dir!=0){ QTimer::singleShot(0, dir, SLOT(TryRenameSelection()) ); } + if(dir!=0){ QTimer::singleShot(0, dir, SLOT(renameFiles()) ); } } void MainUI::on_actionCut_Selection_triggered(){ DirWidget *dir = FindActiveBrowser(); if(DEBUG){ qDebug() << "Cut Shortcut Pressed:" << dir << dir->currentDir(); } - if(dir!=0){ QTimer::singleShot(0, dir, SLOT(TryCutSelection()) ); } + if(dir!=0){ QTimer::singleShot(0, dir, SLOT(cutFiles()) ); } } void MainUI::on_actionCopy_Selection_triggered(){ @@ -462,7 +448,7 @@ void MainUI::on_actionDelete_Selection_triggered(){ DirWidget *dir = FindActiveBrowser(); if(DEBUG){ qDebug() << "Delete Shortcut Pressed:" << dir << dir->currentDir(); } if(dir!=0){ QTimer::singleShot(0, dir, SLOT(TryDeleteSelection()) ); } -} +}*/ void MainUI::on_actionRefresh_triggered(){ DirWidget *cur = FindActiveBrowser(); @@ -473,24 +459,24 @@ void MainUI::on_actionView_Hidden_Files_triggered(){ worker->showHidden = ui->actionView_Hidden_Files->isChecked(); //Now save this setting for later settings->setValue("showhidden", ui->actionView_Hidden_Files->isChecked()); - worker->showHidden = ui->actionView_Hidden_Files->isChecked(); + //worker->showHidden = ui->actionView_Hidden_Files->isChecked(); //Re-load the current browsers - for(int i=0; irefresh(); } + for(int i=0; ishowHidden( ui->actionView_Hidden_Files->isChecked() ); }//DWLIST[i]->refresh(); } } -void MainUI::on_actionShow_Action_Buttons_triggered(){ +/*void MainUI::on_actionShow_Action_Buttons_triggered(){ bool show = ui->actionShow_Action_Buttons->isChecked(); settings->setValue("showactions", show); - for(int i=0; isetShowSidebar(show); } -} + //for(int i=0; isetShowSidebar(show); } +}*/ -void MainUI::on_actionShow_Thumbnails_triggered(){ +/*void MainUI::on_actionShow_Thumbnails_triggered(){ //Now save this setting for later bool show = ui->actionShow_Thumbnails->isChecked(); settings->setValue("showthumbnails", show); - for(int i=0; isetShowThumbnails(show); } -} + //for(int i=0; isetShowThumbnails(show); } +}*/ void MainUI::goToBookmark(QAction *act){ if(act==ui->actionManage_Bookmarks){ @@ -529,8 +515,9 @@ void MainUI::goToDevice(QAction *act){ void MainUI::viewModeChanged(bool active){ if(!active){ return; } //on every view change, all radio buttons will call this function - only run this once though bool showDetails = radio_view_details->isChecked(); - if(showDetails){ settings->setValue("viewmode","details"); } - else{ settings->setValue("viewmode","list"); } + QSettings SET("lumina-desktop","lumina-fm"); + if(showDetails){ SET.setValue("viewmode","details"); } + else{ SET.setValue("viewmode","list"); } //Re-load the view widgets for(int i=0; iisChecked(); - if(usetabs){ - settings->setValue("groupmode","tabs"); + //bool usetabs = radio_view_tabs->isChecked(); + //if(usetabs){ + //settings->setValue("groupmode","tabs"); //Now clean up all the tabs (remove the generic one and add the specific ones) for(int i=0; icount(); i++){ //Remove all the browser tabs @@ -557,7 +544,7 @@ void MainUI::groupModeChanged(bool active){ qDebug() << "Add specific tab:" << DWLIST[i]->currentDir() << DWLIST[i]->id(); int tab = tabBar->addTab( LXDG::findIcon("folder-open",""), DWLIST[i]->currentDir().section("/",-1) ); tabBar->setTabWhatsThis(tab, DWLIST[i]->id() ); - DWLIST[i]->setShowCloseButton(false); + //DWLIST[i]->setShowCloseButton(false); } }else{ settings->setValue("groupmode","columns"); @@ -572,12 +559,12 @@ void MainUI::groupModeChanged(bool active){ //Now create the generic "browser" tab int tab = tabBar->addTab( LXDG::findIcon("folder-open",""), tr("Browser") ); tabBar->setTabWhatsThis(tab, "browser" ); - for(int i=0; isetShowCloseButton(true); } + //for(int i=0; isetShowCloseButton(true); } } if(tabBar->currentIndex()<0){ tabBar->setCurrentIndex(0); } tabBar->setVisible( tabBar->count() > 1 ); QTimer::singleShot(20, this, SLOT(tabChanged()) ); -} +}*/ void MainUI::on_actionLarger_Icons_triggered(){ int size = settings->value("iconsize", 32).toInt(); @@ -645,16 +632,16 @@ void MainUI::tabChanged(int tab){ else if(info=="#SW"){ ui->stackedWidget->setCurrentWidget(ui->page_image); } else{ ui->stackedWidget->setCurrentWidget(ui->page_browser); - if(radio_view_tabs->isChecked()){ + //if(radio_view_tabs->isChecked()){ for(int i=0; isetVisible(DWLIST[i]->id()==info); } - }else{ + /*}else{ //For columns, all widgets need to be visible for(int i=0; isetVisible(true); } - } + }*/ } tabBar->setVisible( tabBar->count() > 1 ); } @@ -695,22 +682,6 @@ void MainUI::nextTab(){ else{ tabBar->setCurrentIndex( cur+1 ); } } -void MainUI::DirDataAvailable(QString id, QString dir, LFileInfoList list){ - for(int i=0; iid()){ - DWLIST[i]->LoadDir(dir, list); - break; - } - } - if(radio_view_tabs->isChecked()){ - //Need to update the text for the tab so it corresponds to the current directory loaded - for(int i=0; icount(); i++){ - if(tabBar->tabWhatsThis(i)==id){ - tabBar->setTabText(i, dir.section("/",-1)); - } - } - } -} void MainUI::SnapshotDataAvailable(QString id , QString dir, QStringList list){ for(int i=0; iclear(); QApplication::clipboard()->setMimeData(dat); //Update all the buttons to account for clipboard change - for(int i=0; irefreshButtons(); } + //for(int i=0; irefreshButtons(); } } void MainUI::CopyFiles(QStringList list){ @@ -809,7 +780,7 @@ void MainUI::CopyFiles(QStringList list){ QApplication::clipboard()->clear(); QApplication::clipboard()->setMimeData(dat); //Update all the buttons to account for clipboard change - for(int i=0; irefreshButtons(); } + //for(int i=0; irefreshButtons(); } } void MainUI::PasteFiles(QString dir, QStringList raw){ @@ -864,7 +835,7 @@ void MainUI::PasteFiles(QString dir, QStringList raw){ } } //Update all the buttons to account for clipboard change - for(int i=0; irefresh(); } + //for(int i=0; irefresh(); } } void MainUI::FavoriteFiles(QStringList list){ @@ -930,13 +901,13 @@ void MainUI::RemoveFiles(QStringList list){ //Now remove the file/dir qDebug() << " - Delete: "<pauseData = true; //pause any info requests + //worker->pauseData = true; //pause any info requests FODialog dlg(this); dlg.RemoveFiles(paths); dlg.show(); dlg.exec(); - worker->pauseData = false; //resume info requests - for(int i=0; irefresh(); } + //worker->pauseData = false; //resume info requests + //for(int i=0; irefresh(); } } void MainUI::CloseBrowser(QString ID){ @@ -959,3 +930,12 @@ void MainUI::CloseBrowser(QString ID){ OpenDirs(QStringList() << QDir::homePath()); } } + +void MainUI::TabNameChanged(QString id, QString name){ + for(int i=0; icount(); i++){ + if(tabBar->tabWhatsThis(i)==id){ + tabBar->setTabText(i, name); + return; + } + } +} diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.h b/src-qt5/desktop-utils/lumina-fm/MainUI.h index 19b40406..94c6f6c2 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.h @@ -55,7 +55,7 @@ #include "DirData.h" #include "widgets/MultimediaWidget.h" #include "widgets/SlideshowWidget.h" -#include "widgets/DirWidget.h" +#include "widgets/DirWidget2.h" namespace Ui{ class MainUI; @@ -79,8 +79,8 @@ private: QTabBar *tabBar; //QFileSystemModel *fsmod; QMenu *contextMenu; - QRadioButton *radio_view_details, *radio_view_list, *radio_view_tabs, *radio_view_cols; - QWidgetAction *detWA, *listWA, *tabsWA, *colsWA; + QRadioButton *radio_view_details, *radio_view_list;//, *radio_view_tabs, *radio_view_cols; + QWidgetAction *detWA, *listWA;//, *tabsWA, *colsWA; //UI Widgets QList DWLIST; @@ -116,19 +116,19 @@ private slots: void on_actionSearch_triggered(); void on_actionClose_Browser_triggered(); void on_actionClose_triggered(); - void on_actionRename_triggered(); + /*void on_actionRename_triggered(); void on_actionCut_Selection_triggered(); void on_actionCopy_Selection_triggered(); void on_actionPaste_triggered(); - void on_actionDelete_Selection_triggered(); + void on_actionDelete_Selection_triggered();*/ void on_actionRefresh_triggered(); void on_actionView_Hidden_Files_triggered(); - void on_actionShow_Action_Buttons_triggered(); - void on_actionShow_Thumbnails_triggered(); + //void on_actionShow_Action_Buttons_triggered(); + //void on_actionShow_Thumbnails_triggered(); void goToBookmark(QAction*); void goToDevice(QAction*); void viewModeChanged(bool); - void groupModeChanged(bool); + //void groupModeChanged(bool); void on_actionLarger_Icons_triggered(); void on_actionSmaller_Icons_triggered(); void CreateBookMark(); @@ -148,7 +148,7 @@ private slots: void focusDirWidget(); //Backend Info passing - void DirDataAvailable(QString, QString, LFileInfoList); + //void DirDataAvailable(QString, QString, LFileInfoList); void SnapshotDataAvailable(QString, QString, QStringList); //Dir Browser Interactions @@ -162,7 +162,8 @@ private slots: void RenameFiles(QStringList); //file selection void RemoveFiles(QStringList); //file selection void CloseBrowser(QString); //ID - + void TabNameChanged(QString, QString); // ID/name + //file info in status bar void DisplayStatusBar(QString); diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.ui b/src-qt5/desktop-utils/lumina-fm/MainUI.ui index 3c11d87e..f356eadb 100644 --- a/src-qt5/desktop-utils/lumina-fm/MainUI.ui +++ b/src-qt5/desktop-utils/lumina-fm/MainUI.ui @@ -131,23 +131,11 @@ - - - Group Mode - - - - - - - - - @@ -164,18 +152,6 @@ - - - Edit - - - - - - - - - Git @@ -184,7 +160,6 @@ - @@ -193,7 +168,7 @@ - New Browser + New Tab New Browser @@ -425,7 +400,7 @@ - Close Browser + Close Tab Ctrl+W diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro index 487a6421..8fb482c7 100644 --- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro +++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro @@ -15,7 +15,7 @@ SOURCES += main.cpp \ BMMDialog.cpp \ widgets/MultimediaWidget.cpp \ widgets/SlideshowWidget.cpp \ - widgets/DirWidget.cpp \ + widgets/DirWidget2.cpp \ gitCompat.cpp \ gitWizard.cpp \ Browser.cpp \ @@ -29,7 +29,7 @@ HEADERS += MainUI.h \ widgets/DDListWidgets.h \ widgets/MultimediaWidget.h \ widgets/SlideshowWidget.h \ - widgets/DirWidget.h \ + widgets/DirWidget2.h \ gitCompat.h \ gitWizard.h \ Browser.h \ @@ -40,7 +40,7 @@ FORMS += MainUI.ui \ BMMDialog.ui \ widgets/MultimediaWidget.ui \ widgets/SlideshowWidget.ui \ - widgets/DirWidget.ui \ + widgets/DirWidget2.ui \ gitWizard.ui icons.files = Insight-FileManager.png diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h index e7dfb4d1..8049600e 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h @@ -44,14 +44,20 @@ public: this->setFlow(QListView::TopToBottom); this->setWrapping(true); this->setMouseTracking(true); - //this->setSortingEnabled(true); //This sorts *only* by name - type is not preserved + this->setSortingEnabled(true); //This sorts *only* by name - type is not preserved } ~DDListWidget(){} signals: void DataDropped(QString, QStringList); //Dir path, List of commands - + void GotFocus(); + protected: + void focusInEvent(QFocusEvent *ev){ + QListWidget::focusInEvent(ev); + emit GotFocus(); + } + void startDrag(Qt::DropActions act){ QList items = this->selectedItems(); if(items.length()<1){ return; } @@ -157,8 +163,13 @@ public: signals: void DataDropped(QString, QStringList); //Dir path, List of commands - + void GotFocus(); + protected: + void focusInEvent(QFocusEvent *ev){ + QTreeWidget::focusInEvent(ev); + emit GotFocus(); + } void startDrag(Qt::DropActions act){ QList items = this->selectedItems(); if(items.length()<1){ return; } @@ -261,10 +272,10 @@ public: inline virtual bool operator<(const QTreeWidgetItem &tmp) const { int column = this->treeWidget()->sortColumn(); // We are in date text - if(column == 3 || column == 4) + if(column == 3 || column == 4){ return this->whatsThis(column) < tmp.whatsThis(column); // We are in size text - else if(column == 1) { + }else if(column == 1) { QString text = this->text(column); QString text_tmp = tmp.text(column); double filesize, filesize_tmp; @@ -280,9 +291,29 @@ public: else filesize_tmp = LUtils::DisplaySizeToBytes(text_tmp); return filesize < filesize_tmp; + + //Name column - still sort by type too (folders first) + }else if(column == 0 && (this->text(2).isEmpty() || tmp.text(2).isEmpty()) ){ + if(this->text(2) != tmp.text(2)){ return this->text(2).isEmpty(); } } // In other cases, we trust base class implementation return QTreeWidgetItem::operator<(tmp); } }; + +//Item override for sorting purposes of list widget items +class CQListWidgetItem : public QListWidgetItem { +public: + CQListWidgetItem(const QIcon &icon, const QString &text, QListWidget *parent = Q_NULLPTR) : QListWidgetItem(icon,text,parent) {} + virtual ~CQListWidgetItem() {} + inline virtual bool operator<(const QListWidgetItem &tmp) const { + QString type = this->data(Qt::UserRole).toString(); + QString tmptype = tmp.data(Qt::UserRole).toString(); + //Sort by type first + if(type!=tmptype){ return (QString::compare(type,tmptype)<0); } + //Then sort by name using the normal rules + return QListWidgetItem::operator<(tmp); + } +}; + #endif -- cgit From 0a1550c1a1d5454b72986c35139ffaf826532b90 Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 30 Sep 2016 14:47:35 -0400 Subject: Oops, forgot to add a couple new files. --- .../desktop-utils/lumina-fm/widgets/DirWidget2.cpp | 717 +++++++++++++++++++++ .../desktop-utils/lumina-fm/widgets/DirWidget2.h | 178 +++++ .../desktop-utils/lumina-fm/widgets/DirWidget2.ui | 249 +++++++ 3 files changed, 1144 insertions(+) create mode 100644 src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp create mode 100644 src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h create mode 100644 src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui (limited to 'src-qt5/desktop-utils/lumina-fm') diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp new file mode 100644 index 00000000..a79f4516 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp @@ -0,0 +1,717 @@ +//=========================================== +// Lumina-DE source code +// Copyright (c) 2015, Ken Moore +// Available under the 3-clause BSD license +// See the LICENSE file for full details +//=========================================== +#include "DirWidget2.h" +#include "ui_DirWidget2.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "../ScrollDialog.h" + +#define DEBUG 1 + +DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){ + ui->setupUi(this); //load the designer file + ID = objID; + //Assemble the toolbar for the widget + toolbar = new QToolBar(this); + toolbar->setContextMenuPolicy(Qt::CustomContextMenu); + toolbar->setFloatable(false); + toolbar->setMovable(false); + toolbar->setOrientation(Qt::Horizontal); + toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly); + //toolbar->setIconSize(QSize(32,32)); + ui->toolbar_layout->addWidget(toolbar); + // - Add the buttons to the toolbar + toolbar->addAction(ui->actionBack); + toolbar->addAction(ui->actionUp); + toolbar->addAction(ui->actionHome); + line_dir = new QLineEdit(this); + toolbar->addWidget(line_dir); + connect(line_dir, SIGNAL(returnPressed()), this, SLOT(dir_changed()) ); + toolbar->addAction(ui->actionSingleColumn); + ui->actionSingleColumn->setChecked(true); + toolbar->addAction(ui->actionDualColumn); + toolbar->addAction(ui->actionMenu); + //Add the browser widgets + RCBW = 0; //right column browser is unavailable initially + BW = new BrowserWidget("", this); + ui->browser_layout->addWidget(BW); + connect(BW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) ); + connect(BW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) ); + connect(BW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) ); + connect(BW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) ); + connect(BW, SIGNAL(updateDirectoryStatus(QString)), this, SLOT(dirStatusChanged(QString)) ); + connect(BW, SIGNAL(hasFocus(QString)), this, SLOT(setCurrentBrowser(QString)) ); + //Now update the rest of the UI + canmodify = false; //initial value + contextMenu = new QMenu(this); + cNewMenu = cOpenMenu = cFModMenu = cFViewMenu = 0; //not created yet + connect(contextMenu, SIGNAL(aboutToShow()), this, SLOT(UpdateContextMenu()) ); + + UpdateIcons(); + UpdateText(); + createMenus(); +} + +DirWidget::~DirWidget(){ + //stopload = true; //just in case another thread is still loading/running +} + +void DirWidget::setFocusLineDir() { + line_dir->setFocus(); + line_dir->selectAll(); +} + +void DirWidget::cleanup(){ + //stopload = true; //just in case another thread is still loading/running + //if(thumbThread.isRunning()){ thumbThread.waitForFinished(); } //this will stop really quickly with the flag set +} + +void DirWidget::ChangeDir(QString dirpath){ + //stopload = true; //just in case it is still loading + //emit LoadDirectory(ID, dirpath); + qDebug() << "ChangeDir:" << dirpath; + currentBrowser()->changeDirectory(dirpath); +} + +void DirWidget::setDirCompleter(QCompleter *comp){ + //line_dir->setCompleter(comp); +} + +QString DirWidget::id(){ + return ID; +} + +QString DirWidget::currentDir(){ + return currentBrowser()->currentDirectory(); +} + +void DirWidget::setShowDetails(bool show){ + BW->showDetails(show); + if(RCBW!=0){ RCBW->showDetails(show); } +} + +void DirWidget::showHidden(bool show){ + BW->showHiddenFiles(show); + if(RCBW!=0){ RCBW->showHiddenFiles(show); } +} + +void DirWidget::setThumbnailSize(int px){ + BW->setThumbnailSize(px); + if(RCBW!=0){ RCBW->setThumbnailSize(px); } + ui->tool_zoom_in->setEnabled(px < 256); //upper limit on image sizes + ui->tool_zoom_out->setEnabled(px >16); //lower limit on image sizes +} + +// ================ +// PUBLIC SLOTS +// ================ + +void DirWidget::LoadSnaps(QString basedir, QStringList snaps){ + //Save these value internally for use later + qDebug() << "ZFS Snapshots available:" << basedir << snaps; + snapbasedir = basedir; + snapshots = snaps; + //if(!snapbasedir.isEmpty()){ watcher->addPath(snapbasedir); } //add this to the watcher in case snapshots get created/removed + //Now update the UI as necessary + if(ui->tool_snap->menu()==0){ + ui->tool_snap->setMenu(new QMenu(this)); + connect(ui->tool_snap->menu(), SIGNAL(triggered(QAction*)), this, SLOT(direct_snap_selected(QAction*)) ); + } + ui->tool_snap->menu()->clear(); + for(int i=0; itool_snap->menu()->addAction(snapshots[i]); + tmp->setWhatsThis(snapshots[i]); + } + ui->slider_snap->setRange(0, snaps.length()); + if(currentBrowser()->currentDirectory().contains(ZSNAPDIR)){ + //The user was already within a snapshot - figure out which one and set the slider appropriately + int index = snaps.indexOf( currentBrowser()->currentDirectory().section(ZSNAPDIR,1,1).section("/",0,0) ); + if(index < 0){ index = snaps.length(); } //unknown - load the system (should never happen) + ui->slider_snap->setValue(index); + }else{ + ui->slider_snap->setValue(snaps.length()); //last item (normal system) + } + on_slider_snap_valueChanged(); + 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()); +} + +void DirWidget::refresh(){ + currentBrowser()->changeDirectory(""); //refresh current dir +} + +//Theme change functions +void DirWidget::UpdateIcons(){ + //Snapshot buttons + ui->tool_snap_newer->setIcon(LXDG::findIcon("go-next-view","") ); + ui->tool_snap_older->setIcon(LXDG::findIcon("go-previous-view","") ); + + //ToolBar Buttons + ui->actionBack->setIcon( LXDG::findIcon("go-previous","") ); + ui->actionUp->setIcon( LXDG::findIcon("go-up","") ); + ui->actionHome->setIcon( LXDG::findIcon("go-home","") ); + ui->actionMenu->setIcon( LXDG::findIcon("format-justify-fill","format-list-unordered") ); + ui->actionSingleColumn->setIcon(LXDG::findIcon("view-right-close","view-close") ); + ui->actionDualColumn->setIcon(LXDG::findIcon("view-right-new","view-split-left-right") ); + + ui->tool_zoom_in->setIcon(LXDG::findIcon("zoom-in","")); + ui->tool_zoom_out->setIcon(LXDG::findIcon("zoom-out","")); + +} + +void DirWidget::UpdateText(){ + ui->retranslateUi(this); + BW->retranslate(); + if(RCBW!=0){ RCBW->retranslate(); } +} + + +//Keyboard Shortcuts triggered +/*void DirWidget::TryRenameSelection(){ + on_tool_act_rename_clicked(); +} + +void DirWidget::TryCutSelection(){ + on_tool_act_cut_clicked(); +} + +void DirWidget::TryCopySelection(){ + on_tool_act_copy_clicked(); +} + +void DirWidget::TryPasteSelection(){ + on_tool_act_paste_clicked(); +} + +void DirWidget::TryDeleteSelection(){ + on_tool_act_rm_clicked(); +}*/ + +// ================= +// PRIVATE +// ================= +void DirWidget::createMenus(){ + //Note: contextMenu already created - this is just for the sub-items + if(cNewMenu==0){ cNewMenu = new QMenu(this); } + else{ cNewMenu->clear(); } + cNewMenu->setTitle(tr("Create...") ); + cNewMenu->setIcon( LXDG::findIcon("list-add","") ); + cNewMenu->addAction(LXDG::findIcon("document-new",""), tr("File"), this, SLOT(createNewFile()) ); + cNewMenu->addAction(LXDG::findIcon("folder-new",""), tr("Directory"), this, SLOT(createNewDir()) ); + if(LUtils::isValidBinary("lumina-fileinfo")){ cNewMenu->addAction(LXDG::findIcon("system-run",""), tr("Application Launcher"), this, SLOT(createNewXDGEntry()) ); } + + if(cOpenMenu==0){ cOpenMenu = new QMenu(this); } + else{ cOpenMenu->clear(); } + cOpenMenu->setTitle(tr("Launch...")); + cOpenMenu->setIcon( LXDG::findIcon("quickopen","") ); + cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(openTerminal())); + cOpenMenu->addAction(LXDG::findIcon("view-preview",""), tr("SlideShow"), this, SLOT(openInSlideshow())); + cOpenMenu->addAction(LXDG::findIcon("view-media-lyrics","media-playback-start"), tr("Multimedia Player"), this, SLOT(openMultimedia())); + + if(cFModMenu==0){ cFModMenu = new QMenu(this); } + else{ cFModMenu->clear(); } + cFModMenu->setTitle(tr("Modify Files...")); + cFModMenu->setIcon( LXDG::findIcon("document-edit","") ); + cFModMenu->addAction(LXDG::findIcon("edit-cut",""), tr("Cut Selection"), this, SLOT(cutFiles()) ); + cFModMenu->addAction(LXDG::findIcon("edit-copy",""), tr("Copy Selection"), this, SLOT(copyFiles()) ); + cFModMenu->addSeparator(); + cFModMenu->addAction(LXDG::findIcon("edit-rename",""), tr("Rename..."), this, SLOT(renameFiles()) ); + cFModMenu->addSeparator(); + cFModMenu->addAction(LXDG::findIcon("edit-delete",""), tr("Delete Selection"), this, SLOT(removeFiles()) ); + + if(cFViewMenu==0){ cFViewMenu = new QMenu(this); } + else{ cFViewMenu->clear(); } + cFViewMenu->setTitle(tr("View Files...")); + cFViewMenu->setIcon( LXDG::findIcon("document-preview","") ); + cFViewMenu->addAction(LXDG::findIcon("document-encrypted",""), tr("Checksums"), this, SLOT(fileCheckSums()) ); + if(LUtils::isValidBinary("lumina-fileinfo")){ + cFViewMenu->addAction(LXDG::findIcon("edit-find-replace",""), tr("Properties"), this, SLOT(fileProperties()) ); + } + +} + +BrowserWidget* DirWidget::currentBrowser(){ + if(cBID.isEmpty() || RCBW==0){ return BW; } + else{ return RCBW; } +} + +QStringList DirWidget::currentDirFiles(){ + return currentBrowser()->currentItems(-1); //files only +} +// ================= +// PRIVATE SLOTS +// ================= + +//UI BUTTONS +void DirWidget::on_tool_zoom_in_clicked(){ + int size = BW->thumbnailSize(); + size += 16; + setThumbnailSize(size); + //Now Save the size value as the default for next time + QSettings SET("lumina-desktop","lumina-fm"); + SET.setValue("iconsize", size); +} + +void DirWidget::on_tool_zoom_out_clicked(){ + int size = BW->thumbnailSize(); + if(size <= 16){ return; } + size -= 16; + setThumbnailSize(size); + //Now Save the size value as the default for next time + QSettings SET("lumina-desktop","lumina-fm"); + SET.setValue("iconsize", size); +} + +// -- Top Snapshot Buttons +void DirWidget::on_tool_snap_newer_clicked(){ + ui->slider_snap->setValue( ui->slider_snap->value()+1 ); +} + +void DirWidget::on_tool_snap_older_clicked(){ + ui->slider_snap->setValue( ui->slider_snap->value()-1 ); +} + +void DirWidget::on_slider_snap_valueChanged(int val){ + bool labelsonly = false; + if(val==-1){ val = ui->slider_snap->value(); labelsonly=true; } + //Update the snapshot interface + ui->tool_snap_newer->setEnabled(val < ui->slider_snap->maximum()); + ui->tool_snap_older->setEnabled(val > ui->slider_snap->minimum()); + if(val >= snapshots.length() || val < 0){ + ui->tool_snap->setText(tr("Current")); + }else if(QFile::exists(snapbasedir+snapshots[val])){ + ui->tool_snap->setText( QFileInfo(snapbasedir+snapshots[val]).lastModified().toString(Qt::DefaultLocaleShortDate) ); + } + //Exit if a non-interactive snapshot change + if(!ui->group_snaps->isEnabled() || labelsonly){ return; } //internal change - do not try to change the actual info + //Determine which snapshot is now selected + QString dir; + if(DEBUG){ qDebug() << "Changing snapshot:" << currentBrowser()->currentDirectory() << val << snapbasedir; } + //stopload = true; //stop any currently-loading procedures + if(val >= snapshots.length() || val < 0){ //active system selected + if(DEBUG){ qDebug() << " - Load Active system:" << normalbasedir; } + dir = normalbasedir; + }else{ + dir = snapbasedir+snapshots[val]+"/"; + if(!QFile::exists(dir)){ + //This snapshot must have been removed in the background by pruning tools + // move to a newer snapshot or the current base dir as necessary + qDebug() << "Snapshot no longer available:" << dir; + qDebug() << " - Reloading available snapshots"; + emit findSnaps(ID, normalbasedir); + return; + } + //Need to figure out the relative path within the snapshot + snaprelpath = normalbasedir.section(snapbasedir.section(ZSNAPDIR,0,0), 1,1000); + if(DEBUG){ qDebug() << " - new snapshot-relative path:" << snaprelpath; } + dir.append(snaprelpath); + dir.replace("//","/"); //just in case any duplicate slashes from all the split/combining + if(DEBUG){ qDebug() << " - Load Snapshot:" << dir; } + } + //Make sure this directory exists, and back up as necessary + if(dir.isEmpty()){ return; } + //Load the newly selected snapshot + currentBrowser()->changeDirectory(dir); +} + +void DirWidget::direct_snap_selected(QAction *act){ + QString snap = act->whatsThis(); + int val = snapshots.indexOf(snap); + if(val<0){ return; } + else{ ui->slider_snap->setValue(val); } +} + +//Top Toolbar buttons +void DirWidget::on_actionBack_triggered(){ + QStringList history = currentBrowser()->history(); + if(history.length()<2){ return; } //cannot do anything + QString dir = history.takeLast(); + //qDebug() << "Go Back:" << dir << normalbasedir << history; + if(dir == normalbasedir){ + dir = history.takeLast(); + } + history << dir; //make sure the current dir is always last in the history + currentBrowser()->changeDirectory(dir); + currentBrowser()->setHistory(history); //re-write the history to account for going backwards + ui->actionBack->setEnabled(history.length()>1); +} + +void DirWidget::on_actionUp_triggered(){ + QString dir = currentBrowser()->currentDirectory().section("/",0,-2); + if(dir.isEmpty()) + dir = "/"; + //Quick check to ensure the directory exists + while(!QFile::exists(dir) && !dir.isEmpty()){ + dir = dir.section("/",0,-2); //back up one additional dir + } + currentBrowser()->changeDirectory(dir); +} + +void DirWidget::on_actionHome_triggered(){ + currentBrowser()->changeDirectory(QDir::homePath()); +} + +void DirWidget::dir_changed(){ + QString dir = line_dir->text().simplified(); + //Run the dir through the user-input checks + dir = LUtils::PathToAbsolute(dir); + //qDebug() << "Dir:" << dir; + //Quick check to ensure the directory exists + while(!QFile::exists(dir) && !dir.isEmpty()){ + dir = dir.section("/",0,-2); //back up one additional dir + } + //qDebug() << " - Now Dir:" << dir; + currentBrowser()->changeDirectory(dir); + //emit LoadDirectory(ID, dir); +} + + +void DirWidget::on_actionSingleColumn_triggered(bool checked){ + if(!checked){ return; } + ui->actionDualColumn->setChecked(false); + if(RCBW==0){ return; } //nothing to do + ui->browser_layout->removeWidget(RCBW); + RCBW->deleteLater(); + RCBW = 0; + setCurrentBrowser(""); //reset back to the remaining browser +} + +void DirWidget::on_actionDualColumn_triggered(bool checked){ + if(!checked){ return; } + ui->actionSingleColumn->setChecked(false); + if(RCBW!=0){ return; } //nothing to do + RCBW = new BrowserWidget("rc", this); + ui->browser_layout->addWidget(RCBW); + connect(RCBW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) ); + connect(RCBW, SIGNAL(itemsActivated()), this, SLOT(itemsActivated()) ); + connect(RCBW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) ); + connect(RCBW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) ); + connect(RCBW, SIGNAL(updateDirectoryStatus(QString)), this, SLOT(dirStatusChanged(QString)) ); + connect(RCBW, SIGNAL(hasFocus(QString)), this, SLOT(setCurrentBrowser(QString)) ); + //Now make sure it has all the same settings as the main browser + setCurrentBrowser("rc"); + RCBW->showDetails(BW->hasDetails()); + RCBW->showHiddenFiles( BW->hasHiddenFiles()); + RCBW->setThumbnailSize( BW->thumbnailSize()); + RCBW->changeDirectory( BW->currentDirectory()); +} + +void DirWidget::on_actionMenu_triggered(){ + OpenContextMenu(); +} + + +// - Other Actions without a specific button on the side +void DirWidget::fileCheckSums(){ + QStringList files = currentBrowser()->currentSelection(); + if(files.isEmpty()){ return; } + qDebug() << "Run Checksums:" << files; + QStringList info = LOS::Checksums(files); + qDebug() << " - Info:" << info; + if(info.isEmpty() || (info.length() != files.length()) ){ return; } + for(int i=0; icurrentSelection(); + //qDebug() << "Open File properties:" << sel; + if(sel.isEmpty()){ return; } + if(!LUtils::isValidBinary("lumina-fileinfo")){ + //It should never get to this point due to checks earlier - but just in case... + QMessageBox::warning(this, tr("Missing Utility"), tr("The \"lumina-fileinfo\" utility could not be found on the system. Please install it first.") ); + return; + } + for(int i=0; icurrentDirectory()); +} + +//Browser Functions +void DirWidget::OpenContextMenu(){ + //Now open the menu at the current cursor location + contextMenu->popup(QCursor::pos()); +} + +void DirWidget::UpdateContextMenu(){ + //First generate the context menu based on the selection + qDebug() << "Update context menu"; + QStringList sel = currentBrowser()->currentSelection(); + contextMenu->clear(); + + if(!sel.isEmpty()){ + contextMenu->addAction(LXDG::findIcon("run-build-file",""), tr("Open"), this, SLOT(runFiles()) ); + contextMenu->addAction(LXDG::findIcon("run-build-configure",""), tr("Open With..."), this, SLOT(runWithFiles()) ); + } + contextMenu->addSection(LXDG::findIcon("unknown",""), tr("File Operations")); + contextMenu->addMenu(cFModMenu); + cFModMenu->setEnabled(!sel.isEmpty() && canmodify); + contextMenu->addMenu(cFViewMenu); + cFViewMenu->setEnabled(!sel.isEmpty()); + contextMenu->addAction(LXDG::findIcon("edit-paste",""), tr("Paste"), this, SLOT(pasteFiles()) )->setEnabled(QApplication::clipboard()->mimeData()->hasFormat("x-special/lumina-copied-files") && canmodify); + //Now add the general selection options + contextMenu->addSection(LXDG::findIcon("folder","inode/directory"), tr("Directory Operations")); + if(canmodify){ + contextMenu->addMenu(cNewMenu); + } + contextMenu->addMenu(cOpenMenu); +} + +void DirWidget::currentDirectoryChanged(bool widgetonly){ + QString cur = currentBrowser()->currentDirectory(); + QFileInfo info(cur); + canmodify = info.isWritable(); + if(widgetonly){ ui->label_status->setText(currentBrowser()->status()); } + else{ ui->label_status->setText(tr("Loading...")); } + //qDebug() << "Start search for snapshots"; + if(!cur.contains("/.zfs/snapshot")){ + normalbasedir = cur; + ui->group_snaps->setVisible(false); + emit findSnaps(ID, cur); + }else{ + //Re-assemble the normalbasedir variable (in case moving around within a snapshot) + normalbasedir = cur.replace( QRegExp("/\\.zfs/snapshot/(.)+/"), "/" ); + } + ui->actionBack->setEnabled( currentBrowser()->history().length()>1 ); + line_dir->setText(normalbasedir); + emit TabNameChanged(ID, normalbasedir.section("/",-1)); +} + +void DirWidget::dirStatusChanged(QString stat){ + if(!canmodify){ stat.prepend(tr("(Limited Access) ")); } + ui->label_status->setText(stat); +} + +void DirWidget::setCurrentBrowser(QString id){ + if(id==cBID){ return; } //no change + cBID = id; + currentDirectoryChanged(true); //update all the averarching widget elements (widget only) + //Now adjust the frame/highlighting around the "active" browser + if(RCBW==0){ BW->setShowActive(true); } + else{ + BW->setShowActive( cBID.isEmpty() ); + RCBW->setShowActive( !cBID.isEmpty() ); + } +} + +//Context Menu Functions +void DirWidget::createNewFile(){ + if(!canmodify){ return; } //cannot create anything here + //Prompt for the new filename + bool ok = false; + QString newdocument = QInputDialog::getText(this, tr("New Document"), tr("Name:"), QLineEdit::Normal, "", \ + &ok, 0, Qt::ImhFormattedNumbersOnly | Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly); + if(!ok || newdocument.isEmpty()){ return; } + //Create the empty file + QString full = BW->currentDirectory(); + if(!full.endsWith("/")){ full.append("/"); } + //verify the new file does not already exist + if(QFile::exists(full+newdocument)){ + QMessageBox::warning(this, tr("Invalid Name"), tr("A file or directory with that name already exists! Please pick a different name.")); + QTimer::singleShot(0,this, SLOT(createNewFile()) ); //repeat this function + return; + } + QFile file(full+newdocument); + if(file.open(QIODevice::ReadWrite)){ + //If successfully opened, it has created a blank file + file.close(); + }else{ + QMessageBox::warning(this, tr("Error Creating Document"), tr("The document could not be created. Please ensure that you have the proper permissions.")); + } +} + +void DirWidget::createNewDir(){ + if(!canmodify){ return; } //cannot create anything here + //Prompt for the new dir name + bool ok = false; + QString newdir = QInputDialog::getText(this, tr("New Directory"), tr("Name:"), QLineEdit::Normal, "", \ + &ok, 0, Qt::ImhFormattedNumbersOnly | Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly); + if(!ok || newdir.isEmpty()){ return; } + //Now create the new dir + QString full = BW->currentDirectory(); + if(!full.endsWith("/")){ full.append("/"); } + QDir dir(full); //open the current dir + full.append(newdir); //append the new name to the current dir + //Verify that the new dir does not already exist + if(dir.exists(full)){ + QMessageBox::warning(this, tr("Invalid Name"), tr("A file or directory with that name already exists! Please pick a different name.")); + QTimer::singleShot(0,this, SLOT(createNewDir()) ); //repeat this function + }else{ + if(!dir.mkdir(newdir) ){ + QMessageBox::warning(this, tr("Error Creating Directory"), tr("The directory could not be created. Please ensure that you have the proper permissions to modify the current directory.")); + } + } +} + +void DirWidget::createNewXDGEntry(){ + if(!canmodify){ return; } //cannot create anything here + //Prompt for the new filename + bool ok = false; + QString newdocument = QInputDialog::getText(this, tr("New Document"), tr("Name:"), QLineEdit::Normal, "", \ + &ok, 0, Qt::ImhFormattedNumbersOnly | Qt::ImhUppercaseOnly | Qt::ImhLowercaseOnly); + if(!ok || newdocument.isEmpty()){ return; } + if(!newdocument.endsWith(".desktop")){ newdocument.append(".desktop"); } + //Create the empty file + QString full = BW->currentDirectory(); + if(!full.endsWith("/")){ full.append("/"); } + //Verify the file does not already exist + if(QFile::exists(full+newdocument)){ + QMessageBox::warning(this, tr("Invalid Name"), tr("A file or directory with that name already exists! Please pick a different name.")); + QTimer::singleShot(0,this, SLOT(createNewFile()) ); //repeat this function + return; + } + QProcess::startDetached("lumina-fileinfo -application \""+full+newdocument+"\""); +} + +/*void DirWidget::createNewSymlink{ + +}*/ + +// - Selected FILE operations +void DirWidget::cutFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + emit CutFiles(sel); +} + +void DirWidget::copyFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + emit CopyFiles(sel); +} + +void DirWidget::pasteFiles(){ + emit PasteFiles(currentBrowser()->currentDirectory(), QStringList() ); +} + +void DirWidget::renameFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + qDebug() << "Deleting selected Items:" << sel; + emit RenameFiles(sel); +} + +void DirWidget::favoriteFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + emit FavoriteFiles(sel); +} + +void DirWidget::removeFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + qDebug() << "Deleting selected Items:" << sel; + emit RemoveFiles(sel); +} + +void DirWidget::runFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + QStringList dirs; + for(int i=0; ichangeDirectory( dirs.takeFirst()); //load the first directory in this widget + } + if(!dirs.isEmpty()){ + emit OpenDirectories(dirs); //open the rest of the directories in other tabs + } +} + +void DirWidget::runWithFiles(){ + QStringList sel = currentBrowser()->currentSelection(); + if(sel.isEmpty()){ return; } + QStringList dirs; + for(int i=0; icurrentSelection(); + if(sel.isEmpty()){ sel = currentDirFiles(); } + //Now turn them all into a list and emit them + LFileInfoList list; + for(int i=0; icurrentSelection(); + if(sel.isEmpty()){ sel = currentDirFiles(); } + //Now turn them all into a list and emit them + LFileInfoList list; + for(int i=0; ibutton(); + if(backmap.testFlag(ev->button())){ + ev->accept(); + on_actionBack_triggered(); + //}else if(ev->button()==Qt::ForwardButton()){ + //ev->accept(); + }else{ + ev->ignore(); //not handled here + } +} diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h new file mode 100644 index 00000000..6a9bdf79 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h @@ -0,0 +1,178 @@ +//=========================================== +// 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "../BrowserWidget.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(); + + void cleanup(); //called before the browser is closed down + + //Directory Managment + void ChangeDir(QString dirpath); + void setDirCompleter(QCompleter *comp); + + //Information + QString id(); + QString currentDir(); + + //View Settings + void setShowDetails(bool show); + void showHidden(bool show); + void setThumbnailSize(int px); + void setFocusLineDir(); + +public slots: + //void LoadDir(QString dir, LFileInfoList list); + void LoadSnaps(QString basedir, QStringList snaps); + + //Refresh options + void refresh(); //Refresh current directory + //void refreshButtons(); //Refresh action buttons only + + //Theme change functions + void UpdateIcons(); + void UpdateText(); + + //Button updates + //void UpdateButtons(); + + //Keyboard Shortcuts triggered + /*void TryRenameSelection(); + void TryCutSelection(); + void TryCopySelection(); + void TryPasteSelection(); + void TryDeleteSelection();*/ + +private: + Ui::DirWidget *ui; + BrowserWidget *BW, *RCBW; //Main BrowserWidget and right-column browser widget + QString ID, cBID; //unique ID assigned by the parent, and currently active browser widget + QString normalbasedir, snapbasedir, snaprelpath; //for maintaining directory context while moving between snapshots + QStringList snapshots, needThumbs, tmpSel; + bool canmodify; + + //The Toolbar and associated items + QToolBar *toolbar; + QLineEdit *line_dir; + + //The context menu and associated items + QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu; + + //Functions for internal use + void createMenus(); //on init only + + BrowserWidget* currentBrowser(); + QStringList currentDirFiles(); //all the "files" available within the current dir/browser + +private slots: + //UI BUTTONS/Actions + + // -- Bottom Action Buttons + void on_tool_zoom_in_clicked(); + void on_tool_zoom_out_clicked(); + + // -- Top Snapshot Buttons + void on_tool_snap_newer_clicked(); + void on_tool_snap_older_clicked(); + void on_slider_snap_valueChanged(int val = -1); + void direct_snap_selected(QAction*); + + //Top Toolbar buttons + void on_actionBack_triggered(); + void on_actionUp_triggered(); + void on_actionHome_triggered(); + void dir_changed(); //user manually changed the directory + void on_actionSingleColumn_triggered(bool); + void on_actionDualColumn_triggered(bool); + void on_actionMenu_triggered(); + + // - Other Actions without a specific button on the side + void fileCheckSums(); + void fileProperties(); + void openTerminal(); + + + //Browser Functions + void OpenContextMenu(); + void UpdateContextMenu(); + void currentDirectoryChanged(bool widgetonly = false); + void dirStatusChanged(QString); + void setCurrentBrowser(QString); + + //Context Menu Functions + // - DIRECTORY operations + void createNewFile(); + void createNewDir(); + void createNewXDGEntry(); + //void createNewSymlink(); + + // - Selected FILE operations + void cutFiles(); + void copyFiles(); + void pasteFiles(); + void renameFiles(); + void favoriteFiles(); + void removeFiles(); + void runFiles(); + void runWithFiles(); + //void attachToNewEmail(); + + // - Context-specific operations + void openInSlideshow(); + void openMultimedia(); + +signals: + //Directory loading/finding signals + void OpenDirectories(QStringList); //Directories to open in other tabs/columns + void findSnaps(QString, QString); //ID, dirpath (Request snapshot information for a directory) + void CloseBrowser(QString); //ID (Request that this browser be closed) + + //External App/Widget launching + void PlayFiles(LFileInfoList); //open in multimedia player + void ViewFiles(LFileInfoList); //open in slideshow + void LaunchTerminal(QString); //dirpath + + //System Interactions + void CutFiles(QStringList); //file selection + void CopyFiles(QStringList); //file selection + void PasteFiles(QString, QStringList); //current dir + void FavoriteFiles(QStringList); //file selection + void RenameFiles(QStringList); //file selection + void RemoveFiles(QStringList); //file selection + void TabNameChanged(QString, QString); //objID, new tab name + +protected: + void mouseReleaseEvent(QMouseEvent *); + +}; + +#endif diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui new file mode 100644 index 00000000..29660ad4 --- /dev/null +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui @@ -0,0 +1,249 @@ + + + DirWidget + + + + 0 + 0 + 400 + 350 + + + + + 350 + 0 + + + + Form + + + + 0 + + + 0 + + + 0 + + + 0 + + + 1 + + + 2 + + + + + + + + 1 + + + + + + 1 + + + 1 + + + 1 + + + 1 + + + + + + 0 + 0 + + + + padding-right: 5px; + + + + + + QToolButton::InstantPopup + + + Qt::ToolButtonTextOnly + + + + + + + 1 + + + 1 + + + Qt::Horizontal + + + false + + + false + + + QSlider::TicksAbove + + + + + + + ... + + + + + + + ... + + + + + + + + + + + + + + + + + Status + + + false + + + + + + + Increase Icon Sizes + + + ZoomIn + + + QToolButton::InstantPopup + + + true + + + + + + + Decrease Icon Sizes + + + ZoomOut + + + true + + + + + + + + + Back + + + Back + + + Go back to previous directory + + + Go back to previous directory + + + + + Up + + + Up + + + Go to parent directory + + + Go to parent directory + + + + + Home + + + Home + + + Go to home directory + + + Go to home directory + + + + + Menu + + + Select Action + + + + + true + + + SingleColumn + + + Single column view + + + + + true + + + Dual Column + + + Dual Column View + + + + + + -- cgit From 6b29ee47912f1e19f80e1cdcc217346f1463ba5c Mon Sep 17 00:00:00 2001 From: Ken Moore Date: Fri, 30 Sep 2016 14:56:13 -0400 Subject: Oops - fix the activation signal for the second column in the dirWidget2. --- .../desktop-utils/lumina-fm/widgets/DirWidget2.cpp | 24 +--------------------- 1 file changed, 1 insertion(+), 23 deletions(-) (limited to 'src-qt5/desktop-utils/lumina-fm') diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp index a79f4516..cc608b92 100644 --- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp +++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp @@ -185,28 +185,6 @@ void DirWidget::UpdateText(){ if(RCBW!=0){ RCBW->retranslate(); } } - -//Keyboard Shortcuts triggered -/*void DirWidget::TryRenameSelection(){ - on_tool_act_rename_clicked(); -} - -void DirWidget::TryCutSelection(){ - on_tool_act_cut_clicked(); -} - -void DirWidget::TryCopySelection(){ - on_tool_act_copy_clicked(); -} - -void DirWidget::TryPasteSelection(){ - on_tool_act_paste_clicked(); -} - -void DirWidget::TryDeleteSelection(){ - on_tool_act_rm_clicked(); -}*/ - // ================= // PRIVATE // ================= @@ -403,7 +381,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){ RCBW = new BrowserWidget("rc", this); ui->browser_layout->addWidget(RCBW); connect(RCBW, SIGNAL(dirChange(QString)), this, SLOT(currentDirectoryChanged()) ); - connect(RCBW, SIGNAL(itemsActivated()), this, SLOT(itemsActivated()) ); + connect(RCBW, SIGNAL(itemsActivated()), this, SLOT(runFiles()) ); connect(RCBW, SIGNAL(DataDropped(QString, QStringList)), this, SIGNAL(PasteFiles(QString, QStringList)) ); connect(RCBW, SIGNAL(contextMenuRequested()), this, SLOT(OpenContextMenu()) ); connect(RCBW, SIGNAL(updateDirectoryStatus(QString)), this, SLOT(dirStatusChanged(QString)) ); -- cgit