//=========================================== // Lumina-DE source code // Copyright (c) 2014, 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 #define DEBUG 0 MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){ //for Signal/slot we must register the Typedef of QFileInfoList qRegisterMetaType("QFileInfoList"); ui->setupUi(this); if(DEBUG){ qDebug() << "Initilization:"; } //Be careful about the QSettings setup, it must match the lumina-desktop setup QSettings::setPath(QSettings::NativeFormat, QSettings::UserScope, QDir::homePath()+"/.lumina"); settings = new QSettings( QSettings::UserScope, "LuminaDE", "lumina-fm", this); favdir = QDir::homePath()+"/.lumina/favorites/"; //save this for later syncTimer = new QTimer(this); syncTimer->setInterval(200); //1/5 second (collect as many signals/slots as necessary syncTimer->setSingleShot(true); //Reset the UI to the previously used size (if possible) if(DEBUG){ qDebug() << " - Reset window size"; } int height = settings->value("geometry/height",-1).toInt(); if(height>100 && height <= QApplication::desktop()->availableGeometry(this).height()){ this->resize(this->width(), height); } int width = settings->value("geometry/width",-1).toInt(); if(width>100 && width <= QApplication::desktop()->availableGeometry(this).width()){ this->resize(width, this->height() ); } //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); ui->verticalLayout_browser->insertWidget(0,tabBar); currentDir = new QLineEdit(this); ui->toolBar->insertWidget(ui->actionBookMark, currentDir); currentDir->setFocusPolicy(Qt::StrongFocus); if(DEBUG){ qDebug() << " - Threading"; } workThread = new QThread; workThread->setObjectName("Lumina-fm filesystem worker"); worker = new BackgroundWorker; worker->moveToThread(workThread); if(DEBUG){ qDebug() << " - File System Model"; } fsmod = new DDFileSystemModel(this); fsmod->setRootPath("/"); //fsmod->setReadOnly(false); //required for DnD, but also enables a lot of other stuff //qDebug() << "DnD options:" << fsmod->supportedDropActions(); ui->tree_dir_view->setModel(fsmod); ui->tree_dir_view->sortByColumn(0, Qt::AscendingOrder); ui->tree_dir_view->setColumnWidth(0,200); ui->tree_dir_view->setColumnWidth(1,80); //size column should be small ui->tree_dir_view->setColumnWidth(2,80); //type column should be small ui->list_dir_view->setModel(fsmod); dirCompleter = new QCompleter(fsmod, this); dirCompleter->setModelSorting( QCompleter::CaseInsensitivelySortedModel ); currentDir->setCompleter(dirCompleter); snapmod = new QFileSystemModel(this); ui->tree_zfs_dir->setModel(snapmod); ui->tree_zfs_dir->sortByColumn(0, Qt::AscendingOrder); if(DEBUG){ qDebug() << " - Icon Provider"; } iconProv = new MimeIconProvider(); fsmod->setIconProvider(iconProv); snapmod->setIconProvider(iconProv); 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_icons = new QRadioButton(tr("Icons"), this); detWA = new QWidgetAction(this); detWA->setDefaultWidget(radio_view_details); listWA = new QWidgetAction(this); listWA->setDefaultWidget(radio_view_list); icoWA = new QWidgetAction(this); icoWA->setDefaultWidget(radio_view_icons); ui->menuView->addAction(detWA); ui->menuView->addAction(listWA); ui->menuView->addAction(icoWA); //Setup the special Phonon widgets if(DEBUG){ qDebug() << " - Multimedia Widgets"; } mediaObj = new QMediaPlayer(this); mediaObj->setVolume(100); mediaObj->setNotifyInterval(500); //only every 1/2 second update videoDisplay = new QVideoWidget(this); videoDisplay->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); ui->videoLayout->addWidget(videoDisplay); mediaObj->setVideoOutput(videoDisplay); videoDisplay->setVisible(false); playerSlider = new QSlider(this); playerSlider->setOrientation(Qt::Horizontal); ui->videoControlLayout->insertWidget(4, playerSlider); ui->tool_player_stop->setEnabled(false); //nothing to stop yet ui->tool_player_pause->setVisible(false); //nothing to pause yet playerSlider->setEnabled(false); //nothing to seek yet //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); closeTabShort = new QShortcut( QKeySequence(tr("Ctrl+W")), this); 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); //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 if(DEBUG){ qDebug() << " - Load Browser Page"; } goToBrowserPage(); if(DEBUG){ qDebug() << " - Done with init"; } } MainUI::~MainUI(){ workThread->quit(); workThread->wait(); } void MainUI::OpenDirs(QStringList dirs){ QStringList invalid; for(int i=0; iaddTab( dirs[i].section("/",-1) ); tabBar->setTabWhatsThis( index, dirs[i] ); if(index==0){ setCurrentDir(dirs[i]); }//display this as the current dir } 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(", ") ); } } //========== // PRIVATE //========== void MainUI::setupIcons(){ this->setWindowIcon( LXDG::findIcon("Insight-FileManager","") ); //Setup all the icons using libLumina ui->actionClose->setIcon( LXDG::findIcon("application-exit","") ); ui->actionNew_Tab->setIcon( LXDG::findIcon("tab-new-background","") ); //ui->action_Preferences->setIcon( LXDG::findIcon("configure","") ); ui->actionUpDir->setIcon( LXDG::findIcon("go-up","") ); ui->actionBack->setIcon( LXDG::findIcon("go-previous","") ); ui->actionHome->setIcon( LXDG::findIcon("go-home","") ); ui->actionBookMark->setIcon( LXDG::findIcon("bookmarks","") ); ui->actionBackToBrowser->setIcon( LXDG::findIcon("go-previous","") ); ui->actionManage_Bookmarks->setIcon( LXDG::findIcon("bookmarks-organize","") ); ui->actionScan->setIcon( LXDG::findIcon("system-search","") ); ui->actionSearch->setIcon( LXDG::findIcon("edit-find","") ); //Browser page ui->tool_addNewFile->setIcon( LXDG::findIcon("document-new","")); ui->tool_addToDir->setIcon( LXDG::findIcon("folder-new","") ); ui->tool_goToImages->setIcon( LXDG::findIcon("fileview-preview","") ); ui->tool_goToPlayer->setIcon( LXDG::findIcon("applications-multimedia","") ); ui->tool_goToRestore->setIcon( LXDG::findIcon("document-revert","") ); ui->tool_act_run->setIcon( LXDG::findIcon("run-build-file","") ); ui->tool_act_runwith->setIcon( LXDG::findIcon("run-build-configure","") ); ui->tool_act_cut->setIcon( LXDG::findIcon("edit-cut","") ); ui->tool_act_copy->setIcon( LXDG::findIcon("edit-copy","") ); ui->tool_act_paste->setIcon( LXDG::findIcon("edit-paste","") ); 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","") ); //Multimedia Player page ui->tool_player_next->setIcon( LXDG::findIcon("media-skip-forward","") ); ui->tool_player_prev->setIcon( LXDG::findIcon("media-skip-backward","") ); ui->tool_player_pause->setIcon( LXDG::findIcon("media-playback-pause","") ); ui->tool_player_play->setIcon( LXDG::findIcon("media-playback-start","") ); ui->tool_player_stop->setIcon( LXDG::findIcon("media-playback-stop","") ); //Slideshow page ui->tool_image_goBegin->setIcon( LXDG::findIcon("go-first-view","") ); ui->tool_image_goEnd->setIcon( LXDG::findIcon("go-last-view","") ); ui->tool_image_goPrev->setIcon( LXDG::findIcon("go-previous-view","") ); ui->tool_image_goNext->setIcon( LXDG::findIcon("go-next-view","") ); ui->tool_image_remove->setIcon( LXDG::findIcon("edit-delete","") ); ui->tool_image_rotateleft->setIcon( LXDG::findIcon("object-rotate-left","") ); ui->tool_image_rotateright->setIcon( LXDG::findIcon("object-rotate-right","") ); //ZFS Restore page ui->tool_zfs_nextSnap->setIcon( LXDG::findIcon("go-next-view","") ); ui->tool_zfs_prevSnap->setIcon( LXDG::findIcon("go-previous-view","") ); ui->tool_zfs_restoreItem->setIcon( LXDG::findIcon("document-revert","") ); } void MainUI::setupConnections(){ connect(QApplication::instance(), SIGNAL(focusChanged(QWidget*, QWidget*)), this, SLOT(startEditDir(QWidget*, QWidget*)) ); 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*)) ); connect(currentDir, SIGNAL(returnPressed()), this, SLOT(goToDirectory())); 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_icons, SIGNAL(toggled(bool)), this, SLOT(viewModeChanged(bool)) ); connect(fsmod, SIGNAL(directoryLoaded(QString)), this, SLOT(slotStartSyncTimer()) ); connect(syncTimer, SIGNAL(timeout()), this, SLOT(currentDirectoryLoaded()) ); //Background worker class connect(this, SIGNAL(DirChanged(QString)), worker, SLOT(startDirChecks(QString)) ); connect(worker, SIGNAL(ImagesAvailable(QStringList)), this, SLOT(AvailablePictures(QStringList)) ); connect(worker, SIGNAL(MultimediaAvailable(QStringList)), this, SLOT(AvailableMultimediaFiles(QStringList)) ); connect(worker, SIGNAL(SnapshotsAvailable(QString, QStringList)), this, SLOT(AvailableBackups(QString, QStringList)) ); //Background worker class for statusbar connect(this, SIGNAL(Si_AdaptStatusBar(QFileInfoList, QString, QString, QString)), worker, SLOT(createStatusBarMsg(QFileInfoList, QString, QString, QString)) ); connect(worker, SIGNAL(Si_DisplayStatusBar(QString)), this, SLOT(DisplayStatusBar(QString)) ); //Action buttons on browser page connect(ui->tool_act_run, SIGNAL(clicked()), this, SLOT(OpenItem()) ); connect(ui->tool_act_runwith, SIGNAL(clicked()), this, SLOT(OpenItemWith()) ); connect(ui->tool_act_rm, SIGNAL(clicked()), this, SLOT(RemoveItem()) ); connect(ui->tool_act_rename, SIGNAL(clicked()), this, SLOT(RenameItem()) ); connect(ui->tool_act_paste, SIGNAL(clicked()), this, SLOT(PasteItems()) ); connect(ui->tool_act_cut, SIGNAL(clicked()), this, SLOT(CutItems()) ); connect(ui->tool_act_copy, SIGNAL(clicked()), this, SLOT(CopyItems()) ); connect(ui->tool_act_fav, SIGNAL(clicked()), this, SLOT(FavoriteItem()) ); //Tree Widget interaction 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()) ); //Page Switching connect(ui->tool_goToPlayer, SIGNAL(clicked()), this, SLOT(goToMultimediaPage()) ); connect(ui->tool_goToRestore, SIGNAL(clicked()), this, SLOT(goToRestorePage()) ); connect(ui->tool_goToImages, SIGNAL(clicked()), this, SLOT(goToSlideshowPage()) ); connect(ui->actionBackToBrowser, SIGNAL(triggered()), this, SLOT(goToBrowserPage()) ); //Slideshow page connect(ui->combo_image_name, SIGNAL(currentIndexChanged(int)), this, SLOT(showNewPicture()) ); connect(ui->tool_image_goBegin, SIGNAL(clicked()), this, SLOT(firstPicture()) ); connect(ui->tool_image_goEnd, SIGNAL(clicked()), this, SLOT(lastPicture()) ); connect(ui->tool_image_goNext, SIGNAL(clicked()), this, SLOT(nextPicture()) ); connect(ui->tool_image_goPrev, SIGNAL(clicked()), this, SLOT(prevPicture()) ); connect(ui->tool_image_remove, SIGNAL(clicked()), this, SLOT(removePicture()) ); connect(ui->tool_image_rotateleft, SIGNAL(clicked()), this, SLOT(rotatePictureLeft()) ); connect(ui->tool_image_rotateright, SIGNAL(clicked()), this, SLOT(rotatePictureRight()) ); //ZFS Restore page connect(ui->slider_zfs_snapshot, SIGNAL(valueChanged(int)), this, SLOT(showSnapshot()) ); connect(ui->tool_zfs_nextSnap, SIGNAL(clicked()), this, SLOT(nextSnapshot()) ); connect(ui->tool_zfs_prevSnap, SIGNAL(clicked()), this, SLOT(prevSnapshot()) ); connect(ui->tool_zfs_restoreItem, SIGNAL(clicked()), this, SLOT(restoreItems()) ); //Multimedia Player page connect(ui->tool_player_next, SIGNAL(clicked()), this, SLOT(playerNext())); connect(ui->tool_player_prev, SIGNAL(clicked()), this, SLOT(playerPrevious())); connect(ui->tool_player_pause, SIGNAL(clicked()), this, SLOT(playerPause())); connect(ui->tool_player_play, SIGNAL(clicked()), this, SLOT(playerStart())); connect(ui->tool_player_stop, SIGNAL(clicked()), this, SLOT(playerStop())); connect(ui->combo_player_list, SIGNAL(currentIndexChanged(int)), this, SLOT(playerFileChanged()) ); connect(playerSlider, SIGNAL(sliderPressed()), this, SLOT(playerSliderHeld()) ); connect(playerSlider, SIGNAL(sliderReleased()), this, SLOT(playerSliderChanged()) ); connect(playerSlider, SIGNAL(valueChanged(int)), this, SLOT(playerSliderMoved(int)) ); connect(mediaObj, SIGNAL(durationChanged(qint64)), this, SLOT(playerDurationChanged(qint64)) ); connect(mediaObj, SIGNAL(seekableChanged(bool)), playerSlider, SLOT(setEnabled(bool)) ); connect(mediaObj, SIGNAL(mediaStatusChanged(QMediaPlayer::MediaStatus)), this, SLOT(playerStatusChanged(QMediaPlayer::MediaStatus)) ); connect(mediaObj, SIGNAL(positionChanged(qint64)), this, SLOT(playerTimeChanged(qint64)) ); connect(mediaObj, SIGNAL(stateChanged(QMediaPlayer::State)), this, SLOT(playerStateChanged(QMediaPlayer::State)) ); connect(mediaObj, SIGNAL(videoAvailableChanged(bool)), this, SLOT(playerVideoAvailable(bool)) ); connect(mediaObj, SIGNAL(error(QMediaPlayer::Error)), this, SLOT(playerError()) ); //Special Keyboard Shortcuts connect(nextTabLShort, SIGNAL(activated()), this, SLOT( prevTab() ) ); connect(nextTabRShort, SIGNAL(activated()), this, SLOT( nextTab() ) ); connect(closeTabShort, SIGNAL(activated()), this, SLOT( tabClosed() ) ); connect(copyFilesShort, SIGNAL(activated()), this, SLOT( CopyItems() ) ); connect(cutFilesShort, SIGNAL(activated()), this, SLOT( CutItems() ) ); connect(pasteFilesShort, SIGNAL(activated()), this, SLOT( PasteItems() ) ); connect(deleteFilesShort, SIGNAL(activated()), this, SLOT( RemoveItem() ) ); } 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_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() ); iconProv->showthumbnails = ui->actionShow_Thumbnails->isChecked(); QString view = settings->value("viewmode","details").toString(); if(view=="icons"){ radio_view_icons->setChecked(true); } else if(view=="list"){ radio_view_list->setChecked(true); } else{ radio_view_details->setChecked(true); } } void MainUI::RebuildBookmarksMenu(){ //Create the bookmarks menu ui->menuBookmarks->clear(); ui->menuBookmarks->addAction(ui->actionManage_Bookmarks); ui->menuBookmarks->addSeparator(); QStringList BM = settings->value("bookmarks", QStringList()).toStringList(); ui->menuBookmarks->clear(); ui->menuBookmarks->addAction(ui->actionManage_Bookmarks); 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] //Now add them to the menu appropriately for(int i=0; i