//=========================================== // Lumina-DE source code // Copyright (c) 2014-2015, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "MainUI.h" #include "ui_MainUI.h" #include #include "gitCompat.h" #include "gitWizard.h" #include #include #include #include #define DEBUG 0 bool rootmode = false; MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ //for Signal/slot we must register the Typedef of QFileInfoList //qRegisterMetaType("QFileInfoList"); qRegisterMetaType< LFileInfoList >("LFileInfoList"); //just to silence/fix some Qt connect warnings in QtConcurrent //qRegisterMetaType< QVector >("QVector"); //qRegisterMetaType< QList >("QList"); waitingToClose = false; //put if statement here to check if running as root rootmode = (getuid()==0); ui->setupUi(this); if(DEBUG){ qDebug() << "Initilization:"; } settings = LUtils::openSettings("lumina-desktop", "lumina-fm", this); //Reset the UI to the previously used size (if possible) QSize orig = settings->value("preferences/MainWindowSize", QSize()).toSize(); if(!orig.isEmpty() && orig.isValid()){ //Make sure the old size is larger than the default size hint if(orig.width() < this->sizeHint().width()){ orig.setWidth(this->sizeHint().width()); } if(orig.height() < this->sizeHint().height()){ orig.setHeight(this->sizeHint().height()); } //Also ensure the old size is smaller than the current screen size QSize screen = QApplication::desktop()->availableGeometry(this).size(); if(orig.width() > screen.width()){ orig.setWidth(screen.width()); } if(orig.height() > screen.height()){ orig.setHeight(screen.height()); } //Now resize the window this->resize(orig); } //initialize the non-ui widgets if(DEBUG){ qDebug() << " - Tab Bar Setup"; } tabBar = new QTabBar(this); tabBar->setTabsClosable(true); tabBar->setMovable(true); //tabs are independant - so allow the user to sort them tabBar->setShape(QTabBar::RoundedNorth); tabBar->setFocusPolicy(Qt::NoFocus); static_cast(ui->centralwidget->layout())->insertWidget(0,tabBar); if(DEBUG){ qDebug() << " - Threading"; } workThread = new QThread; workThread->setObjectName("Lumina-fm filesystem worker"); worker = new DirData(); worker->zfsavailable = LUtils::isValidBinary("zfs"); //connect(worker, SIGNAL(DirDataAvailable(QString, QString, LFileInfoList)), this, SLOT(DirDataAvailable(QString, QString, LFileInfoList)) ); connect(worker, SIGNAL(SnapshotDataAvailable(QString, QString, QStringList)), this, SLOT(SnapshotDataAvailable(QString, QString, QStringList)) ); worker->moveToThread(workThread); if(DEBUG){ qDebug() << " - Context Menu"; } contextMenu = new QMenu(this); radio_view_details = new QRadioButton(tr("Detailed List"), this); radio_view_list = new QRadioButton(tr("Basic List"), this); //radio_view_tabs = new QRadioButton(tr("Prefer Tabs"), this); //radio_view_cols = new QRadioButton(tr("Prefer Columns"), this); ui->menuView_Mode->clear(); //ui->menuGroup_Mode->clear(); detWA = new QWidgetAction(this); detWA->setDefaultWidget(radio_view_details); listWA = new QWidgetAction(this); listWA->setDefaultWidget(radio_view_list); //tabsWA = new QWidgetAction(this); //tabsWA->setDefaultWidget(radio_view_tabs); //colsWA = new QWidgetAction(this); //colsWA->setDefaultWidget(radio_view_cols); ui->menuView_Mode->addAction(detWA); ui->menuView_Mode->addAction(listWA); //ui->menuGroup_Mode->addAction(tabsWA); //ui->menuGroup_Mode->addAction(colsWA); if(DEBUG){ qDebug() << " - sort Menu"; } menuSort_Mode = new QMenu(this); radio_sort_name = new QRadioButton(tr("Sort by Name"), this); radio_sort_size = new QRadioButton(tr("Sort by Size"), this); radio_sort_type = new QRadioButton(tr("Sort by Type"), this); radio_sort_datemod = new QRadioButton(tr("Sort by Date Modified"), this); radio_sort_datecre = new QRadioButton(tr("Sort by Date Created"), this); ui->menuSort_Mode->clear(); sortnameA = new QWidgetAction(this); sortnameA->setDefaultWidget(radio_sort_name); sortsizeA = new QWidgetAction(this); sortsizeA->setDefaultWidget(radio_sort_size); sorttypeA = new QWidgetAction(this); sorttypeA->setDefaultWidget(radio_sort_type); sortdateMA = new QWidgetAction(this); sortdateMA->setDefaultWidget(radio_sort_datemod); sortdateCA = new QWidgetAction(this); sortdateCA->setDefaultWidget(radio_sort_datecre); ui->menuSort_Mode->addAction(sortnameA); ui->menuSort_Mode->addAction(sortsizeA); ui->menuSort_Mode->addAction(sorttypeA); ui->menuSort_Mode->addAction(sortdateMA); ui->menuSort_Mode->addAction(sortdateCA); //Setup the pages //ui->BrowserLayout->clear(); ui->page_player->setLayout(new QVBoxLayout()); ui->page_image->setLayout(new QVBoxLayout()); MW = new MultimediaWidget(this); SW = new SlideshowWidget(this); ui->page_player->layout()->addWidget(MW); ui->page_image->layout()->addWidget(SW); //Setup any specialty keyboard shortcuts if(DEBUG){ qDebug() << " - Keyboard Shortcuts"; } nextTabLShort = new QShortcut( QKeySequence(tr("Shift+Left")), this); nextTabRShort = new QShortcut( QKeySequence(tr("Shift+Right")), this); togglehiddenfilesShort = new QShortcut( QKeySequence(tr("Ctrl+H")), this); focusDirWidgetShort = new QShortcut( QKeySequence(tr("Ctrl+L")), this); //toggledirtreepaneShort = new QShortcut( QKeySequence(tr("Ctrl+P")), this); //Finish loading the interface workThread->start(); if(DEBUG){ qDebug() << " - Icons"; } setupIcons(); if(DEBUG){ qDebug() << " - Connections"; } setupConnections(); if(DEBUG){ qDebug() << " - Settings"; } loadSettings(); if(DEBUG){ qDebug() << " - Bookmarks"; } RebuildBookmarksMenu(); if(DEBUG){ qDebug() << " - Devices"; } RebuildDeviceMenu(); //Make sure we start on the browser page 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")); ui->transferTreeView->setVisible(false); } MainUI::~MainUI(){ for(int i=0; icleanup(); } workThread->quit(); //Also ensure the work thread is stopped // workThread->wait(); } void MainUI::OpenDirs(QStringList dirs){ //Now open the dirs if(dirs.isEmpty()){ dirs << QDir::homePath(); } QStringList invalid; for(int i=0; iid().section("-",1,1).toInt() >= id){ id = DWLIST[j]->id().section("-",1,1).toInt()+1; } } //Create the new DirWidget DirWidget *DW = new DirWidget("DW-"+QString::number(id), settings, this); DW->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->BrowserLayout->addWidget(DW); DWLIST << DW; //Connect the signals/slots for it connect(DW, SIGNAL(OpenDirectories(QStringList)), this, SLOT(OpenDirs(QStringList)) ); //connect(DW, SIGNAL(LoadDirectory(QString, QString)), worker, SLOT(GetDirData(QString, QString)) ); connect(DW, SIGNAL(findSnaps(QString, QString)), worker, SLOT(GetSnapshotData(QString, QString)) ); connect(DW, SIGNAL(PlayFiles(LFileInfoList)), this, SLOT(OpenPlayer(LFileInfoList)) ); connect(DW, SIGNAL(ViewFiles(LFileInfoList)), this, SLOT(OpenImages(LFileInfoList)) ); connect(DW, SIGNAL(LaunchTerminal(QString)), this, SLOT(OpenTerminal(QString)) ); connect(DW, SIGNAL(CutFiles(QStringList)), this, SLOT(CutFiles(QStringList)) ); connect(DW, SIGNAL(CopyFiles(QStringList)), this, SLOT(CopyFiles(QStringList)) ); connect(DW, SIGNAL(FavoriteFiles(QStringList)), this, SLOT(FavoriteFiles(QStringList)) ); connect(DW, SIGNAL(RenameFiles(QStringList)), this, SLOT(RenameFiles(QStringList)) ); connect(DW, SIGNAL(RemoveFiles(QStringList)), this, SLOT(RemoveFiles(QStringList)) ); connect(DW, SIGNAL(PasteFiles(QString,QStringList)), this, SLOT(PasteFiles(QString, QStringList)) ); connect(DW, SIGNAL(CloseBrowser(QString)), this, SLOT(CloseBrowser(QString)) ); connect(DW, SIGNAL(TabNameChanged(QString,QString)), this, SLOT(TabNameChanged(QString, QString)) ); connect(DW, SIGNAL(treeWidgetSizeChanged(float)), this, SLOT(treeWidgetWidthChanged(float)) ); //Now create the tab for this //if(radio_view_tabs->isChecked()){ int index = tabBar->addTab( LXDG::findIcon("folder-open",""), dirs[i].section("/",-1) ); tabBar->setTabWhatsThis( index, "DW-"+QString::number(id) ); tabBar->setCurrentIndex(index); /*}else{ //Just make sure the browser tab is visible bool found = false; for(int i=0; icount() && !found; i++){ if(tabBar->tabWhatsThis(i)=="browser"){ tabBar->setCurrentIndex(i); found=true; } } if(!found){ //Need to create the generic Browser tab int index = tabBar->addTab( LXDG::findIcon("folder-open",""), "Browser" ); tabBar->setTabWhatsThis( index, "browser" ); tabBar->setCurrentIndex(index); } }*/ //Initialize the widget with the proper settings if(DEBUG){ qDebug() << "Setup Dir Widget"; } DW->setShowDetails(radio_view_details->isChecked() ); DW->setThumbnailSize(settings->value("iconsize", 32).toInt() ); DW->showHidden( ui->actionView_Hidden_Files->isChecked() ); DW->showThumbnails( ui->actionShow_Thumbnails->isChecked() ); //DW->showDirTreePane( ui->actionView_showDirTreePane->isChecked() ); DW->adjustTreeWidget( settings->value("dirTree_width", 25.0).toFloat() ); DW->setTreeSortMode( settings->value("sortmode","num").toInt() ); //Now load the directory if(DEBUG){ qDebug() << "Load Directory"; } DW->ChangeDir(dirs[i]); //kick off loading the directory info } //Update visibilities tabChanged(tabBar->currentIndex()); tabBar->setVisible( tabBar->count() > 1 ); if(!invalid.isEmpty()){ QMessageBox::warning(this, tr("Invalid Directories"), tr("The following directories are invalid and could not be opened:")+"\n"+invalid.join(", ") ); } //Double check that there is at least 1 dir loaded //qDebug() << "OpenDirs:" << DWLIST.length() << dirs << invalid << tabBar->currentIndex(); if(DWLIST.isEmpty()){ OpenDirs(QStringList()); } waitingToClose = false; ui->menuGit->setEnabled( GIT::isAvailable() ); this->showNormal(); //single-instance check - make sure the window is raised again if it was minimized } void MainUI::setupIcons(){ this->setWindowIcon( LXDG::findIcon("Insight-FileManager","") ); //Setup all the icons using libLumina // File menu ui->actionNew_Window->setIcon( LXDG::findIcon("window-new","") ); ui->actionNew_Tab->setIcon( LXDG::findIcon("tab-new","") ); ui->actionSearch->setIcon( LXDG::findIcon("edit-find","") ); ui->actionOpen_as_Root->setIcon( LXDG::findIcon("system-file-manager-root","") ); ui->actionClose_Browser->setIcon( LXDG::findIcon("tab-close","") ); ui->actionClose->setIcon( LXDG::findIcon("application-exit","") ); // Edit menu ui->actionRename->setIcon( LXDG::findIcon("edit-rename","") ); ui->actionCut_Selection->setIcon( LXDG::findIcon("edit-cut","") ); ui->actionCopy_Selection->setIcon( LXDG::findIcon("edit-copy","") ); ui->actionPaste->setIcon( LXDG::findIcon("edit-paste","") ); ui->actionDelete_Selection->setIcon( LXDG::findIcon("edit-delete","") ); // View menu ui->actionRefresh->setIcon( LXDG::findIcon("view-refresh","") ); ui->menuView_Mode->setIcon( LXDG::findIcon("view-choose","") ); ui->menuSort_Mode->setIcon(LXDG::findIcon("list-spacing","view-list") ); // Bookmarks menu ui->actionManage_Bookmarks->setIcon( LXDG::findIcon("bookmarks-organize","") ); ui->actionManage_Bookmarks->setShortcut(tr("CTRL+B")); ui->actionAdd_Bookmark->setIcon( LXDG::findIcon("bookmark-new","") ); //GIT menu ui->actionRepo_Status->setIcon( LXDG::findIcon("git","document-edit-verify") ); ui->actionClone_Repository->setIcon( LXDG::findIcon("git","download") ); // External Devices menu ui->actionScan->setIcon( LXDG::findIcon("system-search","") ); ui->actionScan->setShortcut(tr("CTRL+E")); } //========== // PRIVATE //========== void MainUI::setupConnections(){ connect(tabBar, SIGNAL(currentChanged(int)), this, SLOT(tabChanged(int)) ); connect(tabBar, SIGNAL(tabCloseRequested(int)), this, SLOT(tabClosed(int)) ); connect(ui->menuBookmarks, SIGNAL(triggered(QAction*)), this, SLOT(goToBookmark(QAction*)) ); connect(ui->menuExternal_Devices, SIGNAL(triggered(QAction*)), this, SLOT(goToDevice(QAction*)) ); //Radio Buttons connect(radio_view_details, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool)) ); connect(radio_view_list, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool)) ); //connect(radio_view_tabs, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); //connect(radio_view_cols, SIGNAL(toggled(bool)), this, SLOT(groupModeChanged(bool)) ); // Sort Buttons connect(radio_sort_name, SIGNAL(toggled(bool)), this, SLOT(sortModeName(bool)) ); connect(radio_sort_size, SIGNAL(toggled(bool)), this, SLOT(sortModeSize(bool)) ); connect(radio_sort_type, SIGNAL(toggled(bool)), this, SLOT(sortModeType(bool)) ); connect(radio_sort_datemod, SIGNAL(toggled(bool)), this, SLOT(sortModeDateM(bool)) ); connect(radio_sort_datecre, SIGNAL(toggled(bool)), this, SLOT(sortModeDateC(bool)) ); //Special Keyboard Shortcuts connect(nextTabLShort, SIGNAL(activated()), this, SLOT( prevTab() ) ); connect(nextTabRShort, SIGNAL(activated()), this, SLOT( nextTab() ) ); connect(togglehiddenfilesShort, SIGNAL(activated()), this, SLOT( togglehiddenfiles() ) ); connect(focusDirWidgetShort, SIGNAL(activated()), this, SLOT( focusDirWidget() ) ); //connect(toggledirtreepaneShort, SIGNAL(activated()), this, SLOT( toggleDirTreePane() ) ); } void MainUI::focusDirWidget() { DirWidget *dir = FindActiveBrowser(); if(dir != 0) { dir->setFocusLineDir(); } } void MainUI::togglehiddenfiles() { //change setChecked to inverse value ui->actionView_Hidden_Files->setChecked( !settings->value("showhidden", true).toBool() ); // then trigger function on_actionView_Hidden_Files_triggered(); } /*void MainUI::toggleDirTreePane() { //change setChecked to inverse value ui->actionView_Hidden_Files->setChecked( !settings->value("showdirtree", true).toBool() ); // then trigger function on_actionView_showDirTreePane_triggered(); }*/ void MainUI::loadSettings(){ //Note: make sure this is run after all the UI elements are created and connected to slots // but before the first directory gets loaded ui->actionView_Hidden_Files->setChecked( settings->value("showhidden", false).toBool() ); on_actionView_Hidden_Files_triggered(); //make sure to update the models too ui->actionShow_Thumbnails->setChecked( settings->value("showthumbnails",true).toBool()); on_actionShow_Thumbnails_triggered(); //make sure to update models too //ui->actionView_showDirTreePane->setChecked( settings->value("showdirtree", false).toBool()); //on_actionView_showDirTreePane_triggered(); //make sure to update the models too ui->actionVerify_File_Delete->setChecked( settings->value("showdeleteprompt", true).toBool()); //ui->actionShow_Action_Buttons->setChecked(settings->value("showactions", true).toBool() ); //on_actionShow_Action_Buttons_triggered(); //make sure to update the UI //ui->actionShow_Thumbnails->setChecked( settings->value("showthumbnails", true).toBool() ); //View Type //qDebug() << "View Mode:" << settings->value("viewmode","details").toString(); bool showDetails = (settings->value("viewmode","details").toString()=="details"); if(showDetails){ radio_view_details->setChecked(true); } else{ radio_view_list->setChecked(true); } //Grouping type //bool usetabs = (settings->value("groupmode","tabs").toString()=="tabs"); //if(usetabs){ radio_view_tabs->setChecked(true); } // else{ radio_view_cols->setChecked(true); } //Sort Mode int sortMode = (settings->value("sortmode","num").toInt() ); switch(sortMode){ case 0: // Name radio_sort_name->setChecked(true); break; case 1: // Size radio_sort_size->setChecked(true); break; case 2: // Type radio_sort_type->setChecked(true); break; case 3: // Date Modified radio_sort_datemod->setChecked(true); break; case 4: // Date Created radio_sort_datecre->setChecked(true); break; } // end sortMode Switch } void MainUI::RebuildBookmarksMenu(){ //Create the bookmarks menu QStringList BM = settings->value("bookmarks", QStringList()).toStringList(); ui->menuBookmarks->clear(); ui->menuBookmarks->addAction(ui->actionManage_Bookmarks); ui->menuBookmarks->addAction(ui->actionAdd_Bookmark); ui->menuBookmarks->addSeparator(); bool changed = false; BM.sort(); //Sort alphabetically for(int i=0; isetWhatsThis(BM[i].section("::::",1,1)); ui->menuBookmarks->addAction(act); /*}else{ //Invalid directory - remove the bookmark BM.removeAt(i); i--; changed = true; }*/ } if(changed){ settings->setValue("bookmarks",BM); } ui->actionManage_Bookmarks->setEnabled(BM.length()>0); } void MainUI::RebuildDeviceMenu(){ //Create the External Devices Menu appropriately ui->menuExternal_Devices->clear(); ui->menuExternal_Devices->addAction( ui->actionScan ); ui->menuExternal_Devices->addSeparator(); //Scan for externally mounted devices QStringList devs = LOS::ExternalDevicePaths(); //Output Format: :::::::: (6/24/14 - version 0.4.0 ) // = [USB, HDRIVE, SDCARD, DVD, LVM, UNKNOWN] //qDebug() << "Externally-mounted devices:" << devs; //Now add them to the menu appropriately for(int i=0; i