diff options
Diffstat (limited to 'src-qt5/desktop-utils')
31 files changed, 1893 insertions, 744 deletions
diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp index 9d220824..79c023dc 100644 --- a/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.cpp @@ -20,7 +20,11 @@ MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->setupUi(this); - auto_extract_close = false; + delayClose = new QTimer(this); + delayClose->setInterval(500); + delayClose->setSingleShot(true); + connect(delayClose, SIGNAL(timeout()), this, SLOT(close()) ); + QString title = tr("Archive Manager"); if( getuid()==0){ title.append(" ("+tr("Admin Mode")+")"); } this->setWindowTitle(title); @@ -70,33 +74,42 @@ MainUI::~MainUI(){ } void MainUI::LoadArguments(QStringList args){ - bool burnIMG = false; - bool autoExtract = false; - //bool autoArchive = false; + int action = -1; // 0: burnIMG, 1: autoExtract, 2: autoArchive + QStringList files; for(int i=0; i<args.length(); i++){ - if(args[i]=="--burn-img"){ burnIMG = true; continue; } - if(args[i]=="--ax"){ autoExtract = true; continue; } - //if(args[i]=="--aa"){ autoArchive = true; continue; } - if(QFile::exists(args[i])){ - ui->label_progress->setText(tr("Opening Archive...")); - if(autoExtract){ - connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); - connect(BACKEND, SIGNAL(ExtractSuccessful()), this, SLOT(close()) ); - } - BACKEND->loadFile(args[i]); - ui->actionUSB_Image->setEnabled(args[i].simplified().endsWith(".img")); - if(burnIMG){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away - break; + if(args[i].startsWith("--") ){ + if(action>=0){ break; } + else if(args[i]=="--burn-img"){ action = 0; continue; } + else if(args[i]=="--ax"){ action = 1; continue; } + else if(args[i]=="--aa"){ action = 2; continue; } + else if(args[i]=="--sx"){ action = 3; continue; } + }else{ + files << args[i]; } - //if(autoArchive){ - //get rest of arguments - //for(int i=1; i<args.length(); i++){ - // aaFileList << args[i];} - // now launch autoarchive method with arg list - // autoArchiveFiles(aaFileList); - // connect(BACKEND, SIGNAL(ArchivalSuccessful()), this, SLOT(close()) ); - //} } + if(files.isEmpty()){ return; } + //Now go through and do any actions as needed + ui->label_progress->setText(tr("Opening Archive...")); + if(action==1){ + //qDebug() << "blah"; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) ); + }else if(action==2){ + aaFileList.clear(); + for(int j=1; j<files.length(); j++){ aaFileList << files[j]; } + qDebug() << "AA Files:" << aaFileList; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoArchiveFiles()) ); + connect(BACKEND, SIGNAL(ArchivalSuccessful()), delayClose, SLOT(start()) ); + }else if(action==3 && files.length()==2){ + sxFile = files[0]; + sxPath = files[1]; + connect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(simpleExtractFiles()) ); + connect(BACKEND, SIGNAL(ExtractSuccessful()), delayClose, SLOT(start()) ); + } + BACKEND->loadFile(files[0]); + ui->actionUSB_Image->setEnabled(files[0].simplified().endsWith(".img")); + if(action==0){ BurnImgToUSB(); } //Go ahead and launch the burn dialog right away + } void MainUI::loadIcons(){ @@ -255,16 +268,35 @@ void MainUI::extractFiles(){ } void MainUI::autoextractFiles(){ - disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); - QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive - if(dir.isEmpty()){ return; } - ui->label_progress->setText(tr("Extracting...")); - BACKEND->startExtract(dir, true); + disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + QString dir = BACKEND->currentFile().section("/",0,-2); //parent directory of the archive + if(dir.isEmpty()){ return; } + QDir tmp(dir); + QString name = BACKEND->currentFile().section("/",-1).section(".",0,0); + if(QFile::exists(dir+"/"+name)){ + int num = 1; + while( QFile::exists(dir+"/"+name+"_"+QString::number(num))){ num++; } + name = name+"_"+QString::number(num); + } + if(tmp.mkdir(name) ){ + dir.append("/"+name); //created sub directory } + ui->label_progress->setText(tr("Extracting...")); + BACKEND->startExtract(dir, true); +} -/* -void MainUI::autoArchiveFiles(aaFileList){ -*/ +void MainUI::simpleExtractFiles(){ + disconnect(BACKEND, SIGNAL(FileLoaded()), this, SLOT(autoextractFiles()) ); + QString dir = sxPath; + ui->label_progress->setText(tr("Extracting...")); + BACKEND->startExtract(dir, true); +} + +void MainUI::autoArchiveFiles(){ + qDebug() << "Auto Archive Files:" << aaFileList; + ui->label_progress->setText(tr("Adding Items...")); + BACKEND->startAdd(aaFileList); +} void MainUI::extractSelection(){ if(ui->tree_contents->currentItem()==0){ return; } //nothing selected diff --git a/src-qt5/desktop-utils/lumina-archiver/MainUI.h b/src-qt5/desktop-utils/lumina-archiver/MainUI.h index a2687895..1a9d287c 100644 --- a/src-qt5/desktop-utils/lumina-archiver/MainUI.h +++ b/src-qt5/desktop-utils/lumina-archiver/MainUI.h @@ -10,6 +10,7 @@ #include <QMainWindow> #include <QString> #include <QTreeWidgetItem> +#include <QTimer> #include "TarBackend.h" @@ -24,20 +25,21 @@ public: ~MainUI(); void LoadArguments(QStringList); - void loadIcons(); - //QStringList aaFileList; + void loadIcons(); private: Ui::MainUI *ui; Backend *BACKEND; - bool auto_extract_close; + QStringList aaFileList, sxList; + QString sxPath, sxFile; + QTimer *delayClose; QTreeWidgetItem* findItem(QString path, QTreeWidgetItem *start = 0); bool cleanItems(QStringList list, QTreeWidgetItem *start = 0); //returns true if anything gets cleaned //Functions for setting the valid file extensions ("tar" limitations) QString CreateFileTypes(); - QString OpenFileTypes(); + QString OpenFileTypes(); private slots: void NewArchive(); @@ -45,14 +47,15 @@ private slots: void addFiles(); void addDirs(); void remFiles(); - void extractFiles(); - void autoextractFiles(); - //void autoArchiveFiles(QStringList aaFileList); + void extractFiles(); + void autoextractFiles(); + void autoArchiveFiles(); + void simpleExtractFiles(); void extractSelection(); void ViewFile(QTreeWidgetItem *it); void UpdateTree(); - void BurnImgToUSB(); + void BurnImgToUSB(); //Backend Handling void ProcStarting(); diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp index e0b802a4..f110624b 100644 --- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.cpp @@ -36,7 +36,7 @@ void Backend::loadFile(QString path){ flags.clear(); flags << "-f" << filepath; //add the actual archive path if(QFile::exists(path)){ startList(); qDebug () << "BACKEND LOAD startList has started";} - else{ contents.clear(); emit ProcessFinished(true, ""); } + else{ contents.clear(); emit FileLoaded(); emit ProcessFinished(true, ""); } } bool Backend::canModify(){ @@ -262,8 +262,7 @@ void Backend::procFinished(int retcode, QProcess::ExitStatus){ } } if(args.contains("-x")){ result = tr("Extraction Finished"); emit ExtractSuccessful(); } - //if(args.contains("-aa")){ result = tr("Archival Finished"); emit ArchivalSuccessful(); } - else if(args.contains("-c")){ result = tr("Modification Finished"); } + else if(args.contains("-c")){ result = tr("Modification Finished"); emit ArchivalSuccessful(); } if(needupdate){ startList(); } else{ emit ProcessFinished(retcode==0, result); result.clear(); } } diff --git a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h index d86ecf7c..183cb610 100644 --- a/src-qt5/desktop-utils/lumina-archiver/TarBackend.h +++ b/src-qt5/desktop-utils/lumina-archiver/TarBackend.h @@ -64,7 +64,7 @@ signals: void ProcessStarting(); void ProgressUpdate(int, QString); //percentage, text void ProcessFinished(bool, QString); //success, text - //void ArchivalSuccessful(); + void ArchivalSuccessful(); }; #endif diff --git a/src-qt5/desktop-utils/lumina-archiver/main.cpp b/src-qt5/desktop-utils/lumina-archiver/main.cpp index 40cd7967..01e7bda1 100644 --- a/src-qt5/desktop-utils/lumina-archiver/main.cpp +++ b/src-qt5/desktop-utils/lumina-archiver/main.cpp @@ -15,7 +15,7 @@ int main(int argc, char *argv[]) { LTHEME::LoadCustomEnvSettings(); QApplication a(argc, argv); - a.setAttribute(Qt::AA_UseHighDpiPixmaps); + a.setAttribute(Qt::AA_UseHighDpiPixmaps); LUtils::LoadTranslation(&a, "l-archiver"); //Now go ahead and setup the app QStringList args; diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp index d82f09ce..e64346ae 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.cpp @@ -8,21 +8,25 @@ #include "MainUI.h" #include "ui_MainUI.h" +#include <QVideoFrame> #include <QFileDialog> #include <QMessageBox> #include <LUtils.h> #include <LuminaOS.h> -//LFileInfo INFO = LFileInfo(""); - -MainUI::MainUI() : QDialog(), ui(new Ui::MainUI){ +MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ ui->setupUi(this); //load the designer form canwrite = false; terminate_thread = false; + INFO = new LFileInfo(); UpdateIcons(); //Set all the icons in the dialog SetupConnections(); - INFO = 0; + + //Disable buttons that are not working yet + //ui->actionOpen_File->setVisible(false); + //ui->actionOpen_Directory->setVisible(false); + //ui->menuSave_As->setEnabled(false); } MainUI::~MainUI(){ @@ -38,133 +42,38 @@ void MainUI::LoadFile(QString path, QString type){ //Do the first file information tab qDebug() << "Load File:" << path << type; INFO = new LFileInfo(path); - if(INFO->exists()){ canwrite = INFO->isWritable(); } - else if(!INFO->filePath().isEmpty()){ - //See if the containing directory can be written - //QFileInfo chk(INFO->absolutePath()); - canwrite = (INFO->isDir() && INFO->isWritable()); - }else{ - canwrite = true; //no associated file yet - } - if(!INFO->exists() && !type.isEmpty()){ - //Set the proper type flag on the shortcut - if(type=="APP"){ INFO->XDG()->type = XDGDesktop::APP; } - else if(type=="LINK"){ INFO->XDG()->type = XDGDesktop::LINK; } - } //First load the general file information if(!INFO->filePath().isEmpty()){ - ui->label_file_name->setText( INFO->fileName() ); - ui->label_file_mimetype->setText( INFO->mimetype() ); - if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); } - else { - ui->label_file_size->setText(tr("---Calculating---")); - QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath()); - } - ui->label_file_owner->setText(INFO->owner()); - ui->label_file_group->setText(INFO->group()); - ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) ); - ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) ); - //Get the file permissions - QString perms; - if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); } - else if(INFO->isReadable()){ perms = tr("Read Only"); } - else if(INFO->isWritable()){ perms = tr("Write Only"); } - else{ perms = tr("No Access"); } - ui->label_file_perms->setText(perms); - //Now the special "type" for the file - QString ftype; - if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); } - else if(INFO->isDir()){ ftype = tr("Directory"); } - else if(INFO->isExecutable()){ ftype = tr("Binary"); } - else{ ftype = INFO->suffix().toUpper(); } - if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(type); } - ui->label_file_type->setText(ftype); - //Now load the icon for the file - if(INFO->isImage()){ - //qDebug() << "Set Image:"; - QPixmap pix(INFO->absoluteFilePath()); - ui->label_file_icon->setPixmap( pix.scaledToHeight(64) ); - ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" ); - //qDebug() << " - done with image"; - }else{ - ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) ); - } - //Now verify the tab is available in the widget - //qDebug() << "Check tab widget"; - if(ui->tabWidget->indexOf(ui->tab_file)<0){ - //qDebug() << "Add File Info Tab"; - ui->tabWidget->addTab(ui->tab_file, tr("File Information")); - } - //qDebug() << "Done with Tab Check"; + SyncFileInfo(); }else{ - if(ui->tabWidget->indexOf(ui->tab_file)>=0){ - ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) ); - } + SetupNewFile(); } - //Now load the special XDG desktop info - qDebug() << "Check XDG Info:" << type; - //qDebug() << INFO->isDesktopFile() << type; - if(INFO->isDesktopFile() || !type.isEmpty()){ - - if(INFO->XDG()->type == XDGDesktop::APP){ - ui->line_xdg_command->setText(INFO->XDG()->exec); - ui->line_xdg_wdir->setText(INFO->XDG()->path); - ui->check_xdg_useTerminal->setChecked( INFO->XDG()->useTerminal ); - ui->check_xdg_startupNotify->setChecked( INFO->XDG()->startupNotify ); - }else if(INFO->XDG()->type==XDGDesktop::LINK){ - //Hide the options that are unavailable for links - //Command line (exec) - ui->line_xdg_command->setVisible(false); - ui->tool_xdg_getCommand->setVisible(false); - ui->lblCommand->setVisible(false); - //Options - ui->lblOptions->setVisible(false); - ui->check_xdg_useTerminal->setVisible(false); - ui->check_xdg_startupNotify->setVisible(false); - //Now load the variables for this type of shortcut - ui->lblWorkingDir->setText(tr("URL:")); - ui->line_xdg_wdir->setText( INFO->XDG()->url ); - ui->tool_xdg_getDir->setVisible(false); //the dir selection button - - } - ui->line_xdg_name->setText(INFO->XDG()->name); - ui->line_xdg_comment->setText(INFO->XDG()->comment); - ui->push_xdg_getIcon->setWhatsThis( INFO->XDG()->icon ); - ReloadAppIcon(); - ui->push_save->setVisible(true); - ui->push_save->setEnabled(false); - //Now ensure the xdg tab exists in the widget - if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ - qDebug() << "Adding the deskedit tab"; - ui->tabWidget->addTab(ui->tab_deskedit, tr("Edit Shortcut")); - } - }else{ - xdgvaluechanged(); //just do the disables here - //Also remove the xdg tab - if(ui->tabWidget->indexOf(ui->tab_deskedit) >= 0){ - qDebug() << "Removing the deskedit tab"; - ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) ); - } - } - //Setup the tab - if(type.isEmpty()){ ui->tabWidget->setCurrentIndex(0); } - else if(ui->tabWidget->count()>1){ ui->tabWidget->setCurrentIndex(1); } - qDebug() << "Done Loading File"; } void MainUI::UpdateIcons(){ - this->setWindowIcon(LXDG::findIcon("document-preview","unknown")); - ui->push_close->setIcon( LXDG::findIcon("dialog-close","") ); - ui->push_save->setIcon( LXDG::findIcon("document-save","") ); - ui->tool_xdg_getCommand->setIcon( LXDG::findIcon("edit-find-page","") ); - ui->tool_xdg_getDir->setIcon( LXDG::findIcon("document-open","") ); + } //============== // PRIVATE //============== void MainUI::ReloadAppIcon(){ - ui->push_xdg_getIcon->setIcon( LXDG::findIcon(ui->push_xdg_getIcon->whatsThis(),"") ); + //qDebug() << "Reload App Icon:"; + ui->label_xdg_icon->setPixmap( LXDG::findIcon(ui->line_xdg_icon->text(),"").pixmap(64,64) ); + //qDebug() << "Check Desktop File entry"; + if(INFO->iconfile()!=ui->line_xdg_icon->text()){ + xdgvaluechanged(); + } + //qDebug() << "Done with app icon"; +} + +void MainUI::stopDirSize(){ + if(sizeThread.isRunning()){ + terminate_thread = true; + sizeThread.waitForFinished(); + QApplication::processEvents(); //throw away any last signals waiting to be processed + } + terminate_thread = false; } void MainUI::GetDirSize(const QString dirname) const { @@ -215,10 +124,201 @@ void MainUI::GetDirSize(const QString dirname) const { emit folder_size_changed(filesize, file_number, dir_number, true); } +void MainUI::SyncFileInfo(){ + qDebug() << "Sync File Info"; + stopDirSize(); + if(INFO->filePath().isEmpty()){ return; } + if(INFO->exists()){ canwrite = INFO->isWritable(); } + else{ + //See if the containing directory can be written + QFileInfo chk(INFO->absolutePath()); + canwrite = (chk.isDir() && chk.isWritable()); + } + ui->label_file_name->setText( INFO->fileName() ); + ui->label_file_mimetype->setText( INFO->mimetype() ); + if(!INFO->isDir()){ ui->label_file_size->setText( LUtils::BytesToDisplaySize( INFO->size() ) ); } + else { + ui->label_file_size->setText(tr("---Calculating---")); + sizeThread = QtConcurrent::run(this, &MainUI::GetDirSize, INFO->absoluteFilePath()); + } + ui->label_file_owner->setText(INFO->owner()); + ui->label_file_group->setText(INFO->group()); + ui->label_file_created->setText( INFO->created().toString(Qt::SystemLocaleLongDate) ); + ui->label_file_modified->setText( INFO->lastModified().toString(Qt::SystemLocaleLongDate) ); + //Get the file permissions + QString perms; + if(INFO->isReadable() && INFO->isWritable()){ perms = tr("Read/Write"); } + else if(INFO->isReadable()){ perms = tr("Read Only"); } + else if(INFO->isWritable()){ perms = tr("Write Only"); } + else{ perms = tr("No Access"); } + ui->label_file_perms->setText(perms); + //Now the special "type" for the file + QString ftype; + if(INFO->suffix().toLower()=="desktop"){ ftype = tr("XDG Shortcut"); } + else if(INFO->isDir()){ ftype = tr("Directory"); } + else if(INFO->isExecutable()){ ftype = tr("Binary"); } + else{ ftype = INFO->suffix().toUpper(); } + if(INFO->isHidden()){ ftype = QString(tr("Hidden %1")).arg(ftype); } + ui->label_file_type->setText(ftype); + + //Now load the icon for the file + if(INFO->isImage()){ + QPixmap pix(INFO->absoluteFilePath()); + ui->label_file_icon->setPixmap(pix.scaledToHeight(64)); + ui->label_file_size->setText( ui->label_file_size->text()+" ("+QString::number(pix.width())+" x "+QString::number(pix.height())+" px)" ); + }else if(INFO->isVideo()){ + ui->label_file_icon->hide(); + LVideoLabel *mediaLabel = new LVideoLabel(INFO->absoluteFilePath(), true, ui->tab_file); + mediaLabel->setFixedSize(64,64); + ui->formLayout->replaceWidget(ui->label_file_icon, mediaLabel); + }else{ + ui->label_file_icon->setPixmap( LXDG::findIcon( INFO->iconfile(), "unknown").pixmap(QSize(64,64)) ); + } + + //qDebug() << "Check XDG Info:" + //qDebug() << INFO->isDesktopFile() << type; + syncXdgStruct(INFO->XDG()); + //Make sure the right tabs are available + if(ui->tabWidget->indexOf(ui->tab_file)<0){ + //qDebug() << "Add File Info Tab"; + ui->tabWidget->insertTab(0, ui->tab_file, tr("File Information")); + } + if(!INFO->isDesktopFile()){ + if(ui->tabWidget->indexOf(ui->tab_deskedit)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_deskedit) ); + } + }else if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ + ui->tabWidget->addTab( ui->tab_deskedit, tr("XDG Shortcut") ); + } + ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_file) ); +} + +void MainUI::SetupNewFile(){ + //qDebug() << "Setup New File"; + if(!INFO->filePath().isEmpty()){ + INFO = new LFileInfo(); + } + stopDirSize(); + canwrite = true; //can always write a new file + syncXdgStruct(INFO->XDG()); + //Make sure the right tabs are enabled + if(ui->tabWidget->indexOf(ui->tab_file)>=0){ + ui->tabWidget->removeTab( ui->tabWidget->indexOf(ui->tab_file) ); + } + if(ui->tabWidget->indexOf(ui->tab_deskedit)<0){ + //qDebug() << "Adding the deskedit tab"; + ui->tabWidget->addTab(ui->tab_deskedit, tr("XDG Shortcut")); + } + ui->tabWidget->setCurrentIndex(ui->tabWidget->indexOf(ui->tab_deskedit) ); +} + +void MainUI::syncXdgStruct(XDGDesktop *XDG){ + bool cleanup = false; + if(XDG==0){ XDG = new XDGDesktop(); cleanup = true;} //make sure nothing crashes + if(XDG->type == XDGDesktop::APP){ + ui->line_xdg_command->setText(XDG->exec); + ui->line_xdg_wdir->setText(XDG->path); + ui->check_xdg_useTerminal->setChecked( XDG->useTerminal ); + ui->check_xdg_startupNotify->setChecked( XDG->startupNotify ); + }else if(XDG->type==XDGDesktop::LINK){ + //Hide the options that are unavailable for links + //Command line (exec) + ui->line_xdg_command->setVisible(false); + ui->tool_xdg_getCommand->setVisible(false); + ui->lblCommand->setVisible(false); + //Options + ui->lblOptions->setVisible(false); + ui->check_xdg_useTerminal->setVisible(false); + ui->check_xdg_startupNotify->setVisible(false); + //Now load the variables for this type of shortcut + ui->lblWorkingDir->setText(tr("URL:")); + ui->line_xdg_wdir->setText( XDG->url ); + ui->tool_xdg_getDir->setVisible(false); //the dir selection button + } + ui->line_xdg_name->setText(XDG->name); + ui->line_xdg_comment->setText(XDG->comment); + ui->line_xdg_icon->setText( XDG->icon ); + ReloadAppIcon(); + ui->actionSave_Shortcut->setVisible(true); + ui->actionSave_Shortcut->setEnabled(false); + if(cleanup){ delete XDG; } + checkXDGValidity(); +} + +bool MainUI::saveFile(QString path){ + //qDebug() << "Request save file:" << path; + XDGDesktop *XDG = INFO->XDG(); + if(XDG==0){ XDG = new XDGDesktop(); } + if(XDG->type == XDGDesktop::BAD){ XDG->type = XDGDesktop::APP; } + //Update the file path in the data structure + XDG->filePath = path; + //Now change the structure + XDG->name = ui->line_xdg_name->text(); + XDG->genericName = ui->line_xdg_name->text().toLower(); + XDG->comment = ui->line_xdg_comment->text(); + XDG->icon = ui->line_xdg_icon->text(); + //Now do the type-specific fields + if(XDG->type == XDGDesktop::APP){ + XDG->exec = ui->line_xdg_command->text(); + XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check + XDG->path = ui->line_xdg_wdir->text(); //working dir/path + XDG->useTerminal = ui->check_xdg_useTerminal->isChecked(); + XDG->startupNotify = ui->check_xdg_startupNotify->isChecked(); + }else if(XDG->type==XDGDesktop::LINK){ + XDG->url = ui->line_xdg_wdir->text(); //we re-used this field + } + //Clear any info which this utility does not support at the moment + XDG->actionList.clear(); + XDG->actions.clear(); + //Now save the structure to file + //qDebug() << "Saving File:" << XDG->filePath; + return XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary +} + +QString MainUI::findOpenDirFile(bool isdir){ + static QList<QUrl> urls; + if(urls.isEmpty()){ + urls << QUrl::fromLocalFile("/"); + QStringList dirs = QString(getenv("XDG_DATA_DIRS")).split(":"); + for(int i=0; i<dirs.length(); i++){ + if(QFile::exists(dirs[i]+"/applications")){ urls << QUrl::fromLocalFile(dirs[i]+"/applications"); } + } + //Now do the home-directory folders + urls << QUrl::fromLocalFile(QDir::homePath()); + QString localapps = QString(getenv("XDG_DATA_HOME"))+"/applications"; + if(QFile::exists(localapps)){ urls << QUrl::fromLocalFile(localapps); } + } + static QString lastdir = QDir::homePath(); + QFileDialog dlg(this); + dlg.setAcceptMode(QFileDialog::AcceptOpen); + dlg.setFileMode( isdir ? QFileDialog::Directory : QFileDialog::ExistingFiles ); + dlg.setOptions(QFileDialog::ReadOnly | QFileDialog::HideNameFilterDetails); + dlg.setViewMode(QFileDialog::Detail); + dlg.setSidebarUrls( urls ); + dlg.setDirectory(lastdir); + if(!dlg.exec() ){ return ""; } //cancelled + if(dlg.selectedFiles().isEmpty()){ return ""; } + QString path = dlg.selectedFiles().first(); + //Update the last used directory + if(isdir){ lastdir = path; } //save this for next time + else{ lastdir = path.section("/",0,-2); } + //return the path + return path; +} + + // Initialization procedures void MainUI::SetupConnections(){ + connect(ui->actionQuit, SIGNAL(triggered()), this, SLOT(closeApplication()) ); + connect(ui->actionSave_Shortcut, SIGNAL(triggered()), this, SLOT(save_clicked()) ); + connect(ui->actionLocal_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_local_clicked()) ); + connect(ui->actionRegister_Shortcut, SIGNAL(triggered()), this, SLOT(save_as_register_clicked()) ); + connect(ui->actionNew_Shortcut, SIGNAL(triggered()), this, SLOT(SetupNewFile()) ); + connect(ui->actionOpen_File, SIGNAL(triggered()), this, SLOT(open_file_clicked()) ); + connect(ui->actionOpen_Directory, SIGNAL(triggered()), this, SLOT(open_dir_clicked()) ); connect(ui->line_xdg_command, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); connect(ui->line_xdg_comment, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); + connect(ui->line_xdg_icon, SIGNAL(textChanged(QString)), this, SLOT(ReloadAppIcon()) ); connect(ui->tool_xdg_getCommand, SIGNAL(clicked()), this, SLOT(getXdgCommand()) ); connect(ui->line_xdg_name, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); connect(ui->line_xdg_wdir, SIGNAL(editingFinished()), this, SLOT(xdgvaluechanged()) ); @@ -228,58 +328,81 @@ void MainUI::SetupConnections(){ } //UI Buttons -void MainUI::on_push_close_clicked(){ +void MainUI::closeApplication(){ terminate_thread = true; - if(ui->push_save->isEnabled()){ + if(ui->actionSave_Shortcut->isEnabled()){ //Still have unsaved changes //TO-DO - prompt for whether to save the changes } this->close(); } -void MainUI::on_push_save_clicked(){ +void MainUI::save_clicked(){ //Save all the xdg values into the structure - if( (!INFO->isDesktopFile() && !INFO->filePath().isEmpty()) || !canwrite){ return; } - if(INFO->filePath().isEmpty()){ + QString filePath = INFO->filePath(); + if( !filePath.isEmpty() && !INFO->isDesktopFile() ){ return; } + if(filePath.isEmpty() || !canwrite){ //Need to prompt for where to save the file and what to call it QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/"; if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); } - QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("Application Registrations (*.desktop)") ); + filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") ); if(filePath.isEmpty()){ return; } if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } - //Update the file paths in the data structure - INFO->setFile(filePath); - INFO->XDG()->filePath = filePath; } - XDGDesktop *XDG = INFO->XDG(); - //Now change the structure - XDG->name = ui->line_xdg_name->text(); - XDG->genericName = ui->line_xdg_name->text().toLower(); - XDG->comment = ui->line_xdg_comment->text(); - XDG->icon = ui->push_xdg_getIcon->whatsThis(); - //Now do the type-specific fields - if(XDG->type == XDGDesktop::APP){ - XDG->exec = ui->line_xdg_command->text(); - XDG->tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check - XDG->path = ui->line_xdg_wdir->text(); //working dir/path - XDG->useTerminal = ui->check_xdg_useTerminal->isChecked(); - XDG->startupNotify = ui->check_xdg_startupNotify->isChecked(); - }else if(XDG->type==XDGDesktop::LINK){ - XDG->url = ui->line_xdg_wdir->text(); //we re-used this field + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); + if(saved){ + //Re-load the file info + LoadFile(filePath); } - //Clear any info which this utility does not support at the moment - XDG->actionList.clear(); - XDG->actions.clear(); - //Now save the structure to file - bool saved = XDG->saveDesktopFile(true); //Try to merge the file/structure as necessary - qDebug() << "File Saved:" << saved; - ui->push_save->setEnabled( !saved ); +} + +void MainUI::save_as_local_clicked(){ + QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), QDir::homePath(), tr("XDG Shortcuts (*.desktop)") ); + if(filePath.isEmpty()){ return; } + if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } + + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); if(saved){ //Re-load the file info - LoadFile(INFO->absoluteFilePath()); + LoadFile(filePath); } } +void MainUI::save_as_register_clicked(){ + QString appdir = QString(getenv("XDG_DATA_HOME"))+"/applications/"; + if(!QFile::exists(appdir)){ QDir dir; dir.mkpath(appdir); } + QString filePath = QFileDialog::getSaveFileName(this, tr("Save Application File"), appdir, tr("XDG Shortcuts (*.desktop)") ); + if(filePath.isEmpty()){ return; } + if(!filePath.endsWith(".desktop")){ filePath.append(".desktop"); } + + //qDebug() << " -Try Saving File:" << filePath; + bool saved = saveFile(filePath); + //qDebug() << "File Saved:" << saved; + ui->actionSave_Shortcut->setEnabled( !saved ); + if(saved){ + //Re-load the file info + LoadFile(filePath); + } +} + +void MainUI::open_dir_clicked(){ + QString path = findOpenDirFile(true); //directory only + if(path.isEmpty()){ return; } + LoadFile(path, ""); +} + +void MainUI::open_file_clicked(){ + QString path = findOpenDirFile(false); //files only + if(path.isEmpty()){ return; } + LoadFile(path, ""); +} + void MainUI::getXdgCommand(QString prev){ //Find a binary to run QString dir = prev; //start with the previous attempt (if there was one) @@ -315,22 +438,45 @@ void MainUI::on_push_xdg_getIcon_clicked(){ for(int i=0; i<ext.length(); i++){ ext[i].prepend("*."); } //turn them into valid filters QString file = QFileDialog::getOpenFileName(this, tr("Select an icon"), dir ,QString(tr("Images (%1);; All Files (*)")).arg(ext.join(" ")) ); if(file.isEmpty()){ return; } //cancelled - ui->push_xdg_getIcon->setWhatsThis(file); + ui->line_xdg_icon->setText(file); ReloadAppIcon(); xdgvaluechanged(); } //XDG Value Changed +bool MainUI::checkXDGValidity(){ + XDGDesktop tmp; + tmp.type = XDGDesktop::APP; //make this adjustable later (GUI radio buttons?) + tmp.name = ui->line_xdg_name->text(); + tmp.genericName = ui->line_xdg_name->text().toLower(); + tmp.comment = ui->line_xdg_comment->text(); + tmp.icon = ui->line_xdg_icon->text(); + //Now do the type-specific fields + if(tmp.type == XDGDesktop::APP){ + tmp.exec = ui->line_xdg_command->text(); + tmp.tryexec = ui->line_xdg_command->text().section(" ",0,0); //use the first word/binary for the existance check + tmp.path = ui->line_xdg_wdir->text(); //working dir/path + tmp.useTerminal = ui->check_xdg_useTerminal->isChecked(); + tmp.startupNotify = ui->check_xdg_startupNotify->isChecked(); + }else if(tmp.type==XDGDesktop::LINK){ + tmp.url = ui->line_xdg_wdir->text(); //we re-used this field + } + bool valid = tmp.isValid(); + ui->label_xdg_statusicon->setPixmap( LXDG::findIcon( valid ? "dialog-ok" : "dialog-cancel", "").pixmap(32,32) ); + ui->label_xdg_status->setText( valid ? tr("Valid Settings") : tr("Invalid Settings") ); + return tmp.isValid(); +} + void MainUI::xdgvaluechanged(){ - if(INFO!=0 && (INFO->isDesktopFile() || INFO->filePath().isEmpty() ) ){ - ui->push_save->setVisible(true); + //qDebug() << "xdgvaluechanged"; + if( INFO->isDesktopFile() || INFO->filePath().isEmpty() ){ + bool valid = checkXDGValidity(); //Compare the current UI values to the file values - ui->push_save->setEnabled(canwrite); //assume changed at this point - // TO-DO + ui->menuSave_As->setEnabled(valid); + ui->actionSave_Shortcut->setEnabled(canwrite && valid); //assume changed at this point }else{ - ui->push_save->setVisible(false); - ui->push_save->setEnabled(false); + ui->actionSave_Shortcut->setEnabled(false); } } diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h index cbe23d9e..d7b17207 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.h @@ -13,15 +13,20 @@ #ifndef _LUMINA_FILE_INFO_MAIN_UI_H #define _LUMINA_FILE_INFO_MAIN_UI_H -#include <QDialog> +#include <QMainWindow> +#include <QMediaPlayer> +#include <LVideoSurface.h> +#include <LVideoLabel.h> +#include <QElapsedTimer> +#include <QFuture> #include <LuminaXDG.h> namespace Ui{ - class MainUI; + class MainUI; }; -class MainUI : public QDialog{ +class MainUI : public QMainWindow{ Q_OBJECT public: MainUI(); @@ -31,36 +36,55 @@ public: public slots: void UpdateIcons(); + void ReloadAppIcon(); private: Ui::MainUI *ui; LFileInfo *INFO; + LVideoSurface *surface; + QMediaPlayer *player; + bool flag; + QElapsedTimer timer; + QFuture<void> sizeThread; bool canwrite; bool terminate_thread; //flag for terminating the GetDirSize task - void ReloadAppIcon(); + void stopDirSize(); + void GetDirSize(const QString dirname) const; //function to get folder size + void SyncFileInfo(); + + void syncXdgStruct(XDGDesktop*); + + bool saveFile(QString path); + QString findOpenDirFile(bool isdir = false); + signals: void folder_size_changed(quint64 size, quint64 files, quint64 folders, bool finished) const; //Signal for updating the folder size asynchronously private slots: + void SetupNewFile(); //Initialization functions void SetupConnections(); //UI Buttons - void on_push_close_clicked(); - void on_push_save_clicked(); + void closeApplication(); + void save_clicked(); + void save_as_local_clicked(); + void save_as_register_clicked(); + void open_dir_clicked(); + void open_file_clicked(); void getXdgCommand(QString prev = ""); - //void on_tool_xdg_getCommand_clicked(QString prev = ""); void on_tool_xdg_getDir_clicked(); void on_push_xdg_getIcon_clicked(); //XDG Value Changed + bool checkXDGValidity(); void xdgvaluechanged(); - //Folder size - void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously + //Folder size + void refresh_folder_size(quint64 size, quint64 files, quint64 folders, bool finished); //Slot for updating the folder size asynchronously }; #endif diff --git a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui index 51657ba1..217c1a10 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui +++ b/src-qt5/desktop-utils/lumina-fileinfo/MainUI.ui @@ -1,432 +1,652 @@ <?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>MainUI</class> - <widget class="QDialog" name="MainUI"> + <widget class="QMainWindow" name="MainUI"> <property name="geometry"> <rect> <x>0</x> <y>0</y> - <width>349</width> - <height>354</height> + <width>800</width> + <height>658</height> </rect> </property> <property name="windowTitle"> <string>File Information</string> </property> - <layout class="QVBoxLayout" name="verticalLayout"> - <item> - <widget class="QTabWidget" name="tabWidget"> - <property name="currentIndex"> - <number>1</number> - </property> - <widget class="QWidget" name="tab_file"> - <attribute name="title"> - <string>File Information</string> - </attribute> - <layout class="QFormLayout" name="formLayout"> - <property name="labelAlignment"> - <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> - </property> - <item row="0" column="0"> - <widget class="QLabel" name="label_file_icon"> - <property name="text"> - <string notr="true">icon</string> - </property> - <property name="alignment"> - <set>Qt::AlignCenter</set> - </property> - </widget> - </item> - <item row="4" column="0" colspan="2"> - <widget class="Line" name="line_2"> - <property name="sizePolicy"> - <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> - <horstretch>0</horstretch> - <verstretch>0</verstretch> - </sizepolicy> - </property> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="5" column="0"> - <widget class="QLabel" name="label"> - <property name="text"> - <string>Owner:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QLabel" name="label_file_owner"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="6" column="0"> - <widget class="QLabel" name="label_3"> - <property name="text"> - <string>Group:</string> - </property> - </widget> - </item> - <item row="6" column="1"> - <widget class="QLabel" name="label_file_group"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="7" column="0"> - <widget class="QLabel" name="label_11"> - <property name="text"> - <string>Permissions:</string> - </property> - </widget> - </item> - <item row="10" column="0" colspan="2"> - <widget class="Line" name="line_3"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - <item row="11" column="0"> - <widget class="QLabel" name="label_7"> - <property name="text"> - <string>Created:</string> - </property> - </widget> - </item> - <item row="11" column="1"> - <widget class="QLabel" name="label_file_created"> - <property name="toolTip"> - <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string> - </property> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="12" column="0"> - <widget class="QLabel" name="label_2"> - <property name="text"> - <string>Last Modified:</string> - </property> - </widget> - </item> - <item row="1" column="0"> - <widget class="QLabel" name="label_5"> - <property name="text"> - <string>Type:</string> - </property> - </widget> - </item> - <item row="2" column="0"> - <widget class="QLabel" name="label_6"> - <property name="text"> - <string>MimeType:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLabel" name="label_file_mimetype"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="1" column="1"> - <widget class="QLabel" name="label_file_type"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="7" column="1"> - <widget class="QLabel" name="label_file_perms"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="12" column="1"> - <widget class="QLabel" name="label_file_modified"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="3" column="0"> - <widget class="QLabel" name="label_4"> - <property name="text"> - <string>File Size:</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLabel" name="label_file_size"> - <property name="text"> - <string notr="true"/> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - <item row="0" column="1"> - <widget class="QLabel" name="label_file_name"> - <property name="text"> - <string notr="true"/> - </property> - <property name="wordWrap"> - <bool>true</bool> - </property> - <property name="textInteractionFlags"> - <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> - </property> - </widget> - </item> - </layout> - </widget> - <widget class="QWidget" name="tab_deskedit"> - <attribute name="title"> - <string>Edit Shortcut</string> - </attribute> - <layout class="QVBoxLayout" name="verticalLayout_2"> - <property name="spacing"> - <number>2</number> - </property> - <property name="leftMargin"> - <number>4</number> - </property> - <property name="topMargin"> - <number>4</number> - </property> - <property name="rightMargin"> - <number>4</number> - </property> - <property name="bottomMargin"> - <number>4</number> - </property> - <item> - <layout class="QGridLayout" name="gridLayout"> - <item row="3" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblWorkingDir"> - <property name="text"> - <string>Working Dir:</string> - </property> - </widget> - </item> - <item row="5" column="1"> - <widget class="QCheckBox" name="check_xdg_startupNotify"> - <property name="text"> - <string>Use startup notification</string> - </property> - </widget> - </item> - <item row="3" column="1"> - <widget class="QLineEdit" name="line_xdg_wdir"> - <property name="enabled"> - <bool>true</bool> - </property> - </widget> - </item> - <item row="4" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblIcon"> - <property name="text"> - <string>Icon:</string> - </property> - </widget> - </item> - <item row="2" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblCommand"> - <property name="text"> - <string>Command:</string> - </property> - </widget> - </item> - <item row="1" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblComment"> - <property name="text"> - <string>Comment:</string> - </property> - </widget> - </item> - <item row="2" column="1"> - <widget class="QLineEdit" name="line_xdg_command"/> - </item> - <item row="6" column="1"> - <widget class="QCheckBox" name="check_xdg_useTerminal"> - <property name="text"> - <string>Run in terminal</string> - </property> - </widget> - </item> - <item row="0" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblName"> - <property name="text"> - <string>Name:</string> - </property> - </widget> - </item> - <item row="5" column="0" alignment="Qt::AlignRight"> - <widget class="QLabel" name="lblOptions"> - <property name="text"> - <string>Options</string> - </property> - </widget> - </item> - <item row="0" column="1" colspan="2"> - <widget class="QLineEdit" name="line_xdg_name"/> - </item> - <item row="1" column="1" colspan="2"> - <widget class="QLineEdit" name="line_xdg_comment"/> - </item> - <item row="2" column="2"> - <widget class="QToolButton" name="tool_xdg_getCommand"> - <property name="text"> - <string notr="true"/> - </property> - </widget> - </item> - <item row="3" column="2"> - <widget class="QToolButton" name="tool_xdg_getDir"> - <property name="enabled"> - <bool>true</bool> - </property> - <property name="text"> - <string notr="true"/> - </property> - </widget> - </item> - <item row="4" column="1"> - <layout class="QHBoxLayout" name="horizontalLayout"> - <item> - <widget class="QToolButton" name="push_xdg_getIcon"> - <property name="maximumSize"> - <size> - <width>275</width> - <height>16777215</height> - </size> - </property> - <property name="text"> - <string>No Icon</string> - </property> - <property name="iconSize"> - <size> - <width>64</width> - <height>64</height> - </size> - </property> - </widget> - </item> - <item> - <spacer name="horizontalSpacer"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - </layout> - </item> - </layout> - </item> - <item> - <widget class="Line" name="line"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - </widget> - </item> - </layout> - </widget> - </widget> - </item> - <item> - <layout class="QHBoxLayout" name="horizontalLayout_2"> - <item> - <spacer name="horizontalSpacer_2"> - <property name="orientation"> - <enum>Qt::Horizontal</enum> - </property> - <property name="sizeHint" stdset="0"> - <size> - <width>40</width> - <height>20</height> - </size> - </property> - </spacer> - </item> - <item> - <widget class="QToolButton" name="push_save"> - <property name="text"> - <string>Save</string> - </property> - <property name="popupMode"> - <enum>QToolButton::InstantPopup</enum> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> + <property name="windowIcon"> + <iconset theme="document-search"> + <normaloff>.</normaloff>.</iconset> + </property> + <widget class="QWidget" name="centralwidget"> + <layout class="QVBoxLayout" name="verticalLayout"> + <item> + <widget class="QTabWidget" name="tabWidget"> + <property name="currentIndex"> + <number>1</number> + </property> + <widget class="QWidget" name="tab_file"> + <attribute name="title"> + <string>File Information</string> + </attribute> + <layout class="QFormLayout" name="formLayout"> + <property name="labelAlignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + <item row="0" column="0"> + <widget class="QLabel" name="label_file_icon"> + <property name="text"> + <string notr="true">icon</string> + </property> + <property name="alignment"> + <set>Qt::AlignCenter</set> + </property> + </widget> + </item> + <item row="4" column="0" colspan="2"> + <widget class="Line" name="line_2"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="5" column="0"> + <widget class="QLabel" name="label"> + <property name="text"> + <string>Owner:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QLabel" name="label_file_owner"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="6" column="0"> + <widget class="QLabel" name="label_3"> + <property name="text"> + <string>Group:</string> + </property> + </widget> + </item> + <item row="6" column="1"> + <widget class="QLabel" name="label_file_group"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="7" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Permissions:</string> + </property> + </widget> + </item> + <item row="10" column="0" colspan="2"> + <widget class="Line" name="line_3"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + <item row="11" column="0"> + <widget class="QLabel" name="label_7"> + <property name="text"> + <string>Created:</string> + </property> + </widget> + </item> + <item row="11" column="1"> + <widget class="QLabel" name="label_file_created"> + <property name="toolTip"> + <string>Note: The time a file was created might be more recent than the time modified if the file permissions were changed recently.</string> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="12" column="0"> + <widget class="QLabel" name="label_2"> + <property name="text"> + <string>Last Modified:</string> + </property> + </widget> + </item> + <item row="1" column="0"> + <widget class="QLabel" name="label_5"> + <property name="text"> + <string>Type:</string> + </property> + </widget> + </item> + <item row="2" column="0"> + <widget class="QLabel" name="label_6"> + <property name="text"> + <string>MimeType:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLabel" name="label_file_mimetype"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="1" column="1"> + <widget class="QLabel" name="label_file_type"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="7" column="1"> + <widget class="QLabel" name="label_file_perms"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="12" column="1"> + <widget class="QLabel" name="label_file_modified"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="3" column="0"> + <widget class="QLabel" name="label_4"> + <property name="text"> + <string>File Size:</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLabel" name="label_file_size"> + <property name="text"> + <string notr="true"/> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + <item row="0" column="1"> + <widget class="QLabel" name="label_file_name"> + <property name="text"> + <string notr="true"/> + </property> + <property name="wordWrap"> + <bool>true</bool> + </property> + <property name="textInteractionFlags"> + <set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set> + </property> + </widget> + </item> + </layout> </widget> - </item> - <item> - <widget class="QToolButton" name="push_close"> - <property name="text"> - <string>Close</string> - </property> - <property name="popupMode"> - <enum>QToolButton::DelayedPopup</enum> - </property> - <property name="toolButtonStyle"> - <enum>Qt::ToolButtonTextBesideIcon</enum> - </property> + <widget class="QWidget" name="tab_deskedit"> + <attribute name="title"> + <string>XDG Shortcut</string> + </attribute> + <layout class="QVBoxLayout" name="verticalLayout_2"> + <property name="spacing"> + <number>2</number> + </property> + <property name="leftMargin"> + <number>4</number> + </property> + <property name="topMargin"> + <number>4</number> + </property> + <property name="rightMargin"> + <number>4</number> + </property> + <property name="bottomMargin"> + <number>4</number> + </property> + <item> + <layout class="QGridLayout" name="gridLayout"> + <item row="3" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblWorkingDir"> + <property name="text"> + <string>Working Dir:</string> + </property> + </widget> + </item> + <item row="5" column="1"> + <widget class="QCheckBox" name="check_xdg_startupNotify"> + <property name="text"> + <string>Use startup notification</string> + </property> + </widget> + </item> + <item row="3" column="1"> + <widget class="QLineEdit" name="line_xdg_wdir"> + <property name="enabled"> + <bool>true</bool> + </property> + </widget> + </item> + <item row="4" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblIcon"> + <property name="text"> + <string>Icon:</string> + </property> + </widget> + </item> + <item row="2" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblCommand"> + <property name="text"> + <string>Command:</string> + </property> + </widget> + </item> + <item row="1" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblComment"> + <property name="text"> + <string>Comment:</string> + </property> + </widget> + </item> + <item row="2" column="1"> + <widget class="QLineEdit" name="line_xdg_command"/> + </item> + <item row="6" column="1"> + <widget class="QCheckBox" name="check_xdg_useTerminal"> + <property name="text"> + <string>Run in terminal</string> + </property> + </widget> + </item> + <item row="0" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblName"> + <property name="text"> + <string>Name:</string> + </property> + </widget> + </item> + <item row="5" column="0" alignment="Qt::AlignRight"> + <widget class="QLabel" name="lblOptions"> + <property name="text"> + <string>Options</string> + </property> + </widget> + </item> + <item row="0" column="1" colspan="2"> + <widget class="QLineEdit" name="line_xdg_name"/> + </item> + <item row="1" column="1" colspan="2"> + <widget class="QLineEdit" name="line_xdg_comment"/> + </item> + <item row="2" column="2"> + <widget class="QToolButton" name="tool_xdg_getCommand"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>42</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item row="3" column="2"> + <widget class="QToolButton" name="tool_xdg_getDir"> + <property name="enabled"> + <bool>true</bool> + </property> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Preferred"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>42</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + </widget> + </item> + <item row="4" column="1"> + <layout class="QHBoxLayout" name="horizontalLayout"> + <item> + <widget class="QLabel" name="label_xdg_icon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>64</width> + <height>64</height> + </size> + </property> + <property name="frameShape"> + <enum>QFrame::StyledPanel</enum> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QLineEdit" name="line_xdg_icon"/> + </item> + </layout> + </item> + <item row="4" column="2"> + <widget class="QToolButton" name="push_xdg_getIcon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Preferred" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>20000</width> + <height>42</height> + </size> + </property> + <property name="sizeIncrement"> + <size> + <width>2</width> + <height>2</height> + </size> + </property> + <property name="baseSize"> + <size> + <width>0</width> + <height>0</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + <property name="icon"> + <iconset theme="edit-find"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="iconSize"> + <size> + <width>24</width> + <height>24</height> + </size> + </property> + </widget> + </item> + </layout> + </item> + <item> + <spacer name="verticalSpacer"> + <property name="orientation"> + <enum>Qt::Vertical</enum> + </property> + <property name="sizeHint" stdset="0"> + <size> + <width>20</width> + <height>40</height> + </size> + </property> + </spacer> + </item> + <item> + <layout class="QHBoxLayout" name="horizontalLayout_2"> + <item> + <widget class="QLabel" name="label_xdg_statusicon"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Fixed" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>32</width> + <height>32</height> + </size> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + <item> + <widget class="QLabel" name="label_xdg_status"> + <property name="sizePolicy"> + <sizepolicy hsizetype="Expanding" vsizetype="Fixed"> + <horstretch>0</horstretch> + <verstretch>0</verstretch> + </sizepolicy> + </property> + <property name="minimumSize"> + <size> + <width>0</width> + <height>32</height> + </size> + </property> + <property name="maximumSize"> + <size> + <width>16777215</width> + <height>32</height> + </size> + </property> + <property name="font"> + <font> + <italic>true</italic> + </font> + </property> + <property name="text"> + <string notr="true"/> + </property> + </widget> + </item> + </layout> + </item> + <item> + <widget class="Line" name="line"> + <property name="orientation"> + <enum>Qt::Horizontal</enum> + </property> + </widget> + </item> + </layout> </widget> - </item> - </layout> - </item> - </layout> + </widget> + </item> + </layout> + </widget> + <widget class="QMenuBar" name="menubar"> + <property name="geometry"> + <rect> + <x>0</x> + <y>0</y> + <width>800</width> + <height>39</height> + </rect> + </property> + <widget class="QMenu" name="menuFile"> + <property name="title"> + <string>File</string> + </property> + <widget class="QMenu" name="menuSave_As"> + <property name="title"> + <string>Save As</string> + </property> + <property name="icon"> + <iconset theme="document-save"> + <normaloff>.</normaloff>.</iconset> + </property> + <addaction name="actionLocal_Shortcut"/> + <addaction name="actionRegister_Shortcut"/> + </widget> + <addaction name="actionNew_Shortcut"/> + <addaction name="separator"/> + <addaction name="actionOpen_File"/> + <addaction name="actionOpen_Directory"/> + <addaction name="separator"/> + <addaction name="actionSave_Shortcut"/> + <addaction name="menuSave_As"/> + <addaction name="separator"/> + <addaction name="actionQuit"/> + </widget> + <addaction name="menuFile"/> + </widget> + <widget class="QStatusBar" name="statusbar"/> + <action name="actionOpen_File"> + <property name="icon"> + <iconset theme="document-open"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Open File</string> + </property> + <property name="shortcut"> + <string>Ctrl+O</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionQuit"> + <property name="icon"> + <iconset theme="window-close"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Quit</string> + </property> + <property name="shortcut"> + <string>Ctrl+Q</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionSave_Shortcut"> + <property name="icon"> + <iconset theme="document-save"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Save Shortcut</string> + </property> + <property name="shortcut"> + <string>Ctrl+S</string> + </property> + <property name="shortcutContext"> + <enum>Qt::ApplicationShortcut</enum> + </property> + </action> + <action name="actionLocal_Shortcut"> + <property name="icon"> + <iconset theme="document-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Local Shortcut</string> + </property> + </action> + <action name="actionRegister_Shortcut"> + <property name="icon"> + <iconset theme="bookmark-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Register Shortcut</string> + </property> + </action> + <action name="actionOpen_Directory"> + <property name="icon"> + <iconset theme="folder-open"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>Open Directory</string> + </property> + </action> + <action name="actionNew_Shortcut"> + <property name="icon"> + <iconset theme="document-new"> + <normaloff>.</normaloff>.</iconset> + </property> + <property name="text"> + <string>New Shortcut</string> + </property> + </action> </widget> - <layoutdefault spacing="6" margin="11"/> - <tabstops> - <tabstop>line_xdg_name</tabstop> - <tabstop>line_xdg_comment</tabstop> - <tabstop>line_xdg_command</tabstop> - <tabstop>line_xdg_wdir</tabstop> - <tabstop>check_xdg_startupNotify</tabstop> - <tabstop>check_xdg_useTerminal</tabstop> - <tabstop>tool_xdg_getCommand</tabstop> - <tabstop>tool_xdg_getDir</tabstop> - </tabstops> <resources/> <connections/> </ui> diff --git a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro index bbaf842e..14345f50 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro +++ b/src-qt5/desktop-utils/lumina-fileinfo/lumina-fileinfo.pro @@ -1,7 +1,7 @@ include("$${PWD}/../../OS-detect.pri") QT += core gui -greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent +greaterThan(QT_MAJOR_VERSION, 4): QT += widgets concurrent multimedia TARGET = lumina-fileinfo @@ -13,6 +13,7 @@ target.path = $${L_BINDIR} include(../../core/libLumina/LUtils.pri) #includes LUtils include(../../core/libLumina/LuminaXDG.pri) #include(../../core/libLumina/LuminaSingleApplication.pri) +include(../../core/libLumina/LVideoLabel.pri) include(../../core/libLumina/LuminaThemes.pri) SOURCES += main.cpp\ diff --git a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp index a602f290..ce62399d 100644 --- a/src-qt5/desktop-utils/lumina-fileinfo/main.cpp +++ b/src-qt5/desktop-utils/lumina-fileinfo/main.cpp @@ -11,46 +11,26 @@ int main(int argc, char ** argv) { LTHEME::LoadCustomEnvSettings(); QApplication a(argc, argv); - a.setAttribute(Qt::AA_UseHighDpiPixmaps); + a.setAttribute(Qt::AA_UseHighDpiPixmaps); LUtils::LoadTranslation(&a, "l-fileinfo"); - //LuminaThemeEngine theme(&a); //Read the input variables QString path = ""; QString flag = ""; for(int i=1; i<argc; i++){ - if( QString(argv[i]).startsWith("-") ){ flag = QString(argv[i]); } - else{ path = QString(argv[i]); break; } + QString tmp(argv[i]); + if( tmp=="--new-application" ){ flag = "APP"; } + else if( tmp=="--new-link" ){ flag = "LINK"; } + else if(!tmp.startsWith("-")){ path = QString(argv[i]); break; } } //Check the input variables // - path if(!path.isEmpty()){ path = LUtils::PathToAbsolute(path); } - // - flag - if(!flag.isEmpty()){ - if(flag=="-application"){ - flag = "APP"; //for internal use - }else if(flag=="-link"){ - flag = "LINK"; //for internal use - }else{ - //Invalid flag - clear the path as well - flag.clear(); - path.clear(); - } - } - if(!path.isEmpty() || !flag.isEmpty()){ + if(path.isEmpty() && flag.isEmpty()){ flag = "APP"; } MainUI w; - //QObject::connect(&theme, SIGNAL(updateIcons()), &w, SLOT(UpdateIcons()) ); w.LoadFile(path, flag); w.show(); int retCode = a.exec(); return retCode; - }else{ - //Show an error text and exit - qDebug() << "ERROR: Invalid input arguments"; - qDebug() << "Usage: \"lumina-fileinfo [-application | -link] [file]"; - return 1; - } - - } 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(){ +} diff --git a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp index 4c2ce0bd..9e4ce499 100644 --- a/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp +++ b/src-qt5/desktop-utils/lumina-textedit/MainUI.cpp @@ -496,11 +496,14 @@ void MainUI::closeEvent(QCloseEvent *ev){ unsaved << tmp->currentFile(); } } - bool savenow = unsaved.isEmpty(); + if(unsaved.isEmpty()){ QMainWindow::closeEvent(ev); return; } + bool savenow = false; if(!savenow && !ui->actionShow_Popups->isChecked()){ savenow = true; } if(!savenow){ - savenow = (QMessageBox::Yes == QMessageBox::question(this, tr("Save Changes before closing?"), QString(tr("There are unsaved changes.\nDo you want save them before you close the editor?\n\n%1")).arg(unsaved.join("\n")), QMessageBox::Yes | QMessageBox::No, QMessageBox::No) ); + QMessageBox::StandardButton but = QMessageBox::question(this, tr("Save Changes before closing?"), QString(tr("There are unsaved changes.\nDo you want save them before you close the editor?\n\n%1")).arg(unsaved.join("\n")), QMessageBox::Yes | QMessageBox::No | QMessageBox::Cancel, QMessageBox::No); + savenow = (but == QMessageBox::Yes); + if(but == QMessageBox::Cancel){ ev->ignore(); return; } } - if(!savenow){ QMainWindow::closeEvent(ev); } - else{ ev->ignore(); SaveFile(); } + if(savenow){ SaveFile(); } + QMainWindow::closeEvent(ev); } diff --git a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp index 7b34935e..1ad6edcd 100644 --- a/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp +++ b/src-qt5/desktop-utils/lumina-xdg-entry/mainwindow.cpp @@ -1,7 +1,7 @@ //=========================================== // Copyright (c) 2017, q5sys (JT) // Available under the MIT license -// See the LICENSE file for full details +// See the LICENSE file for full details //=========================================== #include "mainwindow.h" |