<commit_before>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014-2015, <NAME>
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "MainUI.h"
#include "ui_MainUI.h"

#include <QMenu>
#include <QFileInfo>
#include "gitCompat.h"
#include "gitWizard.h"

#include <LDesktopUtils.h>

#define DEBUG 0

MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
  //for Signal/slot we must register the Typedef of QFileInfoList
  //qRegisterMetaType<QFileInfoList>("QFileInfoList");
  qRegisterMetaType< LFileInfoList >("LFileInfoList");
  //just to silence/fix some Qt connect warnings in QtConcurrent
  //qRegisterMetaType< QVector<int> >("QVector<int>"); 
  //qRegisterMetaType< QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>");
  waitingToClose = false;
	
  ui->setupUi(this);
  ui->menuGit->setVisible( GIT::isAvailable() );
  if(DEBUG){ qDebug() << "Initilization:"; }
  settings = new QSettings( QSettings::UserScope, "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<QBoxLayout*>(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);
  //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);

  //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"; }
}

MainUI::~MainUI(){
  for(int i=0; i<DWLIST.length(); i++){
    DWLIST[i]->cleanup();
  }
  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; i<dirs.length(); i++){
    if(dirs[i].simplified().isEmpty()){ continue; }
    //Open this directory in a viewer
    if(dirs[i].endsWith("/")){ dirs[i].chop(1); }
    if(!QFile::exists(dirs[i])){ invalid << dirs[i]; continue; }
    if(DEBUG){ qDebug() << "Open Directory:" << dirs[i]; }
    ///Get a new Unique ID
    int id = 0;
    for(int j=0; j<DWLIST.length(); j++){ 
      if(DWLIST[j]->id().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), 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)) );
    //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; i<tabBar->count() && !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
    DW->setShowDetails(radio_view_details->isChecked()); 
    DW->setThumbnailSize(settings->value("iconsize", 32).toInt());
    //Now load the 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;
}

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->actionClose_Browser->setIcon( LXDG::findIcon("tab-close","") );
  ui->actionClose->setIcon( LXDG::findIcon("application-exit","") );

  // Edit menu<commit_msg>Fix up the loading of the "show hidden files" option at the start of a browser widget in lumina-fm.<commit_after>//===========================================
//  Lumina-DE source code
//  Copyright (c) 2014-2015, <NAME>
//  Available under the 3-clause BSD license
//  See the LICENSE file for full details
//===========================================
#include "MainUI.h"
#include "ui_MainUI.h"

#include <QMenu>
#include <QFileInfo>
#include "gitCompat.h"
#include "gitWizard.h"

#include <LDesktopUtils.h>

#define DEBUG 0

MainUI::MainUI() : QMainWindow(), ui(new Ui::MainUI){
  //for Signal/slot we must register the Typedef of QFileInfoList
  //qRegisterMetaType<QFileInfoList>("QFileInfoList");
  qRegisterMetaType< LFileInfoList >("LFileInfoList");
  //just to silence/fix some Qt connect warnings in QtConcurrent
  //qRegisterMetaType< QVector<int> >("QVector<int>"); 
  //qRegisterMetaType< QList<QPersistentModelIndex> >("QList<QPersistentModelIndex>");
  waitingToClose = false;
	
  ui->setupUi(this);
  ui->menuGit->setVisible( GIT::isAvailable() );
  if(DEBUG){ qDebug() << "Initilization:"; }
  settings = new QSettings( QSettings::UserScope, "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<QBoxLayout*>(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);
  //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);

  //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"; }
}

MainUI::~MainUI(){
  for(int i=0; i<DWLIST.length(); i++){
    DWLIST[i]->cleanup();
  }
  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; i<dirs.length(); i++){
    if(dirs[i].simplified().isEmpty()){ continue; }
    //Open this directory in a viewer
    if(dirs[i].endsWith("/")){ dirs[i].chop(1); }
    if(!QFile::exists(dirs[i])){ invalid << dirs[i]; continue; }
    if(DEBUG){ qDebug() << "Open Directory:" << dirs[i]; }
    ///Get a new Unique ID
    int id = 0;
    for(int j=0; j<DWLIST.length(); j++){ 
      if(DWLIST[j]->id().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), 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)) );
    //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; i<tabBar->count() && !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
    DW->setShowDetails(radio_view_details->isChecked()); 
    DW->setThumbnailSize(settings->value("iconsize", 32).toInt());
    DW->showHidden( ui->actionView_Hidden_Files->isChecked() );
    //Now load the 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;
}

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->actionClose_Browser->setIcon( LXDG::findIcon("tab-close","") );
  ui->actionClose->setIcon( LXDG::findIcon("application-exit","") );

  // Edit menu
{'fraction_non_alphanumeric': 0.18314348416762463, 'fraction_numerical': 0.0028216114536524194, 'mean_word_length': 4.79794001817631, 'pattern_counts': {'":': 0, '<': 125, '<?xml version=': 0, '>': 214, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '921884', 'n_tokens_mistral': 6503, 'n_tokens_neox': 6267, 'n_words': 1273}