diff options
author | Ken Moore <moorekou@gmail.com> | 2015-08-20 17:04:12 -0400 |
---|---|---|
committer | Ken Moore <moorekou@gmail.com> | 2015-08-20 17:04:12 -0400 |
commit | a233a037540b965d2c3b8be0b75bf021a0a9a795 (patch) | |
tree | 19fe2b4ed8464a16126db3cb3959afd5b4ff2aef /lumina-fm/widgets/DirWidget.cpp | |
parent | Fix a bug in the color dialog title, it can be used for more than just panels... (diff) | |
download | lumina-a233a037540b965d2c3b8be0b75bf021a0a9a795.tar.gz lumina-a233a037540b965d2c3b8be0b75bf021a0a9a795.tar.bz2 lumina-a233a037540b965d2c3b8be0b75bf021a0a9a795.zip |
Another checkpoint in the lumina-fm backend overhaul - still not tied into the general build/use yet.
Diffstat (limited to 'lumina-fm/widgets/DirWidget.cpp')
-rw-r--r-- | lumina-fm/widgets/DirWidget.cpp | 336 |
1 files changed, 314 insertions, 22 deletions
diff --git a/lumina-fm/widgets/DirWidget.cpp b/lumina-fm/widgets/DirWidget.cpp index 75a0bc79..8e7e3b0e 100644 --- a/lumina-fm/widgets/DirWidget.cpp +++ b/lumina-fm/widgets/DirWidget.cpp @@ -7,8 +7,20 @@ #include "DirWidget.h" #include "ui_DirWidget.h" +#include <QMessageBox> +#include <QCursor> +#include <QClipboard> +#include <QMimeData> + +#include <LuminaOS.h> +#include <LuminaXDG.h> +#include <LuminaUtils.h> + DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){ ui->setupUi(this); //load the designer file + ID = objID; + canmodify = false; //initial value + contextMenu = new QMenu(this); setShowDetails(true); UpdateIcons(); UpdateText(); @@ -30,12 +42,12 @@ void DirWidget::setShowDetails(bool show){ } void DirWidget::setShowSidebar(bool show){ - this->stacked_actions->setVisible(show); + ui->group_actions->setVisible(show); } void DirWidget::setDetails(QList<DETAILTYPES> list){ listDetails = list; - LoadDir(CDIR, CLIST); //just refresh the UI + emit LoadDirectory(ID, CDIR); } // ================ @@ -43,15 +55,19 @@ void DirWidget::setDetails(QList<DETAILTYPES> list){ // ================ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){ if(dir.isEmpty()){ return; } //nothing to do + QString lastdir = CDIR; //for some checks later + canmodify = QFileInfo(CDIR).isWritable(); CLIST = list; //save for later CDIR = dir; + //Hide the extra buttons for a moment + ui->tool_goToPlayer->setVisible(false); + ui->tool_goToImages->setVisible(false); //Determine if this is an internal ZFS snapshot bool loadsnaps = false; if( dir.contains(ZSNAPDIR) ){ //This is a zfs snapshot - only update the saved paths necessary to rotate between snapshots/system snaprelpath = dir.section(ZSNAPDIR,1,1000).section("/",1,1000); //the relative path inside the snapshot normalbasedir = dir.section(ZSNAPDIR,0,0)+"/"+snaprelpath; //Update the new base directory - ui->stacked_actions->setCurrentWidget(ui->page_restore); //See if this was a manual move to the directory, or an internal move QString tmp = dir.section(ZSNAPDIR,0,0); if(tmp != snapbasedir.section(ZSNAPDIR,0,0)){ @@ -61,7 +77,6 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){ //This is a normal directory - prompt for snapshot information normalbasedir = dir; snapbasedir.clear(); - ui->stacked_actions->setCurrentWidget(ui->page_dir); loadsnaps = true; } if(loadsnaps){ @@ -77,22 +92,41 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){ //Need to re-create the header item as well QTreeWidgetItem *it = new QTreeWidgetItem(); for(int t=0; t<listDetails.length(); t++){ - it-> + switch(listDetails[t]){ + case NAME: + it->setText(t,tr("Name")); + break; + case SIZE: + it->setText(t,tr("Size")); + break; + case TYPE: + it->setText(t, tr("Type")); + case DATEMOD: + it->setText(t, tr("Date Modified") ); + break; + case DATECREATE: + it->setText(t, tr("Date Created") ); + break; + } } ui->treeWidget->setHeaderItem(it); }else{ ui->listWidget->clear(); } //Now fill the display widget + bool hasimages, hasmultimedia; + hasimages = hasmultimedia = false; for(int i=0; i<list.length(); i++){ + hasimages = hasimages || list[i].isImage(); + hasmultimedia = hasmultimedia || list[i].isAVFile(); if(showDetails){ - //Now create all the individual items + //Now create all the individual items for the details tree QTreeWidgetItem *it = new QTreeWidgetItem(); - it->setWhatsThis(list[i].fileName()); + it->setWhatsThis(0, list[i].fileName()); for(int t=0; t<listDetails.length(); t++){ switch(listDetails[t]){ case NAME: it->setText(t,list[i].fileName()); if(list[i].isImage()){ - it->setIcon(t, QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(64) ) ); + it->setIcon(t, QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->treeWidget->iconSize().height()) ) ); }else{ it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"unknown") ); } @@ -105,19 +139,45 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){ case TYPE: it->setText(t, list[i].mimetype()); case DATEMOD: - it->setText(t, list[i].lastModified().toString(Qt:DefaultLocaleShortDate); + it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) ); break; case DATECREATE: - it->setText(t, list[i].created().toString(Qt:DefaultLocaleShortDate); + it->setText(t, list[i].created().toString(Qt::DefaultLocaleShortDate) ); break; } } ui->treeWidget->addTopLevelItem(it); + if(lastdir == CDIR+"/"+it->whatsThis(0)){ + ui->treeWidget->setCurrentItem(it); + ui->treeWidget->scrollToItem(it); + } }else{ - + //Create all the individual items for the basic list + QListWidgetItem *it = new QListWidgetItem(); + it->setWhatsThis(list[i].fileName()); + it->setText(list[i].fileName()); + if(list[i].isImage()){ + it->setIcon(QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->listWidget->iconSize().height()) ) ); + }else{ + it->setIcon(LXDG::findIcon(list[i].iconfile(),"unknown") ); + } + ui->listWidget->addItem(it); + if(lastdir == CDIR+"/"+it->whatsThis()){ + ui->listWidget->setCurrentItem(it); + ui->listWidget->scrollToItem(it); + } } QApplication::processEvents(); //keep the UI snappy while loading a directory } + //Another check to ensure the current item is visible + if(showDetails){ + if(ui->treeWidget->currentItem()!=0){ ui->treeWidget->scrollToItem(ui->treeWidget->currentItem()); } + }else{ + if(ui->listWidget->currentItem()!=0){ ui->listWidget->scrollToItem(ui->listWidget->currentItem()); } + } + //Now Re-enable buttons as necessary + ui->tool_goToPlayer->setVisible(hasimages); + ui->tool_goToImages->setVisible(hasmultimedia); } void DirWidget::LoadSnaps(QString basedir, QStringList snaps){ @@ -126,12 +186,12 @@ void DirWidget::LoadSnaps(QString basedir, QStringList snaps){ snapshots = snaps; //Now update the UI as necessary - ui->slider_snap->setRange(1, snaps.length()+1); + ui->slider_snap->setRange(0, snaps.length()); if(CDIR.contains(ZSNAPDIR)){ //The user was already within a snapshot - figure out which one and set the slider appropriately int index = snaps.indexOf( CDIR.section(ZSNAPDIR,1,1).section("/",0,0) ); if(index < 0){ index = snaps.length()+1; } //unknown - load the system (should never happen) - ui->slider_snap_setValue(index); + ui->slider_snap->setValue(index); }else{ ui->slider_snap->setValue(snaps.length()+1); //last item (normal system) } @@ -151,7 +211,7 @@ void DirWidget::UpdateIcons(){ //Snapshot buttons ui->tool_snap_newer->setIcon(LXDG::findIcon("go-next-view","") ); ui->tool_snap_older->setIcon(LXDG::findIcon("go-previous-view","") ); - //Botton-Action Buttons + //Bottom-Action Buttons ui->tool_goToImages->setIcon( LXDG::findIcon("fileview-preview","") ); ui->tool_goToPlayer->setIcon( LXDG::findIcon("applications-multimedia","") ); //Side-Action Buttons @@ -163,29 +223,261 @@ void DirWidget::UpdateIcons(){ ui->tool_act_rename->setIcon( LXDG::findIcon("edit-rename","") ); ui->tool_act_rm->setIcon( LXDG::findIcon("edit-delete","") ); ui->tool_act_fav->setIcon( LXDG::findIcon("bookmark-toolbar","") ); - //Restore-Action Buttons - ui->tool_restore->setIcon( LXDG::findIcon("document-revert","") ); - ui->tool_restore_over->setIcon( LXDG::findIcon("document-revert","") ); } void DirWidget::UpdateText(){ ui->retranslateUi(this); } +void DirWidget::UpdateButtons(){ + SelectionChanged(); +} // ================= // PRIVATE // ================= void DirWidget::setupConnections(){ //Tree Widget interaction - connect(ui->tree_dir_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ItemRun(const QModelIndex&)) ); + connect(ui->treeWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu()) ); + connect(ui->listWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu()) ); + connect(ui->treeWidget, SIGNAL(itemSelectionChanged()), this, SLOT(SelectionChanged()) ); + connect(ui->listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(SelectionChanged()) ); + + /*connect(ui->tree_dir_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ItemRun(const QModelIndex&)) ); connect(ui->list_dir_view, SIGNAL(activated(const QModelIndex&)), this, SLOT(ItemRun(const QModelIndex&)) ); - connect(ui->tree_dir_view, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu(const QPoint&)) ); - connect(ui->list_dir_view, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(OpenContextMenu(const QPoint&)) ); connect(ui->tree_dir_view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(ItemSelectionChanged()) ); - connect(ui->list_dir_view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(ItemSelectionChanged()) ); + connect(ui->list_dir_view->selectionModel(), SIGNAL(selectionChanged(const QItemSelection, const QItemSelection)), this, SLOT(ItemSelectionChanged()) );*/ + + +} + +QStringList DirWidget::currentSelection(){ + QStringList out; + if(showDetails){ + QList<QTreeWidgetItem*> sel = ui->treeWidget->selectedItems(); + for(int i=0; i<sel.length(); i++){ + out << sel[i]->whatsThis(0); + } + }else{ + QList<QListWidgetItem*> sel = ui->listWidget->selectedItems(); + for(int i=0; i<sel.length(); i++){ + out << sel[i]->whatsThis(); + } + } + out.removeDuplicates(); + return out; } // ================= // PRIVATE SLOTS -// =================
\ No newline at end of file +// ================= +//UI BUTTONS +// -- Left Action Buttons +void DirWidget::on_tool_act_cut_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ sel[i] = CDIR+"/"+sel[i]; } //use absolute paths + emit CutFiles(sel); +} + +void DirWidget::on_tool_act_copy_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ sel[i] = CDIR+"/"+sel[i]; } //use absolute paths + emit CopyFiles(sel); +} + +void DirWidget::on_tool_act_fav_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ sel[i] = CDIR+"/"+sel[i]; } //use absolute paths + emit FavoriteFiles(sel); +} + +void DirWidget::on_tool_act_paste_clicked(){ + emit PasteFiles(CDIR); +} + +void DirWidget::on_tool_act_rename_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ sel[i] = CDIR+"/"+sel[i]; } //use absolute paths + emit RenameFiles(sel); +} + +void DirWidget::on_tool_act_rm_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ sel[i] = CDIR+"/"+sel[i]; } //use absolute paths + emit RemoveFiles(sel); +} + +void DirWidget::on_tool_act_run_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + QStringList dirs; + for(int i=0; i<sel.length(); i++){ + sel[i] = CDIR+"/"+sel[i]; //use absolute paths + if(QFileInfo(sel[i]).isDir()){ + dirs << sel[i]; + }else{ + QProcess::startDetached("lumina-open \""+sel[i]+"\""); + } + } + if(!dirs.isEmpty()){ + emit LoadDirectory(ID, dirs.takeFirst()); //load the first directory in this widget + } + if(!dirs.isEmpty()){ + emit OpenDirectories(dirs); + } +} + +void DirWidget::on_tool_act_runwith_clicked(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + for(int i=0; i<sel.length(); i++){ + QProcess::startDetached("lumina-open -select \""+CDIR+"/"+sel[i]+"\""); //use absolute paths + } +} + +// -- Bottom Action Buttons +void DirWidget::on_tool_goToImages_clicked(){ + emit ViewFiles(CLIST); +} + +void DirWidget::on_tool_goToPlayer_clicked(){ + emit PlayFiles(CLIST); +} + +// -- Top Snapshot Buttons +void DirWidget::on_tool_snap_newer_clicked(){ + ui->slider_snap->setValue( ui->slider_snap->value()+1 ); +} + +void DirWidget::on_tool_snap_older_clicked(){ + ui->slider_snap->setValue( ui->slider_snap->value()-1 ); +} + +void DirWidget::on_slider_snap_valueChanged(int val){ + //Update the snapshot interface + ui->tool_snap_newer->setEnabled(val < ui->slider_snap->maximum()); + ui->tool_snap_older->setEnabled(val > ui->slider_snap->minimum()); + if(val >= snapshots.length() || val < 0){ + ui->label_snap->setText(tr("Current")); + }else{ + ui->label_snap->setText( QFileInfo(snapbasedir+snapshots[val]).created().toString(Qt::DefaultLocaleShortDate) ); + } + //Exit if a non-interactive snapshot change + if(!ui->group_snaps->isEnabled()){ return; } //internal change - do not try to change the actual info + //Determine which snapshot is now selected + QString dir; + qDebug() << "Changing snapshot:" << CDIR << val; + if(val >= snapshots.length() || val < 0){ //active system selected + qDebug() << " - Load Active system:" << normalbasedir; + dir = normalbasedir; + }else{ + dir = snapbasedir+snapshots[val]+"/"; + if(snaprelpath.isEmpty()){ + //Need to figure out the relative path within the snapshot + snaprelpath = CDIR.section(snapbasedir.section(ZSNAPDIR,0,0), 1,1000); + qDebug() << " - new snapshot-relative path:" << snaprelpath; + } + dir.append(snaprelpath); + qDebug() << " - Load Snapshot:" << dir; + } + //Make sure this directory exists, and back up as necessary + while(!QFile::exists(dir) && !dir.isEmpty()){ + dir = dir.section("/",0,-1); //back up one dir + } + if(dir.isEmpty()){ return; } + //Load the newly selected snapshot + emit LoadDirectory(ID, dir); +} + +// - Other Actions without a specific button on the side +void DirWidget::fileCheckSums(){ + QStringList files = currentSelection(); + if(files.isEmpty()){ return; } + for(int i=0; i<files.length(); i++){ files[i] = CDIR+"/"+files[i]; } //use absolute paths + qDebug() << "Run Checksums:" << files; + QStringList info = LOS::Checksums(files); + qDebug() << " - Info:" << info; + if(info.isEmpty() || (info.length() != files.length()) ){ return; } + for(int i=0; i<info.length(); i++){ + info[i] = QString("%2 \t(%1)").arg(files[i].section("/",-1), info[i]); + } + /*QMessageBox dlg(this); + dlg.setWindowFlags( Qt::Dialog ); + dlg.setWindowTitle( tr("File Checksums") ); + dlg.setDetailedText(info.join("\n")); + dlg.exec();*/ + QMessageBox::information(this, tr("File Checksums"), info.join("\n") ); +} + +void DirWidget::fileProperties(){ + QStringList sel = currentSelection(); + if(sel.isEmpty()){ return; } + if(!LUtils::isValidBinary("lumina-fileinfo")){ + //It should never get to this point due to checks earlier - but just in case... + QMessageBox::warning(this, tr("Missing Utility"), tr("The \"lumina-fileinfo\" utility could not be found on the system. Please install it first.") ); + return; + } + for(int i=0; i<sel.length(); i++){ + QProcess::startDetached("lumina-fileinfo \""+CDIR+"/"+sel[i]+"\""); //use absolute paths + } +} + +void DirWidget::openTerminal(){ + emit LaunchTerminal(CDIR); +} + +void DirWidget::NewFile(){ + +} + +void DirWidget::NewDir(){ + +} + +//Browser Functions +void DirWidget::OpenContextMenu(){ + //First generate the context menu based on the selection + QStringList sel = currentSelection(); + contextMenu->clear(); + if(!sel.isEmpty()){ + contextMenu->addAction(LXDG::findIcon("run-build-file",""), tr("Open"), this, SLOT(on_tool_act_run_clicked()) ); + contextMenu->addAction(LXDG::findIcon("run-build-configure",""), tr("Open With..."), this, SLOT(on_tool_act_runwith_clicked()) ); + + contextMenu->addAction(LXDG::findIcon("edit-rename",""), tr("Rename"), this, SLOT(on_tool_act_rename_clicked()) )->setEnabled(canmodify); + contextMenu->addAction(LXDG::findIcon("document-encrypted",""), tr("View Checksums"), this, SLOT(fileCheckSums()) ); + contextMenu->addSeparator(); + } + //Now add the general selection options + contextMenu->addAction(LXDG::findIcon("edit-cut",""), tr("Cut Selection"), this, SLOT(on_tool_act_cut_clicked()) )->setEnabled(canmodify && !sel.isEmpty()); + contextMenu->addAction(LXDG::findIcon("edit-copy",""), tr("Copy Selection"), this, SLOT(on_tool_act_copy_clicked()) )->setEnabled(!sel.isEmpty()); + contextMenu->addAction(LXDG::findIcon("edit-paste",""), tr("Paste"), this, SLOT(on_tool_act_paste_clicked()) )->setEnabled(QApplication::clipboard()->mimeData()->hasFormat("x-special/lumina-copied-files") && canmodify); + contextMenu->addSeparator(); + contextMenu->addAction(LXDG::findIcon("edit-delete",""), tr("Delete Selection"), this, SLOT(on_tool_act_rm_clicked()) )->setEnabled(canmodify&&!sel.isEmpty()); + if(LUtils::isValidBinary("lumina-fileinfo")){ + contextMenu->addSeparator(); + contextMenu->addAction(LXDG::findIcon("edit-find-replace",""), tr("File Properties"), this, SLOT(fileProperties()) )->setEnabled(!sel.isEmpty()); + } + contextMenu->addSeparator(); + contextMenu->addAction(LXDG::findIcon("system-search",""), tr("Open Terminal here"), this, SLOT(openTerminal())); + + //Now open the menu at the current cursor location + contextMenu->popup(QCursor::pos()); +} + +void DirWidget::SelectionChanged(){ + //Go through and enable/disable the buttons as necessary + bool hasselection = !currentSelection().isEmpty(); + ui->tool_act_copy->setEnabled(hasselection); + ui->tool_act_cut->setEnabled(hasselection && canmodify); + ui->tool_act_fav->setEnabled(hasselection); + ui->tool_act_paste->setEnabled(canmodify && QApplication::clipboard()->mimeData()->hasFormat("x-special/lumina-copied-files") ); + ui->tool_act_rename->setEnabled(hasselection && canmodify); + ui->tool_act_rm->setEnabled(hasselection && canmodify); + ui->tool_act_run->setEnabled(hasselection); + ui->tool_act_runwith->setEnabled(hasselection); +} |