aboutsummaryrefslogtreecommitdiff
path: root/src-qt5/desktop-utils/lumina-fm
diff options
context:
space:
mode:
Diffstat (limited to 'src-qt5/desktop-utils/lumina-fm')
-rw-r--r--src-qt5/desktop-utils/lumina-fm/Browser.cpp88
-rw-r--r--src-qt5/desktop-utils/lumina-fm/Browser.h12
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp208
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserModel.h87
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp59
-rw-r--r--src-qt5/desktop-utils/lumina-fm/BrowserWidget.h6
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.cpp33
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.h3
-rw-r--r--src-qt5/desktop-utils/lumina-fm/MainUI.ui7
-rw-r--r--src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h144
-rw-r--r--src-qt5/desktop-utils/lumina-fm/lumina-fm.pro2
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h61
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp21
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h9
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui29
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp36
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h36
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp59
-rw-r--r--src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h13
19 files changed, 827 insertions, 86 deletions
diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.cpp b/src-qt5/desktop-utils/lumina-fm/Browser.cpp
index f2bdc178..29cc5a99 100644
--- a/src-qt5/desktop-utils/lumina-fm/Browser.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/Browser.cpp
@@ -16,10 +16,12 @@
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)) );
+ connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(dirChanged(QString)) );
showHidden = false;
showThumbs = false;
imageFormats = LUtils::imageExtensions(false); //lowercase suffixes
+ //connect(surface, SIGNAL(frameReceived(QImage)), this, SLOT(captureFrame(QImage)));
+ //connect(player, &QMediaPlayer::mediaStatusChanged, this, [&]{ stopVideo(player, player->mediaStatus()); });
connect(this, SIGNAL(threadDone(QString, QImage)), this, SLOT(futureFinished(QString, QImage))); //will always be between different threads
}
@@ -32,6 +34,7 @@ QString Browser::currentDirectory(){ return currentDir; }
void Browser::showHiddenFiles(bool show){
if(show !=showHidden){
showHidden = show;
+ lastcheck = QDateTime(); //reset this timestamp - need to reload all
if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
}
@@ -42,6 +45,7 @@ bool Browser::showingHiddenFiles(){
void Browser::showThumbnails(bool show){
if(show != showThumbs){
showThumbs = show;
+ lastcheck = QDateTime(); //reset this timestamp - need to reload all
if(!currentDir.isEmpty()){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
}
@@ -60,69 +64,83 @@ void Browser::loadItem(QString info, Browser *obj){
file.close();
pix.loadFromData(bytes);
if(pix.width() > 256 || pix.height() > 256 ){
- pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::SmoothTransformation);
+ pix = pix.scaled(256,256, Qt::KeepAspectRatio, Qt::FastTransformation);
}
}
}
-
//qDebug() << " - done with item:" << info;
obj->emit threadDone(info, pix);
}
-QIcon Browser::loadIcon(QString icon){
+QIcon* Browser::loadIcon(QString icon){
if(!mimeIcons.contains(icon)){
mimeIcons.insert(icon, LXDG::findIcon(icon, "unknown"));
}
-
- return mimeIcons[icon];
+ return &mimeIcons[icon];
}
// PRIVATE SLOTS
void Browser::fileChanged(QString file){
- if(file.startsWith(currentDir+"/") ){
+ //qDebug() << "Got File Changed:" << file;
+ if(file.section("/",0,-2) == currentDir){
if(QFile::exists(file) ){ QtConcurrent::run(this, &Browser::loadItem, file, this); } //file modified but not removed
- else{ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); } //file removed - need to update entire dir
- }else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
+ else if(oldFiles.contains(file) ){
+ oldFiles.removeAll(file);
+ emit itemRemoved(file);
+ }
+ }//else if(file==currentDir){ QTimer::singleShot(0, this, SLOT(loadDirectory()) ); }
}
void Browser::dirChanged(QString dir){
-
- if(dir==currentDir){ QTimer::singleShot(500, this, SLOT(loadDirectory()) ); }
+ //qDebug() << "Got Dir Changed:" << dir;
+ if(dir==currentDir){ QTimer::singleShot(10, this, SLOT(loadDirectory()) ); }
else if(dir.startsWith(currentDir)){ QtConcurrent::run(this, &Browser::loadItem, dir, this ); }
}
void Browser::futureFinished(QString name, QImage icon){
//Note: this will be called once for every item that loads
- QIcon ico;
- //LFileInfo info(name);
- LFileInfo *info = new LFileInfo(name);
- if(!icon.isNull() && showThumbs){
- //qDebug() << " -- Data:";
- QPixmap pix = QPixmap::fromImage(icon);
- ico.addPixmap(pix);
- //}else if(info->isDir()){
- //qDebug() << " -- Folder:";
- //ico = loadIcon("folder");
- }
- if(ico.isNull()){
- //qDebug() << " -- MimeType:" << info.fileName() << info.mimetype();
- ico = loadIcon(info->iconfile());
- }
- this->emit itemDataAvailable( ico, info);
- //qDebug() << " -- done:" << name;
+ //Haven't added the extra files in a directory fix, but that should be easy to do
+ //Try to load a file with multiple videos and lots of other stuff before any other directory. It crashes for some reason
+ //qDebug() << name << "here";
+ QIcon *ico = new QIcon();
+ LFileInfo *info = new LFileInfo(name);
+ if(!icon.isNull() && showThumbs){
+ QPixmap pix = QPixmap::fromImage(icon);
+ ico->addPixmap(pix);
+ /*}else if(info->isVideo() && showThumbs) {
+ if(videoImages.find(name) == videoImages.end()) {
+ LVideoLabel *mediaLabel = new LVideoLabel(name);
+ while(mediaLabel->pixmap()->isNull()) { QCoreApplication::processEvents(QEventLoop::AllEvents, 50); }
+ ico->addPixmap(*(mediaLabel->pixmap()));
+ videoImages.insert(name, *mediaLabel->pixmap());
+ delete mediaLabel;
+ }else{
+ ico->addPixmap(videoImages[name]);
+ }*/
+ }else{
+ ico = loadIcon(info->iconfile());
+ }
+ this->emit itemDataAvailable( *ico, info);
+ //qDebug() << " -- done:" << name;
}
// PUBLIC SLOTS
-void Browser::loadDirectory(QString dir){
+void Browser::loadDirectory(QString dir, bool force){
+ if(force){ lastcheck = QDateTime(); } //reset check time to force reloads
if(dir.isEmpty()){ dir = currentDir; } //reload current directory
if(dir.isEmpty()){ return; } //nothing to do - nothing previously loaded
//qDebug() << "Load Directory" << dir;
+ bool dirupdate = true;
if(currentDir != dir){ //let the main widget know to clear all current items (completely different dir)
+ //videoImages.clear();
oldFiles.clear();
+ lastcheck = QDateTime(); //null time
emit clearItems();
+ dirupdate = false;
}
currentDir = dir; //save this for later
+ QDateTime now = QDateTime::currentDateTime();
//clean up the watcher first
QStringList watched; watched << watcher->files() << watcher->directories();
if(!watched.isEmpty()){ watcher->removePaths(watched); }
@@ -134,15 +152,18 @@ void Browser::loadDirectory(QString dir){
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());
+ if(dirupdate){ emit itemsLoading(files.length()); }
for(int i=0; i<files.length(); i++){
watcher->addPath(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
+ bool reloaditem = !dirupdate || lastcheck.isNull() || (QFileInfo(path).lastModified() > lastcheck || QFileInfo(path).created() > lastcheck);
+ //if(dirupdate){ qDebug() << "Reload Item:" << reloaditem << path.section("/",-1); }
+ //reloaditem = true;
+ if(old.contains(path)){ old.removeAll(path); } //still in existance
//if(showThumbs && imageFormats.contains(path.section(".",-1).toLower())){
- QtConcurrent::run(this, &Browser::loadItem, path, this);
+ //qDebug() << "Future Starting:" << files[i];
+ if(reloaditem){ QtConcurrent::run(this, &Browser::loadItem, path, this); }
/*}else{
//No special icon loading - just skip the file read step
futureFinished(path, QImage()); //loadItem(path, this);
@@ -158,4 +179,5 @@ void Browser::loadDirectory(QString dir){
}else{
emit itemsLoading(0); //nothing to load
}
+ lastcheck = now; // save this for later
}
diff --git a/src-qt5/desktop-utils/lumina-fm/Browser.h b/src-qt5/desktop-utils/lumina-fm/Browser.h
index 94f6ba3f..0f4a0abe 100644
--- a/src-qt5/desktop-utils/lumina-fm/Browser.h
+++ b/src-qt5/desktop-utils/lumina-fm/Browser.h
@@ -15,6 +15,9 @@
#include <QIcon>
//#include <QFutureWatcher>
+#include <QMediaPlayer>
+#include <LVideoSurface.h>
+#include <LVideoLabel.h>
#include <LuminaXDG.h>
/*class FileItem{
public:
@@ -42,22 +45,23 @@ public:
private:
QString currentDir;
+ QDateTime lastcheck;
QFileSystemWatcher *watcher;
+ QMap<QString, QPixmap> videoImages;
bool showHidden, showThumbs;
- QStringList imageFormats, oldFiles;
+ QStringList imageFormats, videoFormats, oldFiles;
QHash<QString, QIcon> mimeIcons; //cache for quickly re-using QIcons
void loadItem(QString info, Browser *obj); //this is the main loader class - multiple instances each run in a separate thread
- QIcon loadIcon(QString icon); //simplification for using/populating the mimIcons cache
+ QIcon* loadIcon(QString icon); //simplification for using/populating the mimIcons cache
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, QImage);
public slots:
- void loadDirectory(QString dir = "");
+ void loadDirectory(QString dir = "", bool force = false);
signals:
//Main Signals
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp
new file mode 100644
index 00000000..d79da006
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.cpp
@@ -0,0 +1,208 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore & JT Pennington
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "BrowserModel.h"
+
+BrowserModel::BrowserModel(QObject *parent){
+
+}
+
+BrowserModel::~BrowserModel(){
+
+}
+
+//Virtual overrides
+QModelIndex BrowserModel::index(int row, int column, const QModelIndex &parent) const{
+
+}
+
+QModelIndex BrowserModel::parent(const QModelIndex &index) const{
+
+}
+
+// item management
+int BrowserModel::rowCount(const QModelIndex &parent) const{
+
+}
+
+bool BrowserModel::insertRows(int row, int count, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeRow(int row, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeRows(int row, int count, const QModelIndex &parent){
+
+}
+
+int BrowserModel::columnCount(const QModelIndex &parent) const{
+
+}
+
+bool BrowserModel::insertColumns(int column, int count, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeColumn(int column, const QModelIndex &parent){
+
+}
+
+bool BrowserModel::removeColumns(int column, int count, const QModelIndex &parent){
+
+}
+
+
+//bool BrowserModel::hasChildren(const QModelIndex &parent) const{
+
+}
+
+
+// data functions
+Qt::ItemFlags BrowserModel::flags(const QModelIndex &index) const{
+
+}
+
+QVariant BrowserModel::data(const QModelIndex &index, int role) const{
+ QFileInfo *info = indexToInfo(index);
+ switch(role){
+ case Qt::DisplayRole:
+ if(index.column()==0){ return QVariant(info->fileName()); }
+ else if(index.column()==1){ return QVariant(info->fileSize()); }
+ else if(index.column()==2){ return QVariant(info->mimetype()); }
+ else if(index.column()==3){ return QVariant(info->lastModified()->toString(Qt::DefaultLocaleShortDate)); }
+ else if(index.column()==4){ return QVariant(info->created()->toString(Qt::DefaultLocaleShortDate)); }
+ case Qt::ToolTipRole:
+ return QVariant(info->absoluteFilePath());
+ case Qt::StatusTipRole:
+ return QVariant(info->absoluteFilePath());
+ case Qt::SizeHintRole;
+ return QVariant(QSize(100,14));
+ case Qt::DecorationRole:
+ return QVariant(LXDG::findIcon(info->iconFile(), "unknown"));
+ }
+ return QVariant();
+}
+
+QVariant BrowserModel::headerData(int section, Qt::Orientation orientation, int role) const{
+ if(role == Qt::DisplayRole){
+ if(orientation == Qt::Horizontal){
+ switch(section){
+ case 0:
+ return QVariant(tr("File Name"));
+ case 1:
+ return QVariant("Size");
+ case 2:
+ return QVariant("Type");
+ case 3:
+ return QVariant("Date Modified");
+ case 4:
+ return QVariant("Date Created");
+ }
+ }
+ }
+ case Qt::DisplayRole:
+ return QVariant(tr("File Name");
+ /*case Qt::ToolTipRole:
+ return QVariant("ToolTip");
+ case Qt::StatusTipRole:
+ return QVariant("Status Tip");
+ case Qt::SizeHintRole;
+ return QVariant(QSize(100,14));*/
+ case Qt::DecorationRole:
+ return QVariant("Icon"));
+ }
+ return QVariant();
+}
+
+// data modification functions
+bool BrowserModel::setData(const QModelIndex &index, const QVariant &value, int role){
+
+}
+
+bool BrowserModel::setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role){
+
+}
+
+
+// drag and drop
+//QMimeData* BrowserModel::mimeData(const QModelIndexList &indexes) const{
+
+}
+
+//QStringList BrowserModel::mimeTypes() const{
+
+}
+
+//bool BrowserModel::setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles){
+
+}
+
+//Qt::DropActions BrowserModel::supportedDropActions() const{
+
+}
+
+//bool BrowserModel::dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent){
+
+}
+
+//Special Functions (non virtual replacements)
+LFileInfo* BrowserModel::fileInfo(QString name){
+
+}
+
+QString BrowserModel::currentDirectory(){
+ return cDir;
+}
+
+
+// ==============
+// PUBLIC SLOTS
+// ==============
+void BrowserModel::loadDirectory(QString dir){
+
+
+}
+
+void BrowserModel::loadItem(QString itempath){
+ LFileInfo *it = new LFileInfo(itempath);
+ //Determine the row/column that it needs to be
+ int row, column;
+ row = 0;
+ //Now create the index
+ for(int i=0; i<5; i++){
+ QModelIndex index = createIndex(row, i, it);
+ }
+}
+
+
+// =============
+// PRIVATE
+// =============
+/*QString BrowserModel::findInHash(QString path){
+ QStringList keys = HASH.keys();
+ for(int i=0; i<keys.length(); i++){
+ if(HASH[keys[i]]->filePath() == path){ return keys[i]; }
+ }
+ return "";
+}
+
+QString BrowserModel::findInHash(QModelIndex index){
+ QString id = QString::number(index.row())+"/"+QString::number(index.column());
+ if(HASH.contains(id)){ return id; }
+ return "";
+}
+
+LFileInfo* BrowserModel::indexToInfo(QString path){
+ QString id = findInHash(path);
+ if(id.isEmpty()){ return 0;}
+ return HASH[id];
+}*/
+
+LFileInfo* BrowserModel::indexToInfo(QModelIndex index){
+ return static_cast<LFileInfo*>(index.internalPointer());
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserModel.h b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h
new file mode 100644
index 00000000..b30e117e
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserModel.h
@@ -0,0 +1,87 @@
+//===========================================
+// Lumina Desktop source code
+// Copyright (c) 2017, Ken Moore & JT Pennington
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+// This is the main browsing backend for the file manager
+//===========================================
+#ifndef _LUMINA_FM_BROWSER_MODEL_BACKEND_H
+#define _LUMINA_FM_BROWSER_MODEL_BACKEND_H
+
+#include <QAbstractItemModel>
+#include <QModelIndex>
+#include <QMimeData>
+#include <QMap>
+#include <QVariant>
+#include <QHash>
+
+#include <LuminaXDG.h>
+
+class BrowserModel : public QAbstractItemModel {
+ Q_OBJECT
+public:
+ BrowserModel(QObject *parent = 0);
+ ~BrowserModel();
+
+ //Virtual overrides
+ QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const;
+ QModelIndex parent(const QModelIndex &index) const;
+
+ // item management
+ int rowCount(const QModelIndex &parent = QModelIndex()) const;
+ bool insertRows(int row, int count, const QModelIndex &parent = QModelIndex());
+ bool removeRow(int row, const QModelIndex &parent = QModelIndex());
+ bool removeRows(int row, int count, const QModelIndex &parent = QModelIndex());
+
+ int columnCount(const QModelIndex &parent = QModelIndex()) const;
+ bool insertColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+ bool removeColumn(int column, const QModelIndex &parent = QModelIndex());
+ bool removeColumns(int column, int count, const QModelIndex &parent = QModelIndex());
+
+ //bool hasChildren(const QModelIndex &parent = QModelIndex()) const;
+
+ // data functions
+ Qt::ItemFlags flags(const QModelIndex &index) const;
+ QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
+ QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
+ // data modification functions
+ bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
+ bool setHeaderData(int section, Qt::Orientation orientation, const QVariant &value, int role = Qt::EditRole);
+
+ // drag and drop
+ //QMimeData* mimeData(const QModelIndexList &indexes) const;
+ //QStringList mimeTypes() const;
+ //bool setItemData(const QModelIndex &index, const QMap<int, QVariant> &roles);
+ //Qt::DropActions supportedDropActions() const;
+ //bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
+
+ //Special Functions (non virtual replacements)
+ LFileInfo* fileInfo(QString name);
+ QString currentDirectory();
+
+ void setShowHidden(bool showHidden);
+ bool showHidden
+
+public slots:
+ void loadDirectory(QString dir="");
+ void loadItem(QString item);
+
+private:
+ QHash<quintptr, QModelIndex> HASH; //QString: "row/column"
+ QString cDir;
+ //simplification functions
+ /*QString findInHash(QString path);
+ QString findInHash(QModelIndex index);
+ LFileInfo* indexToInfo(QString path);*/
+ LFileInfo* indexToInfo(QModelIndex index);
+
+private slots:
+
+protected:
+
+signals:
+
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
index d5f219bb..87a3a6d7 100644
--- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.cpp
@@ -24,7 +24,7 @@ BrowserWidget::BrowserWidget(QString objID, QWidget *parent) : QWidget(parent){
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)) );
+ connect(this, SIGNAL(dirChange(QString, bool)), BROWSER, SLOT(loadDirectory(QString, bool)) );
listWidget = 0;
treeWidget = 0;
readDateFormat();
@@ -38,6 +38,7 @@ BrowserWidget::~BrowserWidget(){
}
void BrowserWidget::changeDirectory(QString dir){
+ videoMap.clear();
if(BROWSER->currentDirectory()==dir){ return; } //already on this directory
//qDebug() << "Change Directory:" << dir << historyList;
@@ -50,7 +51,7 @@ void BrowserWidget::changeDirectory(QString dir){
if( (historyList.isEmpty() || historyList.last()!=cleaned) && !cleaned.isEmpty() ){ historyList << cleaned; }
}
//qDebug() << "History:" << historyList;
- emit dirChange(dir);
+ emit dirChange(dir, false);
}
void BrowserWidget::showDetails(bool show){
@@ -81,7 +82,8 @@ void BrowserWidget::showDetails(bool show){
connect(treeWidget, SIGNAL(GotFocus()), this, SLOT(selectionChanged()) );
retranslate();
treeWidget->sortItems(0, Qt::AscendingOrder);
- if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange(""); }
+ treeWidget->setColumnWidth(0, treeWidget->fontMetrics().width("W")*20);
+ if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("", true); }
}else if(!show && listWidget==0){
listWidget = new DDListWidget(this);
listWidget->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -91,8 +93,10 @@ void BrowserWidget::showDetails(bool show){
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(""); }
+ if(!BROWSER->currentDirectory().isEmpty()){ emit dirChange("",true); }
}
+ if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); }
+ if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); }
//qDebug() << " Done making widget";
}
@@ -109,6 +113,18 @@ bool BrowserWidget::hasHiddenFiles(){
}
void BrowserWidget::showThumbnails(bool show){
+ //qDebug() << show << videoMap.size();
+ for(QString file : videoMap.uniqueKeys()) {
+ QTreeWidgetItem *it = videoMap[file].first;
+ LVideoWidget *widget = videoMap[file].second;
+ if(show) {
+ widget->enableIcons();
+ treeWidget->setItemWidget(it, 0, widget);
+ }else{
+ widget->disableIcons();
+ treeWidget->setItemWidget(it, 0, widget);
+ }
+ }
BROWSER->showThumbnails(show);
}
@@ -125,9 +141,15 @@ void BrowserWidget::setThumbnailSize(int px){
larger = treeWidget->iconSize().height() < px;
treeWidget->setIconSize(QSize(px,px));
}
+ for(QString file : videoMap.uniqueKeys()) {
+ QTreeWidgetItem *it = videoMap[file].first;
+ LVideoWidget *widget = videoMap[file].second;
+ widget->setIconSize(treeWidget->iconSize());
+ treeWidget->setItemWidget(it, 0, widget);
+ }
//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("");
+ emit dirChange("", larger);
}
int BrowserWidget::thumbnailSize(){
@@ -271,6 +293,8 @@ void BrowserWidget::itemRemoved(QString item){
}
void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
+ if(listWidget!=0){ listWidget->setWhatsThis( BROWSER->currentDirectory() ); }
+ if(treeWidget!=0){ treeWidget->setWhatsThis(BROWSER->currentDirectory() ); }
//qDebug() << "Item Data Available:" << info->fileName();
int num = 0;
if(listWidget!=0){
@@ -326,15 +350,28 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
treeWidget->addTopLevelItem(it);
}
}else{
- if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ){ it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first(); }
- else{
+ if( ! treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).isEmpty() ) {
+ it = treeWidget->findItems(info->fileName(), Qt::MatchExactly, 0).first();
+ }else if(info->isVideo() && videoMap.find(info->absoluteFilePath()) == videoMap.end()) {
+ it = new CQTreeWidgetItem(treeWidget);
+ treeWidget->addTopLevelItem(it);
+ LVideoWidget *widget = new LVideoWidget(info->absoluteFilePath(), treeWidget->iconSize(), hasThumbnails(), treeWidget);
+ videoMap.insert(info->absoluteFilePath(), QPair<QTreeWidgetItem*,LVideoWidget*>(it, widget));
+ treeWidget->setItemWidget(it, 0, widget);
+ }else if(info->isVideo()) {
+ it = videoMap[info->absoluteFilePath()].first;
+ LVideoWidget *widget = videoMap[info->absoluteFilePath()].second;
+ widget->setIconSize(treeWidget->iconSize());
+ treeWidget->setItemWidget(it, 0, widget);
+ }else{
it = new CQTreeWidgetItem(treeWidget);
- it->setText(0, info->fileName() ); //name (0)
treeWidget->addTopLevelItem(it);
+ it->setText(0, info->fileName() ); //name (0)
}
}
//Now set/update all the data
- it->setIcon(0, ico);
+ if(!info->isVideo())
+ 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)
@@ -352,7 +389,9 @@ void BrowserWidget::itemDataAvailable(QIcon ico, LFileInfo *info){
}else{
if(freshload && treeWidget!=0){
//qDebug() << "Resize Tree Widget Contents";
- for(int i=0; i<treeWidget->columnCount(); i++){ treeWidget->resizeColumnToContents(i); }
+ //for(int i=treeWidget->columnCount()-1; i>0; i--){ treeWidget->resizeColumnToContents(i); }
+ treeWidget->resizeColumnToContents(1);
+ //treeWidget->resizeColumnToContents(0);
}
freshload = false; //any further changes are updates - not a fresh load of a dir
//Done loading items
diff --git a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
index fafb3746..b17ad588 100644
--- a/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
+++ b/src-qt5/desktop-utils/lumina-fm/BrowserWidget.h
@@ -12,6 +12,8 @@
#include <QWidget>
#include <QThread>
+#include <LVideoWidget.h>
+
#include "Browser.h"
#include "widgets/DDListWidgets.h"
@@ -23,6 +25,7 @@ private:
int numItems; //used for checking if all the items have loaded yet
QString ID, statustip;
QStringList date_format, historyList;
+ QMap<QString,QPair<QTreeWidgetItem*, LVideoWidget*>> videoMap;
bool freshload;
//The drag and drop brower widgets
@@ -86,9 +89,10 @@ signals:
void contextMenuRequested();
void DataDropped(QString, QStringList);
void hasFocus(QString); //ID output
+ void stopLoop();
//Internal signal
- void dirChange(QString); //current dir path
+ void dirChange(QString, bool); //current dir path, force
};
#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
index abb99975..9ce7b69e 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.cpp
@@ -14,8 +14,10 @@
#include <LUtils.h>
#include <LDesktopUtils.h>
+#include <ExternalProcess.h>
#define DEBUG 0
+bool rootmode = false;
MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
//for Signal/slot we must register the Typedef of QFileInfoList
@@ -25,6 +27,8 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
//qRegisterMetaType< QVector<int> >("QVector<int>");
//qRegisterMetaType< QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>");
waitingToClose = false;
+ //put if statement here to check if running as root
+ rootmode = (getuid()==0);
ui->setupUi(this);
if(DEBUG){ qDebug() << "Initilization:"; }
@@ -112,6 +116,7 @@ QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize();
TRAY = new TrayUI(this);
connect(TRAY, SIGNAL(JobsFinished()), this, SLOT(TrayJobsFinished()) );
if(DEBUG){ qDebug() << " - Done with init"; }
+ ui->actionOpen_as_Root->setVisible(LUtils::isValidBinary("qsudo"));
}
MainUI::~MainUI(){
@@ -344,7 +349,7 @@ void MainUI::RebuildDeviceMenu(){
QStringList devs = LOS::ExternalDevicePaths();
//Output Format: <type>::::<filesystem>::::<path> (6/24/14 - version 0.4.0 )
// <type> = [USB, HDRIVE, SDCARD, DVD, LVM, UNKNOWN]
- qDebug() << "Externally-mounted devices:" << devs;
+ //qDebug() << "Externally-mounted devices:" << devs;
//Now add them to the menu appropriately
for(int i=0; i<devs.length(); i++){
//Skip hidden mount points (usually only for system usage - not user browsing)
@@ -356,6 +361,7 @@ void MainUI::RebuildDeviceMenu(){
if(path == "/"){ label = tr("Root"); }
else{ label = path.section("/",-1).simplified(); }
if(label.startsWith(".") ){ continue; } //don't show hidden mountpoint (not usually user-browsable)
+ if(label.endsWith(".desktop")){ label = label.section(".desktop",0,-2); } //chop the shortcut suffix off the end
//Create entry for this device
if( !fs.simplified().isEmpty()){
//Add filesystem type to the label
@@ -502,13 +508,29 @@ void MainUI::goToDevice(QAction *act){
if(act==ui->actionScan){
RebuildDeviceMenu();
}else{
+ QString action = act->whatsThis();
+ if(action.endsWith(".desktop")){
+ //Find the actual action/directory within this shortcut
+ XDGDesktop xdg(action);
+ if(xdg.type==XDGDesktop::DIR){
+ action = xdg.path; //use the new path
+ }else{
+ //Need to run the full open routine on this shortcut
+ QProcess::startDetached("lumina-open", QStringList() << action);
+ return;
+ }
+ }else if( !QFileInfo(action).isDir() ){
+ //Need to run the full open routine on this file since it is not a directory
+ QProcess::startDetached("lumina-open", QStringList() << action);
+ return;
+ }
DirWidget *dir = FindActiveBrowser();
if(dir!=0){
- dir->ChangeDir(act->whatsThis());
+ dir->ChangeDir(action);
return;
}
//If no current dir could be found - open a new tab/column
- OpenDirs(QStringList() << act->whatsThis() );
+ OpenDirs(QStringList() << action );
}
}
@@ -962,3 +984,8 @@ void MainUI::closeEvent(QCloseEvent *ev){
}
QMainWindow::closeEvent(ev); //continue normal close routine
}
+
+void MainUI::on_actionOpen_as_Root_triggered()
+{
+ ExternalProcess::launch("qsudo lumina-fm");
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.h b/src-qt5/desktop-utils/lumina-fm/MainUI.h
index 492ba533..04b80f28 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.h
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.h
@@ -67,6 +67,7 @@ class MainUI : public QMainWindow{
public:
MainUI();
~MainUI();
+ //bool rootmode;
public slots:
void OpenDirs(QStringList); //also called from the main.cpp after initialization
@@ -176,6 +177,8 @@ private slots:
void TrayJobsFinished();
+ void on_actionOpen_as_Root_triggered();
+
signals:
void Si_AdaptStatusBar(QFileInfoList fileList, QString path, QString messageFolders, QString messageFiles);
diff --git a/src-qt5/desktop-utils/lumina-fm/MainUI.ui b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
index 744f31a3..8a635199 100644
--- a/src-qt5/desktop-utils/lumina-fm/MainUI.ui
+++ b/src-qt5/desktop-utils/lumina-fm/MainUI.ui
@@ -119,6 +119,8 @@
<addaction name="separator"/>
<addaction name="actionClose_Browser"/>
<addaction name="separator"/>
+ <addaction name="actionOpen_as_Root"/>
+ <addaction name="separator"/>
<addaction name="actionClose"/>
</widget>
<widget class="QMenu" name="menuView">
@@ -434,6 +436,11 @@
<string>Ctrl+P</string>
</property>
</action>
+ <action name="actionOpen_as_Root">
+ <property name="text">
+ <string>Open as Root</string>
+ </property>
+ </action>
</widget>
<resources/>
<connections/>
diff --git a/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h
new file mode 100644
index 00000000..894394d4
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/VideoItemWidget.h
@@ -0,0 +1,144 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2016, Ken Moore
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#ifndef _LUMINA_VIDEO_ITEM_WIDGET_H
+#define _LUMINA_VIDEO_ITEM_WIDGET_H
+
+#include <QWidget>
+#include <QVideoWidget>
+#include <QMediaPlayer>
+#include <QString>
+#include <QObject>
+#include <QLabel>
+#include <QTimer>
+#include <QHBoxLayout>
+#include <QResizeEvent>
+
+#include <LVideoSurface.h>
+
+class RolloverVideoWidget : public QVideoWidget{
+ Q_OBJECT
+public:
+ RolloverVideoWidget(QWidget *parent = 0) : QVideoWidget(parent){
+ this->setMouseTracking(true);
+ }
+signals:
+ void OverWidget();
+ void NotOverWidget();
+
+protected:
+ /*void mouseMoveEvent(QMouseEvent *ev){
+ QWidget::mouseMoveEvent(ev);
+ qDebug() << "Got video rollover";
+ emit OverWidget();
+ }*/
+ void enterEvent(QEvent *ev){
+ QWidget::enterEvent(ev);
+ qDebug() << "Got video enter";
+ emit OverWidget();
+ }
+ void leaveEvent(QEvent *ev){
+ QWidget::leaveEvent(ev);
+ if(!this->underMouse()){
+ qDebug() << "Got video leave";
+ emit NotOverWidget();
+ }
+ }
+};
+
+class VideoItemWidget : public QWidget{
+ Q_OBJECT
+private:
+ QLabel *textLabel;
+ QMediaPlayer *mplayer;
+ LVideoSurface *vwidget;
+ QString file, text;
+ QSize fixedsize;
+
+public:
+ VideoItemWidget(QString filepath, QWidget *parent = 0) : QWidget(parent){
+ file = filepath;
+ text = filepath.section("/",-1);
+ textLabel = 0;
+ mplayer = 0;
+ vwidget = 0;
+ this->setMouseTracking(true);
+ QTimer::singleShot(5, this, SLOT(setupPlayer()) ); //make sure this creation routine is thread-safe
+ }
+ ~VideoItemWidget(){ mplayer->stop(); }
+
+ //Optional overloads - it will try to automatically adjust as needed
+ void setText(QString txt){
+ text = txt;
+ if(textLabel!=0){
+ textLabel->setText(txt);
+ textLabel->setVisible( !txt.isEmpty() );
+ }
+ }
+ void setIconSize(QSize sz){
+ fixedsize = sz;
+ if(vwidget!=0 && fixedsize.isValid()){ vwidget->setFixedSize(sz); }
+ }
+
+private slots:
+ void setupPlayer(){
+ textLabel = new QLabel(this);
+ vwidget = new LVideoSurface(this); //RolloverVideoWidget(this);
+ vwidget->setAspectRatioMode(Qt::IgnoreAspectRatio);
+ if(fixedsize.isValid()){ vwidget->setFixedSize(fixedsize); }
+ else{ vwidget->setMinimumSize(QSize(16,16)); }
+ mplayer = new QMediaPlayer(this, QMediaPlayer::VideoSurface);
+ mplayer->setVideoOutput(vwidget);
+ mplayer->setPlaybackRate(3); // 3x playback speed
+ mplayer->setMuted(true);
+ QHBoxLayout *tmpL = new QHBoxLayout(this);
+ tmpL->setAlignment(Qt::AlignLeft | Qt::AlignCenter);
+ tmpL->addWidget(vwidget);
+ tmpL->addWidget(textLabel);
+ tmpL->setStretchFactor(textLabel, 1); //make sure this always occupies all extra space
+ //connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(durationChanged(qint64)) );
+ connect(mplayer, SIGNAL(durationChanged(qint64)), this, SLOT(stopVideo()) );
+ //connect(vwidget, SIGNAL(OverWidget()), this, SLOT(startVideo()) );
+ //connect(vwidget, SIGNAL(NotOverWidget()), this, SLOT(stopVideo()) );
+ //Now load the file
+ textLabel->setText(text);
+ mplayer->setMedia(QUrl::fromLocalFile(file) );
+ mplayer->play();
+ }
+ void durationChanged(qint64 max){
+ qDebug() << "Got Duration Changed:" << max;
+ mplayer->setPosition( qRound(max/2.0));
+ }
+
+ void startVideo(){
+ if(mplayer==0){ return; }
+ if(mplayer->state()!=QMediaPlayer::PlayingState){
+ qDebug() << "Start Video";
+ mplayer->setPosition(0);
+ mplayer->play();
+ }
+ }
+
+ void stopVideo(){
+ if(mplayer==0){ return; }
+ if(mplayer->state()==QMediaPlayer::PlayingState){
+ qDebug() << "Stop Video";
+ mplayer->pause();
+ mplayer->setPosition( qRound(mplayer->duration()/2.0) );
+ }
+ }
+
+protected:
+ void resizeEvent(QResizeEvent *ev){
+ if(vwidget!=0 && !fixedsize.isValid()){ vwidget->setFixedSize( QSize(ev->size().height(), ev->size().height()) ); }
+ }
+ /*void mouseMoveEvent(QMouseEvent *ev){
+ QWidget::mouseMoveEvent(ev);
+ stopVideo(); //not over the video widget any more
+ }*/
+};
+
+#endif
diff --git a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
index 6c340e14..e27dad25 100644
--- a/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
+++ b/src-qt5/desktop-utils/lumina-fm/lumina-fm.pro
@@ -15,6 +15,8 @@ include(../../core/libLumina/LuminaXDG.pri)
include(../../core/libLumina/LuminaSingleApplication.pri)
include(../../core/libLumina/LuminaThemes.pri)
include(../../core/libLumina/ExternalProcess.pri)
+#include(../../core/libLumina/LVideoSurface.pri)
+include(../../core/libLumina/LVideoLabel.pri)
SOURCES += main.cpp \
MainUI.cpp \
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
index 254362fd..7e4b1f22 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DDListWidgets.h
@@ -23,6 +23,7 @@
#include <QMouseEvent>
#include <QUrl>
#include <QDir>
+#include <QApplication>
#include <LUtils.h>
@@ -63,8 +64,8 @@ protected:
QList<QListWidgetItem*> items = this->selectedItems();
if(items.length()<1){ return; }
QList<QUrl> urilist;
- for(int i=0; i<items.length(); i++){
- urilist << QUrl::fromLocalFile(items[i]->whatsThis());
+ for(int i=0; i<items.length(); i++){
+ urilist << QUrl::fromLocalFile(items[i]->whatsThis());
}
//Create the mime data
//qDebug() << "Start Drag:" << urilist;
@@ -88,7 +89,7 @@ protected:
ev->ignore();
}
}
-
+
void dragMoveEvent(QDragMoveEvent *ev){
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
//Change the drop type depending on the data/dir
@@ -104,7 +105,7 @@ protected:
}
this->update();
}
-
+
void dropEvent(QDropEvent *ev){
if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported
//qDebug() << "Drop Event:";
@@ -125,7 +126,7 @@ protected:
foreach(const QUrl &url, ev->mimeData()->urls()){
const QString filepath = url.toLocalFile();
//If the target file is modifiable, assume a move - otherwise copy
- if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
+ if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir
}else{ files << "copy::::"+filepath; }
}
@@ -133,18 +134,18 @@ protected:
if(!files.isEmpty()){ emit DataDropped( dirpath, files ); }
this->setCursor(Qt::ArrowCursor);
}
-
+
void mouseReleaseEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
else{ QListWidget::mouseReleaseEvent(ev); } //pass it along to the widget
}
void mousePressEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget
+ else{ QListWidget::mousePressEvent(ev); } //pass it along to the widget
}
/*void mouseMoveEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget
+ else{ QListWidget::mouseMoveEvent(ev); } //pass it along to the widget
}*/
};
@@ -158,6 +159,8 @@ public:
//Drag and Drop Properties
this->setDragDropMode(QAbstractItemView::DragDrop);
this->setDefaultDropAction(Qt::MoveAction); //prevent any built-in Qt actions - the class handles it
+ this->setDropIndicatorShown(true);
+ this->setAcceptDrops(true);
//Other custom properties necessary for the FM
this->setFocusPolicy(Qt::StrongFocus);
this->setContextMenuPolicy(Qt::CustomContextMenu);
@@ -183,8 +186,8 @@ protected:
QList<QTreeWidgetItem*> items = this->selectedItems();
if(items.length()<1){ return; }
QList<QUrl> urilist;
- for(int i=0; i<items.length(); i++){
- urilist << QUrl::fromLocalFile(items[i]->whatsThis(0));
+ for(int i=0; i<items.length(); i++){
+ urilist << QUrl::fromLocalFile(items[i]->whatsThis(0));
}
//Create the mime data
QMimeData *mime = new QMimeData;
@@ -192,35 +195,43 @@ protected:
//Create the drag structure
QDrag *drag = new QDrag(this);
drag->setMimeData(mime);
- /*if(info.first().section("::::",0,0)=="cut"){
- drag->exec(act | Qt::MoveAction);
- }else{*/
+ //qDebug() << "Start Drag:" << urilist;
drag->exec(act | Qt::CopyAction| Qt::MoveAction);
- //}
+ //qDebug() << " - Drag Finished";
}
void dragEnterEvent(QDragEnterEvent *ev){
- //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasFormat(MIME);
+ //qDebug() << "Drag Enter Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
+ //QTreeWidget::dragEnterEvent(ev);
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
ev->acceptProposedAction(); //allow this to be dropped here
}else{
ev->ignore();
- }
+ }
}
-
+
void dragMoveEvent(QDragMoveEvent *ev){
+ //qDebug() << "Drag Move Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
+ //QTreeWidget::dragMoveEvent(ev);
if(ev->mimeData()->hasUrls() && !this->whatsThis().isEmpty() ){
//Change the drop type depending on the data/dir
QString home = QDir::homePath();
- if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); }
- else{ ev->setDropAction(Qt::CopyAction); }
- ev->accept(); //allow this to be dropped here
+ if( this->whatsThis().startsWith(home) ){ ev->setDropAction(Qt::MoveAction); this->setCursor(Qt::DragMoveCursor); }
+ else{ ev->setDropAction(Qt::CopyAction); this->setCursor(Qt::DragCopyCursor);}
+ ev->acceptProposedAction(); //allow this to be dropped here
+ //this->setAcceptDrops(true);
}else{
+ //this->setAcceptDrops(false);
+ this->setCursor(Qt::ForbiddenCursor);
ev->ignore();
}
+ //this->setDropIndicatorShown(true);
+ //this->update();
+ //QTreeWidget::dragMoveEvent(ev);
}
-
+
void dropEvent(QDropEvent *ev){
+ //qDebug() << "Drop Event:" << ev->mimeData()->hasUrls() << this->whatsThis();
if(this->whatsThis().isEmpty() || !ev->mimeData()->hasUrls() ){ ev->ignore(); return; } //not supported
ev->accept(); //handled here
QString dirpath = this->whatsThis();
@@ -239,25 +250,25 @@ protected:
foreach(const QUrl &url, ev->mimeData()->urls()){
const QString filepath = url.toLocalFile();
//If the target file is modifiable, assume a move - otherwise copy
- if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
+ if(QFileInfo(filepath).isWritable() && (filepath.startsWith(home) && dirpath.startsWith(home))){
if(filepath.section("/",0,-2)!=dirpath){ files << "cut::::"+filepath; } //don't "cut" a file into the same dir
}else{ files << "copy::::"+filepath; }
}
//qDebug() << "Drop Event:" << dirpath;
emit DataDropped( dirpath, files );
}
-
+
void mouseReleaseEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
else{ QTreeWidget::mouseReleaseEvent(ev); } //pass it along to the widget
}
void mousePressEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget
+ else{ QTreeWidget::mousePressEvent(ev); } //pass it along to the widget
}
/*void mouseMoveEvent(QMouseEvent *ev){
if(ev->button() != Qt::RightButton && ev->button() != Qt::LeftButton){ ev->ignore(); }
- else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget
+ else{ QTreeWidget::mouseMoveEvent(ev); } //pass it along to the widget
}*/
};
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
index 8273d09c..5c6f9ef5 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.cpp
@@ -27,9 +27,12 @@
#include "../ScrollDialog.h"
#define DEBUG 0
+extern bool rootmode;
DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){
ui->setupUi(this); //load the designer file
+ ui->label_rootmode->setVisible(rootmode);
+
ID = objID;
//Assemble the toolbar for the widget
toolbar = new QToolBar(this);
@@ -59,7 +62,7 @@ DirWidget::DirWidget(QString objID, QSettings *settings, QWidget *parent) : QWid
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(dirChange(QString, bool)), 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()) );
@@ -281,10 +284,11 @@ void DirWidget::createMenus(){
else{ cOpenMenu->clear(); }
cOpenMenu->setTitle(tr("Launch..."));
cOpenMenu->setIcon( LXDG::findIcon("quickopen","") );
- cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Terminal"), this, SLOT(openTerminal()), kOpTerm->key());
+ cOpenMenu->addAction(LXDG::findIcon("utilities-terminal",""), tr("Open Current Dir in a Terminal"), this, SLOT(openTerminal()), kOpTerm->key());
cOpenMenu->addAction(LXDG::findIcon("media-slideshow",""), tr("SlideShow"), this, SLOT(openInSlideshow()), kOpSS->key());
cOpenMenu->addAction(LXDG::findIcon("media-playback-start-circled","media-playback-start"), tr("Multimedia Player"), this, SLOT(openMultimedia()), kOpMM->key());
-/*
+ if(LUtils::isValidBinary("qsudo")){ cOpenMenu->addAction(LXDG::findIcon("", ""), tr("Open Current Dir as Root"), this, SLOT(openRootFM()));
+ /*
if(cFModMenu==0){ cFModMenu = new QMenu(this); }
else{ cFModMenu->clear(); }
cFModMenu->setTitle(tr("Modify Files..."));
@@ -319,6 +323,8 @@ void DirWidget::createMenus(){
}
+}
+
BrowserWidget* DirWidget::currentBrowser(){
if(cBID.isEmpty() || RCBW==0){ return BW; }
else{ return RCBW; }
@@ -471,7 +477,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){
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(dirChange(QString, bool)), this, SLOT(currentDirectoryChanged()) );
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()) );
@@ -482,6 +488,7 @@ void DirWidget::on_actionDualColumn_triggered(bool checked){
RCBW->showDetails(BW->hasDetails());
RCBW->showHiddenFiles( BW->hasHiddenFiles());
RCBW->setThumbnailSize( BW->thumbnailSize());
+ RCBW->showThumbnails( BW->hasThumbnails());
RCBW->changeDirectory( BW->currentDirectory());
}
@@ -880,3 +887,9 @@ void DirWidget::mouseReleaseEvent(QMouseEvent *ev){
ev->ignore(); //not handled here
}
}
+
+void DirWidget::openRootFM(){
+ rootfmdir = "qsudo lumina-fm -new-instance " + currentDir();
+ qDebug() << "rootfmdir" << rootfmdir;
+ ExternalProcess::launch(rootfmdir);
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
index 8dd367df..4377f92d 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.h
@@ -73,9 +73,9 @@ 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
+ QString normalbasedir, snapbasedir, snaprelpath, rootfmdir; //for maintaining directory context while moving between snapshots
QStringList snapshots, needThumbs, tmpSel;
- QSettings *settings;
+ QSettings *settings;
bool canmodify;
//The Toolbar and associated items
@@ -83,10 +83,10 @@ private:
QLineEdit *line_dir;
//The context menu and associated items
- QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu;
+ QMenu *contextMenu, *cNewMenu, *cOpenMenu, *cFModMenu, *cFViewMenu, *cOpenWithMenu;
//The keyboard shortcuts for context menu items
- QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \
+ QShortcut *kZoomIn, *kZoomOut, *kNewFile, *kNewDir, *kNewXDG, *kCut, *kCopy, *kPaste, *kRename, \
*kFav, *kDel, *kOpSS, *kOpMM, *kOpTerm, *kExtract; //, *kArchive;
//Functions for internal use
@@ -129,6 +129,7 @@ private slots:
void fileCheckSums();
void fileProperties();
void openTerminal();
+ void openRootFM();
//Browser Functions
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
index b1ba9d95..5f980c67 100644
--- a/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/DirWidget2.ui
@@ -7,7 +7,7 @@
<x>0</x>
<y>0</y>
<width>400</width>
- <height>350</height>
+ <height>389</height>
</rect>
</property>
<property name="minimumSize">
@@ -19,7 +19,32 @@
<property name="windowTitle">
<string>Form</string>
</property>
- <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,1,0">
+ <layout class="QVBoxLayout" name="verticalLayout" stretch="0,0,0,1,0">
+ <item>
+ <widget class="QLabel" name="label_rootmode">
+ <property name="font">
+ <font>
+ <family>Droid Sans Mono</family>
+ <pointsize>16</pointsize>
+ <weight>75</weight>
+ <italic>false</italic>
+ <bold>true</bold>
+ </font>
+ </property>
+ <property name="frameShape">
+ <enum>QFrame::Box</enum>
+ </property>
+ <property name="frameShadow">
+ <enum>QFrame::Sunken</enum>
+ </property>
+ <property name="text">
+ <string> * - FILE MANAGER RUNNING AS ROOT- * </string>
+ </property>
+ <property name="alignment">
+ <set>Qt::AlignCenter</set>
+ </property>
+ </widget>
+ </item>
<item>
<layout class="QHBoxLayout" name="toolbar_layout"/>
</item>
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp
new file mode 100644
index 00000000..6e65ebaf
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.cpp
@@ -0,0 +1,36 @@
+#include "fmwebdav.h"
+
+fmwebdav::fmwebdav(QObject *parent) : QNetworkAccessManager(parent) ,wdRootPath(), wdUsername(), wdUassword(), wdBaseUrl(), wdCurrentConnectionType(QWebdav::HTTP){
+// typical Qnetwork connection stuff goes here
+// probably ssl parts too
+}
+
+fmwebdav::~fmwebdav(){
+}
+
+QString fmwebdav::hostname() const{ return wdBaseUrl.host(); }
+
+int fmwebdav::port() const{ return wdBaseUrl.port(); }
+
+QString fmwebdav::rootPath() const{ return wdRootPath;}
+
+QString fmwebdav::username() const{ return wdUsername; }
+
+QString fmwebdav::password() const{ return wdPassword; }
+
+fmwebdav::QWebdavConnectionType : fmwebdav::connectionType() const{ return wdCurrentConnectionType; }
+
+bool fmwebdav::isSSL() const{ return (wdCurrentConnectionType==QWebdav::HTTPS); }
+
+void QWebdav::setConnectionSettings(const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath, const QString *username, const QString *password, int *port){
+ wdRootPath = rootPath;
+ if ((wdRootPath.endsWith("/")){ wdRootPath.chop(1); }
+ wdCurrentConnectionType = connectionType;
+ wdBaseUrl.setScheme();
+ wdBaseUrl.setHost(hostname);
+ wdBaseUrl.setPath(rootPath);
+ if (port != 0) { // use user-defined port number if not 80 or 443
+ if ( ! ( ( (port == 80) && (wdCurrentConnectionType==QWebdav::HTTP) ) || ( (port == 443) && (wdCurrentConnectionType==QWebdav::HTTPS) ) ) ){ wdBaseUrl.setPort(port); }
+ wdUsername = username;
+ wdPassword = password;
+}
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h
new file mode 100644
index 00000000..04d29e3b
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/fmwebdav.h
@@ -0,0 +1,36 @@
+#ifndef FMWEBDAV_H
+#define FMWEBDAV_H
+
+#include <QtCore>
+#include <QtNetwork>
+#include <QNetworkAccessManager>
+
+public:
+
+ enum QWebdavConnectionType {HTTP = 1, HTTPS};
+
+ QString hostname() const;
+ int port() const;
+ QString rootPath() const;
+ QString username() const;
+ QString password() const;
+ QWebdavConnectionType connectionType() const;
+ bool isSSL() const;
+
+ void setConnectionSettings( const QWebdavConnectionType connectionType, const QString *hostname, const QString *rootPath = "/", const QString *username = "", const QString *password = "", int *port = 0;
+
+
+private:
+
+ QString wdRootPath;
+ QString wdUsername;
+ QString wdPassword;
+ QUrl wdBaseUrl;
+ QWebdavConnectionType wdCurrentConnectionType;
+
+
+
+
+
+
+#endif // FMWEBDAV
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp
new file mode 100644
index 00000000..d0ecdecf
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.cpp
@@ -0,0 +1,59 @@
+#ifndef VIDNAIL_H
+#define VIDNAIL_H
+
+extern "C" {
+#include <libavcodec/avcodec.h>
+#include <libavformat/avformat.h>
+}
+
+class VidNail;
+
+struct vFrame {
+ vFrame() : *width(0), *height(0) {}
+ vFrame(int *width, int *height : width(width), height(height) {}
+ int *width;
+ int *height;
+};
+
+public:
+
+ QString getCodec();
+ void skipTo(int timeInSeconds);
+ void readVideoFrame();
+ void getScaledVideoFrame(int scaledSize, vFrame& vFrame);
+
+ int getWidth();
+ int getHeight();
+ int getLength();
+
+ void makeThumbnail(const QString& videoFile, QImage &image);
+ void setThumbnailSize(int size);
+ void setPercentage(int percent);
+ void setTime(const QString& Time);
+
+ void writeVidNail(vFrame& frame, QImage& image);
+
+
+ private:
+ bool readVideoPacket();
+ bool getVideoPacket();
+ void scaleVideo(int scaledSize, int& scaledWidth, int& scaledHeight);
+ void createVFrame(AVFrame *vFrame, quint8 *frameBuffer, int width, int height);
+ void calculateDimensions(int size);
+ void generateThumbnail(const QString& videoFile, ImageWriter& imageWriter, QImage& image);
+ QString getMimeType(const QString& videoFile);
+ QString getExtension(const QString& videoFilename);
+
+
+ private:
+ int videoStream;
+ AVFormatContext *inputVideoFormatContext;
+ AVCodecContext *inputvideoCodecContext;
+ AVCodec *inputVideoCodec;
+ AVStream *inputVideoStream;
+ AVFrame *inputVideoFrame;
+ quint8 *inputFrameBuffer;
+ AVPacket *videoPacket;
+
+
+#endif // VIDNAIL_H
diff --git a/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h
new file mode 100644
index 00000000..e13894e1
--- /dev/null
+++ b/src-qt5/desktop-utils/lumina-fm/widgets/vidnail.h
@@ -0,0 +1,13 @@
+//===========================================
+// Lumina-DE source code
+// Copyright (c) 2017, q5sys
+// Available under the 3-clause BSD license
+// See the LICENSE file for full details
+//===========================================
+#include "vidnail.h"
+
+VidNail::VidNail(QObject *parent) : QObject(parent){
+}
+
+VidNail::~VidNail(){
+}
bgstack15