aboutsummaryrefslogtreecommitdiff
path: root/lumina-fm/widgets/DirWidget.cpp
diff options
context:
space:
mode:
authorKen Moore <moorekou@gmail.com>2015-08-25 15:43:53 -0400
committerKen Moore <moorekou@gmail.com>2015-08-25 15:43:53 -0400
commit88507c36076b100e26a8e2c85533d667675f9daa (patch)
tree53fc42d5b8b83924e19aa5d6618dae446ba698a4 /lumina-fm/widgets/DirWidget.cpp
parentDisable the "size" output of a directory in lumina-fm: this needs some better... (diff)
downloadlumina-88507c36076b100e26a8e2c85533d667675f9daa.tar.gz
lumina-88507c36076b100e26a8e2c85533d667675f9daa.tar.bz2
lumina-88507c36076b100e26a8e2c85533d667675f9daa.zip
Commit a major overhaul of lumina-fm: PLEASE TEST!!
1) Seemlessly embed the ZFS rollback options into the main dir browser (simple time slider at the top). 2) Take all the main widgets and put them into separate classes/files (widgets/*) 3) Add support for both tabs and columns for multiple directory viewing 4) Remove the "icon" view mode, and replace it with an icon sizing option (larger/smaller) 5) Add the ability for the multimedia player and slideshow viewer to be running within separate tabs while still browsing the system (new files will be added to the queue instead of replacing it) 6) Ensure that only selected files are added to the player/slideshow on demand. 7) Add the ability to zoom in/out on a slideshow image. KNOWN ISSUES: 1) The new file/dir functionality has not been replaced/re-implemented yet. 2) The drag and drop functionality has been removed until a new implementation is put in. PLEASE TEST: ZFS snapshot use, multimedia file player, browsing and other UI changes
Diffstat (limited to 'lumina-fm/widgets/DirWidget.cpp')
-rw-r--r--lumina-fm/widgets/DirWidget.cpp269
1 files changed, 224 insertions, 45 deletions
diff --git a/lumina-fm/widgets/DirWidget.cpp b/lumina-fm/widgets/DirWidget.cpp
index b32e5c20..775a252b 100644
--- a/lumina-fm/widgets/DirWidget.cpp
+++ b/lumina-fm/widgets/DirWidget.cpp
@@ -19,9 +19,36 @@
DirWidget::DirWidget(QString objID, QWidget *parent) : QWidget(parent), ui(new Ui::DirWidget){
ui->setupUi(this); //load the designer file
ID = objID;
+ //Assemble the toolbar for the widget
+ toolbar = new QToolBar(this);
+ toolbar->setContextMenuPolicy(Qt::CustomContextMenu);
+ toolbar->setFloatable(false);
+ toolbar->setMovable(false);
+ toolbar->setOrientation(Qt::Horizontal);
+ toolbar->setToolButtonStyle(Qt::ToolButtonIconOnly);
+ //toolbar->setIconSize(QSize(32,32));
+ ui->toolbar_layout->addWidget(toolbar);
+ // - Add the buttons to the toolbar
+ toolbar->addAction(ui->actionBack);
+ toolbar->addAction(ui->actionUp);
+ toolbar->addAction(ui->actionHome);
+ line_dir = new QLineEdit(this);
+ toolbar->addWidget(line_dir);
+ toolbar->addAction(ui->actionStopLoad);
+ toolbar->addAction(ui->actionClose_Browser);
+ //Create the keyboard shortcuts
+ copyFilesShort = new QShortcut( QKeySequence(tr("Ctrl+C")), this);
+ pasteFilesShort = new QShortcut( QKeySequence(tr("Ctrl+V")), this);
+ cutFilesShort = new QShortcut( QKeySequence(tr("Ctrl+X")), this);
+ deleteFilesShort = new QShortcut( QKeySequence(tr("Delete")), this);
+ refreshShort = new QShortcut( QKeySequence(tr("F5")), this);
+ //Create the filesystem watcher
+ watcher = new QFileSystemWatcher(this);
+ //Now update the rest of the UI
canmodify = false; //initial value
contextMenu = new QMenu(this);
setShowDetails(true);
+ setShowThumbnails(true);
UpdateIcons();
UpdateText();
setupConnections();
@@ -31,24 +58,71 @@ DirWidget::~DirWidget(){
}
+void DirWidget::ChangeDir(QString dirpath){
+ emit LoadDirectory(ID, dirpath);
+}
+
+void DirWidget::setDirCompleter(QCompleter *comp){
+ line_dir->setCompleter(comp);
+}
+
QString DirWidget::id(){
return ID;
}
+QString DirWidget::currentDir(){
+ return CDIR;
+}
+
void DirWidget::setShowDetails(bool show){
showDetails = show;
ui->listWidget->setVisible(!showDetails);
ui->treeWidget->setVisible(showDetails);
+ this->refresh();
}
void DirWidget::setShowSidebar(bool show){
ui->group_actions->setVisible(show);
}
+void DirWidget::setShowThumbnails(bool show){
+ showThumbs = show;
+ this->refresh();
+}
+
void DirWidget::setDetails(QList<DETAILTYPES> list){
listDetails = list;
+ //Need to re-create the header item as well
+ QTreeWidgetItem *it = new QTreeWidgetItem();
+ int nmcol = -1; int typecol = -1;
+ for(int t=0; t<listDetails.length(); t++){
+ switch(listDetails[t]){
+ case NAME:
+ it->setText(t,tr("Name"));
+ nmcol = t;
+ break;
+ case SIZE:
+ it->setText(t,tr("Size"));
+ break;
+ case TYPE:
+ it->setText(t, tr("Type"));
+ typecol = t;
+ break;
+ case DATEMOD:
+ it->setText(t, tr("Date Modified") );
+ break;
+ case DATECREATE:
+ it->setText(t, tr("Date Created") );
+ break;
+ }
+ }
+ ui->treeWidget->setHeaderItem(it);
+ //Now reset the sorting (alphabetically, dirs first)
+ if(nmcol>=0){ ui->treeWidget->sortItems(nmcol, Qt::AscendingOrder); } // sort by name
+ if(typecol>=0){ ui->treeWidget->sortItems(typecol, Qt::AscendingOrder); } //sort by type first
+
if(CDIR.isEmpty() || !showDetails){ return; } //don't need to reload dir if details are not visible
- emit LoadDirectory(ID, CDIR);
+ this->refresh();
}
void DirWidget::setThumbnailSize(int px){
@@ -56,17 +130,25 @@ void DirWidget::setThumbnailSize(int px){
ui->listWidget->setIconSize(QSize(px,px));
ui->treeWidget->setIconSize(QSize(px,px));
if(CDIR.isEmpty() || !larger ){ return; } //don't need to reload icons unless the new size is larger
- emit LoadDirectory(ID, CDIR);
+ this->refresh();
+}
+
+void DirWidget::setShowCloseButton(bool show){
+ ui->actionClose_Browser->setVisible(show);
}
+
// ================
// PUBLIC SLOTS
// ================
void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
if(dir.isEmpty()){ return; } //nothing to do
+ qDebug() << "Load Dir:" << dir;
QString lastdir = CDIR; //for some checks later
- canmodify = QFileInfo(CDIR).isWritable();
- CLIST = list; //save for later
+ QString lastbasedir = normalbasedir;
CDIR = dir;
+ if(CDIR.endsWith("/")){ CDIR.chop(1); }
+ CLIST = list; //save for laterr
+ canmodify = QFileInfo(CDIR).isWritable();
//Hide the extra buttons for a moment
ui->tool_goToPlayer->setVisible(false);
ui->tool_goToImages->setVisible(false);
@@ -75,7 +157,10 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
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
+ if(snaprelpath.endsWith("/")){ snaprelpath.chop(1); }
normalbasedir = dir.section(ZSNAPDIR,0,0)+"/"+snaprelpath; //Update the new base directory
+ if(normalbasedir.endsWith("/")){ normalbasedir.chop(1); }
+ line_dir->setText(normalbasedir);
//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)){
@@ -83,7 +168,8 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
}
}else{
//This is a normal directory - prompt for snapshot information
- normalbasedir = dir;
+ line_dir->setText(CDIR);
+ normalbasedir = CDIR;
snapbasedir.clear();
loadsnaps = true;
}
@@ -94,37 +180,32 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
ui->slider_snap->setRange(1,1);
emit findSnaps(ID, normalbasedir);
}
+ //Now update the history for this browser
+ if(!history.isEmpty() && history.last() == normalbasedir && lastbasedir!=normalbasedir ){
+ //We went back one - remove this from the history
+ history.takeLast();
+ ui->actionBack->setEnabled(!history.isEmpty());
+ }else if(lastbasedir!=normalbasedir){ //not a refresh or internal snapshot change
+ history << normalbasedir;
+ ui->actionBack->setEnabled(history.length()>1);
+ }
+ //Clear the current watcher
+ if(!watcher->directories().isEmpty()){ watcher->removePaths(watcher->directories()); }
+ if(!watcher->files().isEmpty()){ watcher->removePaths(watcher->files()); }
+ watcher->addPath(CDIR);
+ ui->actionStopLoad->setVisible(true);
+ stopload = false;
//Clear the display widget
- if(showDetails){
- ui->treeWidget->clear();
- //Need to re-create the header item as well
- QTreeWidgetItem *it = new QTreeWidgetItem();
- for(int t=0; t<listDetails.length(); t++){
- 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(); }
+ if(showDetails){ ui->treeWidget->clear(); }
+ else{ ui->listWidget->clear(); }
//Now fill the display widget
bool hasimages, hasmultimedia;
hasimages = hasmultimedia = false;
for(int i=0; i<list.length(); i++){
+ if(stopload){ ui->actionStopLoad->setVisible(false); return; } //stop right now
hasimages = hasimages || list[i].isImage();
hasmultimedia = hasmultimedia || list[i].isAVFile();
+ //watcher->addPath(list[i].absoluteFilePath());
if(showDetails){
//Now create all the individual items for the details tree
QTreeWidgetItem *it = new QTreeWidgetItem();
@@ -133,8 +214,10 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
switch(listDetails[t]){
case NAME:
it->setText(t,list[i].fileName());
+ it->setStatusTip(t, list[i].fileName());
if(list[i].isImage()){
- it->setIcon(t, QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->treeWidget->iconSize().height()) ) );
+ if(showThumbs){ it->setIcon(t, QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->treeWidget->iconSize().height()) ) ); }
+ else{ it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
}else{
it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"unknown") );
}
@@ -146,6 +229,7 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
break;
case TYPE:
it->setText(t, list[i].mimetype());
+ break;
case DATEMOD:
it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) );
break;
@@ -164,8 +248,10 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
QListWidgetItem *it = new QListWidgetItem();
it->setWhatsThis(list[i].fileName());
it->setText(list[i].fileName());
+ it->setStatusTip(list[i].fileName());
if(list[i].isImage()){
- it->setIcon(QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->listWidget->iconSize().height()) ) );
+ if(showThumbs){ it->setIcon(QIcon( QPixmap(list[i].absoluteFilePath()).scaledToHeight(ui->treeWidget->iconSize().height()) ) ); }
+ else{ it->setIcon(LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
}else{
it->setIcon(LXDG::findIcon(list[i].iconfile(),"unknown") );
}
@@ -177,15 +263,19 @@ void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
}
QApplication::processEvents(); //keep the UI snappy while loading a directory
}
+ ui->actionStopLoad->setVisible(false);
//Another check to ensure the current item is visible
if(showDetails){
if(ui->treeWidget->currentItem()!=0){ ui->treeWidget->scrollToItem(ui->treeWidget->currentItem()); }
+ for(int t=0; t<ui->treeWidget->columnCount(); t++){ui->treeWidget->resizeColumnToContents(t); }
}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);
+ ui->tool_goToPlayer->setVisible(hasmultimedia);
+ ui->tool_goToImages->setVisible(hasimages);
+ if(canmodify){ ui->label_status->setText(""); }
+ else{ ui->label_status->setText(tr("Restricted Access")); }
}
void DirWidget::LoadSnaps(QString basedir, QStringList snaps){
@@ -211,6 +301,17 @@ void DirWidget::LoadSnaps(QString basedir, QStringList snaps){
}
+void DirWidget::refresh(){
+ if(!CDIR.isEmpty() && ~ID.isEmpty()){
+ stopload = true; //just in case it is still loading
+ emit LoadDirectory(ID, CDIR);
+ }
+}
+
+void DirWidget::refreshButtons(){
+ SelectionChanged();
+}
+
//Theme change functions
void DirWidget::UpdateIcons(){
//ui->tool_addNewFile->setIcon( LXDG::findIcon("document-new",""));
@@ -231,6 +332,12 @@ 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","") );
+ //ToolBar Buttons
+ ui->actionBack->setIcon( LXDG::findIcon("go-previous","") );
+ ui->actionUp->setIcon( LXDG::findIcon("go-up","") );
+ ui->actionHome->setIcon( LXDG::findIcon("go-home","") );
+ ui->actionStopLoad->setIcon( LXDG::findIcon("dialog-cancel","") );
+ ui->actionClose_Browser->setIcon( LXDG::findIcon("dialog-close","") );
}
void DirWidget::UpdateText(){
@@ -252,13 +359,19 @@ void DirWidget::setupConnections(){
connect(ui->listWidget, SIGNAL(itemSelectionChanged()), this, SLOT(SelectionChanged()) );
//Activation routines
- connect(ui->treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*)), this, SLOT(on_tool_act_run_clicked()) );
+ connect(ui->treeWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(on_tool_act_run_clicked()) );
connect(ui->listWidget, SIGNAL(itemActivated(QListWidgetItem*)), this, SLOT(on_tool_act_run_clicked()) );
- connect(ui->treeWidget, SIGNAL(itemDoubleClicked(QTreeWidgetItem*)), this, SLOT(on_tool_act_run_clicked()) );
- connect(ui->listWidget, SIGNAL(itemDoubleClicked(QListWidgetItem*)), this, SLOT(on_tool_act_run_clicked()) );
+ connect(line_dir, SIGNAL(returnPressed()), this, SLOT(dir_changed()) );
-
-
+ //Keyboard Shortcuts
+ connect(copyFilesShort, SIGNAL(activated()), this, SLOT( on_tool_act_copy_clicked() ) );
+ connect(cutFilesShort, SIGNAL(activated()), this, SLOT( on_tool_act_cut_clicked() ) );
+ connect(pasteFilesShort, SIGNAL(activated()), this, SLOT( on_tool_act_paste_clicked() ) );
+ connect(deleteFilesShort, SIGNAL(activated()), this, SLOT( on_tool_act_rm_clicked() ) );
+ connect(refreshShort, SIGNAL(activated()), this, SLOT( refresh()) );
+ //Filesystem Watcher
+ connect(watcher, SIGNAL(directoryChanged(const QString&)), this, SLOT(refresh()) );
+ connect(watcher, SIGNAL(fileChanged(const QString&)), this, SLOT(refresh()) ); //just in case
}
QStringList DirWidget::currentSelection(){
@@ -352,11 +465,33 @@ void DirWidget::on_tool_act_runwith_clicked(){
// -- Bottom Action Buttons
void DirWidget::on_tool_goToImages_clicked(){
- emit ViewFiles(CLIST);
+ QStringList sel = currentSelection();
+ if(sel.isEmpty()){ emit ViewFiles(CLIST); }
+ else{
+ //Just use the files from the current selection
+ LFileInfoList list;
+ for(int i=0; i<CLIST.length(); i++){
+ if(CLIST[i].isImage() && sel.contains(CLIST[i].fileName()) ){
+ list << CLIST[i]; //add to the list
+ }
+ }
+ if(!list.isEmpty()){ emit ViewFiles(list); }
+ }
}
void DirWidget::on_tool_goToPlayer_clicked(){
- emit PlayFiles(CLIST);
+ QStringList sel = currentSelection();
+ if(sel.isEmpty()){ emit PlayFiles(CLIST); }
+ else{
+ //Just use the files from the current selection
+ LFileInfoList list;
+ for(int i=0; i<CLIST.length(); i++){
+ if(CLIST[i].isAVFile() && sel.contains(CLIST[i].fileName()) ){
+ list << CLIST[i]; //add to the list
+ }
+ }
+ if(!list.isEmpty()){ emit PlayFiles(list); }
+ }
}
// -- Top Snapshot Buttons
@@ -381,29 +516,73 @@ void DirWidget::on_slider_snap_valueChanged(int val){
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;
+ //qDebug() << "Changing snapshot:" << CDIR << val;
+ stopload = true; //stop any currently-loading procedures
if(val >= snapshots.length() || val < 0){ //active system selected
- qDebug() << " - Load Active system:" << normalbasedir;
+ //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;
+ //qDebug() << " - new snapshot-relative path:" << snaprelpath;
}
dir.append(snaprelpath);
- qDebug() << " - Load Snapshot:" << dir;
+ dir.replace("//","/"); //just in case any duplicate slashes from all the split/combining
+ //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
+ dir = dir.section("/",0,-2); //back up one dir
}
if(dir.isEmpty()){ return; }
//Load the newly selected snapshot
emit LoadDirectory(ID, dir);
}
+//Top Toolbar buttons
+void DirWidget::on_actionBack_triggered(){
+ if(history.isEmpty()){ return; } //cannot do anything
+ QString dir = history.takeLast();
+ if(dir == normalbasedir){
+ dir = history.last();
+ }
+ emit LoadDirectory(ID, dir);
+}
+
+void DirWidget::on_actionUp_triggered(){
+ QString dir = CDIR.section("/",0,-2);
+ //Quick check to ensure the directory exists
+ while(!QFile::exists(dir) && !dir.isEmpty()){
+ dir = dir.section("/",0,-2); //back up one additional dir
+ }
+ emit LoadDirectory(ID, dir);
+}
+
+void DirWidget::on_actionHome_triggered(){
+ emit LoadDirectory(ID, QDir::homePath());
+}
+
+void DirWidget::on_actionStopLoad_triggered(){
+ stopload = true;
+ ui->actionStopLoad->setVisible(false);
+}
+
+void DirWidget::dir_changed(){
+ QString dir = line_dir->text();
+ //Quick check to ensure the directory exists
+ while(!QFile::exists(dir) && !dir.isEmpty()){
+ dir = dir.section("/",0,-2); //back up one additional dir
+ }
+ emit LoadDirectory(ID, dir);
+}
+
+void DirWidget::on_actionClose_Browser_triggered(){
+ emit CloseBrowser(ID);
+}
+
// - Other Actions without a specific button on the side
void DirWidget::fileCheckSums(){
QStringList files = currentSelection();
bgstack15