Пример #1
0
void DirWidget::startSync(const QString &file){
  //Update date_format based on user settings
  if(file == sessionsettings_config_file){ setDateFormat(); }
  else if(file == snapbasedir){ emit findSnaps(ID, normalbasedir); } //snapshot list changed
  else if(file == normalbasedir){ 
    if(synctimer->isActive()){ synctimer->stop(); } //already starting a sync - restart the timer
    synctimer->start();
  }else{
    //Some file in the directory got changed - start the time for a dir reload 
    // -- This prevents a directory from refreshing constantly if a file within the directory is changing all the time (such as a log file)
    if(!synctimer->isActive()){ synctimer->start(); }
  }
}
Пример #2
0
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 if(QFile::exists(snapbasedir+snapshots[val])){
    ui->label_snap->setText( QFileInfo(snapbasedir+snapshots[val]).lastModified().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;
  if(DEBUG){ qDebug() << "Changing snapshot:" << CDIR << val << snapbasedir; }
  stopload = true; //stop any currently-loading procedures
  if(val >= snapshots.length() || val < 0){ //active system selected
    if(DEBUG){ qDebug() << " - Load Active system:" << normalbasedir; }
    dir = normalbasedir;
  }else{
    dir = snapbasedir+snapshots[val]+"/";
    if(!QFile::exists(dir)){
      //This snapshot must have been removed in the background by pruning tools
      //    move to a newer snapshot or the current base dir as necessary
      qDebug() << "Snapshot no longer available:" << dir;
      qDebug() << " - Reloading available snapshots";
      emit findSnaps(ID, normalbasedir);
      return;
    }
    //if(snaprelpath.isEmpty()){
      //Need to figure out the relative path within the snapshot
      snaprelpath = normalbasedir.section(snapbasedir.section(ZSNAPDIR,0,0), 1,1000);
      if(DEBUG){ qDebug() << " - new snapshot-relative path:" << snaprelpath; }
    //}
    dir.append(snaprelpath);
    dir.replace("//","/"); //just in case any duplicate slashes from all the split/combining
    if(DEBUG){ qDebug() << " - Load Snapshot:" << dir; }
  }
  //Make sure this directory exists, and back up as necessary
  
  /*while(!QFile::exists(dir) && !dir.isEmpty()){
    dir = dir.section("/",0,-2); //back up one dir
  }*/
  if(dir.isEmpty()){ return; }
  //Load the newly selected snapshot
  stopload = true; //just in case it is still loading
  emit LoadDirectory(ID, dir);
}
Пример #3
0
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)) );
    //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->setShowSidebar(ui->actionShow_Action_Buttons->isChecked());
    QList<DirWidget::DETAILTYPES> details; details <<DirWidget::NAME << DirWidget::SIZE << DirWidget::TYPE << DirWidget::DATEMOD;
    DW->setDetails(details); //Which details to show and in which order (L->R)
    DW->setShowThumbnails(ui->actionShow_Thumbnails->isChecked());
    DW->setThumbnailSize(settings->value("iconsize", 32).toInt());
    DW->setDirCompleter(dirCompleter);
    DW->setShowCloseButton(!radio_view_tabs->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()); }
  
}
Пример #4
0
// ================
//    PUBLIC SLOTS
// ================
void DirWidget::LoadDir(QString dir, QList<LFileInfo> list){
  if(dir.isEmpty()){ return; } //nothing to do
  QTime time;
  if(DEBUG){time.start(); }
  qDebug() << "Load Dir:" << dir;
  QString lastdir = CDIR; //for some checks later
  QString lastbasedir = normalbasedir;
  CDIR = dir;
  if(CDIR.endsWith("/") && CDIR.length() > 1){ CDIR.chop(1); }
  CLIST = list; //save for later
  canmodify = QFileInfo(CDIR).isWritable();
  if(DEBUG){ qDebug() << "Clear UI:" <<time.elapsed(); }
  //Clear the status text
  if(!canmodify){ui->label_status->setText(tr("(Limited Access) ")); }
  else{ ui->label_status->setText(""); }
  //Hide the extra buttons for a moment
  ui->tool_goToPlayer->setVisible(false);
  ui->tool_goToImages->setVisible(false);
  ui->tool_new_dir->setVisible(canmodify);
  ui->tool_new_file->setVisible(canmodify);
  //Set the drag/drop info as appripriate
  if(canmodify){
    listWidget->setWhatsThis(CDIR);
    treeWidget->setWhatsThis(CDIR);
  }else{
    listWidget->setWhatsThis("");
    treeWidget->setWhatsThis("");
  }
  bool updateThumbs = (lastdir != CDIR);
  //Determine if this is an internal ZFS snapshot
  bool loadsnaps = false;
  if(DEBUG){ qDebug() << "Load Snap Info:" << time.elapsed(); }
  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)){
      loadsnaps = true; //different snapshot loaded - need to update internally
    }
  }else{
    //This is a normal directory - prompt for snapshot information
    line_dir->setText(CDIR);
    normalbasedir = CDIR;
    if(!snapbasedir.isEmpty()){ watcher->removePath(snapbasedir); }
    snapbasedir.clear();
    loadsnaps = true;
  }
  if(loadsnaps){
    //kick this off while still loading the dir contents
    ui->group_snaps->setEnabled(false); //to prevent the snap updates to be automatically used
    ui->group_snaps->setVisible(false);
    ui->slider_snap->setRange(1,1);
    emit findSnaps(ID, normalbasedir);
  }

  if(DEBUG){ qDebug() << "Update History:" <<time.elapsed(); }
  //Now update the history for this browser
  //qDebug() << "History:" << history << normalbasedir << lastbasedir;
  if(!history.isEmpty() && history.last() == normalbasedir && lastbasedir!=normalbasedir ){
    //We went back one - remove this from the history
    history.takeLast();
    ui->actionBack->setEnabled(!history.isEmpty());
    //qDebug() << " - Duplicate: removed item";
  }else if(lastbasedir!=normalbasedir){ //not a refresh or internal snapshot change
    //qDebug() << " - New History Item:" << normalbasedir;
    history << normalbasedir;
    ui->actionBack->setEnabled(history.length()>1);
  }
  if(DEBUG){ qDebug() << "Update Watcher:" << time.elapsed(); }
  //Clear the current watcher
  if(!watcher->directories().isEmpty()){ watcher->removePaths(watcher->directories()); }
  if(!watcher->files().isEmpty()){ watcher->removePaths(watcher->files()); }
  watcher->addPath(CDIR);
  // add sessionsettings to watcher so date_format can be update based on user settings
  watcher->addPath(sessionsettings_config_file);
  ui->actionStopLoad->setVisible(true);
  stopload = false;
  //Clear the display widget (if a new directory)
    if(DEBUG){ qDebug() << "Clear Browser Widget:" << time.elapsed(); }
  double scrollpercent = -1;
  if(updateThumbs){ needThumbs.clear(); }
  if(lastbasedir != normalbasedir){
    if(showDetails){ treeWidget->clear(); }
    else{ listWidget->clear(); }
    QApplication::processEvents(); //make sure it is cleared right away
  }else{
    //Need to be smarter about which items need to be removed
    // - compare the old/new lists and remove any items not in the new listing (new items taken care of below)
    QStringList newfiles; //just the filenames
    for(int i=0; i<CLIST.length(); i++){ newfiles << CLIST[i].fileName(); }
    if(showDetails){
      for(int i=0; i<treeWidget->topLevelItemCount(); i++){
        if( !newfiles.contains(treeWidget->topLevelItem(i)->whatsThis(0).section("/",-1)) ){
	  if(!updateThumbs){ needThumbs.removeAll( treeWidget->topLevelItem(i)->whatsThis(0).section("::::",1,50)); }
	  delete treeWidget->takeTopLevelItem(i); 
	  i--;
	}
      }
      QApplication::processEvents(); //make sure the scrollbar is up to date after removals
      scrollpercent = treeWidget->verticalScrollBar()->value()/( (double) treeWidget->verticalScrollBar()->maximum());
    }else{
      for(int i=0; i<listWidget->count(); i++){
        if( !newfiles.contains(listWidget->item(i)->text()) ){
	  if(!updateThumbs){ needThumbs.removeAll( listWidget->item(i)->whatsThis().section("::::",1,50)); }
	  delete listWidget->takeItem(i); 
	  i--;
	}
      }
      QApplication::processEvents(); //make sure the scrollbar is up to date after removals
      scrollpercent = listWidget->horizontalScrollBar()->value()/( (double) listWidget->horizontalScrollBar()->maximum());
    }
  } //end check for CDIR reload
  //Now fill the display widget
  bool hasimages, hasmultimedia;
  hasimages = hasmultimedia = false;
  int numdirs = 0;
  qint64 filebytes = 0;
  //Setup the timer to see when we should process events
  /*QTimer updatetime;
    updatetime.setInterval(1000); //1 second updates
    updatetime.setSingleShot(true);
    updatetime.start();*/
  QTime updatetime = QTime::currentTime().addMSecs(500);
  if(DEBUG){ qDebug() << "Start Loop over items:" << time.elapsed(); }
  for(int i=0; i<list.length(); i++){
    if(stopload){ ui->actionStopLoad->setVisible(false); return; } //stop right now
    if(!hasimages && list[i].isImage()){ hasimages = true;  ui->tool_goToImages->setVisible(true); }
    else if(!hasmultimedia && list[i].isAVFile()){ hasmultimedia = true;  ui->tool_goToPlayer->setVisible(true); }
    //Update statistics
    if(list[i].isDir()){ numdirs++; }
    else{ filebytes += list[i].size(); }
    watcher->addPath(list[i].absoluteFilePath());
    if(showDetails){
      //Now create all the individual items for the details tree
      CQTreeWidgetItem *it;
      bool addnew = false;
	//See if an item already exists for this file
	QList<QTreeWidgetItem*> items = treeWidget->findItems(list[i].fileName(),Qt::MatchExactly,0); //NOTE: This requires column 0 to be the name
	if(items.isEmpty()){
        it = new CQTreeWidgetItem();
	    addnew = true;
	}else{
        // Safe downcasting because CQTreeWidgetItem only redefines the virtual function bool opearot<. Not new methos added.
        it = static_cast<CQTreeWidgetItem *> (items.first());
	}
	//Now update the entry contents
	it->setWhatsThis(0, QString(canmodify ? "cut": "copy")+"::::"+list[i].absoluteFilePath());
      for(int t=0; t<listDetails.length(); t++){
        switch(listDetails[t]){
	  case NAME:
	    it->setText(t,list[i].fileName());
	    it->setStatusTip(t, list[i].fileName());
	      //Since the icon/image is based on the filename - only update this for a new item
	      // (This is the slowest part of the routine)
	      if(list[i].isImage()&& (addnew || updateThumbs)){
	        if(showThumbs){ 
		  it->setIcon(t, LXDG::findIcon("fileview-preview","image-x-generic") );
		  needThumbs << list[i].fileName();	
		}else{ it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
	      }else if(addnew){
	        it->setIcon(t, LXDG::findIcon(list[i].iconfile(),"unknown") );
	      }
	    break;
	  case SIZE:
	    if(!list[i].isDir()){
	      it->setText(t, LUtils::BytesToDisplaySize(list[i].size()) );
	    }
	    break;
	  case TYPE:
	    it->setText(t, list[i].mimetype());
	    break;
      case DATEMOD:
        {
          QStringList datetime_format = getDateFormat();
          // Save datetime in WhatThis value. Lately will be used by CQTreeWidgetItem for sorting by date
          it->setWhatsThis(t, list[i].lastModified().toString("yyyyMMddhhmmsszzz"));
          // Default configurition. Fallback to Qt::DefaultLocaleShortDate for formats
          if(datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) );
          // Date is setted but time not. Time goes to default
          else if(!datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(Qt::DefaultLocaleShortDate));
          // Time is setted but date not. Date goes to default
          else if(datetime_format.at(0).isEmpty() && !datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(Qt::DefaultLocaleShortDate) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          // Both time and date setted.
          else
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          break;
        }
      case DATECREATE:
        {
          QStringList datetime_format = getDateFormat();
          it->setWhatsThis(DATECREATE, list[i].lastModified().toString("yyyyMMddhhmmsszzz"));
          if(datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().toString(Qt::DefaultLocaleShortDate) );
          else if(!datetime_format.at(0).isEmpty() && datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(Qt::DefaultLocaleShortDate));
          else if(datetime_format.at(0).isEmpty() && !datetime_format.at(1).isEmpty())
            it->setText(t, list[i].lastModified().date().toString(Qt::DefaultLocaleShortDate) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          else
            it->setText(t, list[i].lastModified().date().toString(datetime_format.at(0)) + " " + list[i].lastModified().time().toString(datetime_format.at(1)));
          break;
        }
	}
      }
      if(addnew){ treeWidget->addTopLevelItem(it); }
      if(tmpSel.contains(list[i].absoluteFilePath())){ it->setSelected(true); }
      if(lastdir == CDIR+"/"+list[i].fileName()){ 
	treeWidget->setCurrentItem(it);
	treeWidget->scrollToItem(it);
      }
    }else{
	//Create all the individual items for the basic list
	QListWidgetItem *it;
	  //See if there is an existing item to re-use
	  bool addnew = false;
	  QList<QListWidgetItem*> items = listWidget->findItems(list[i].fileName(), Qt::MatchExactly);
	  if(items.isEmpty()){
	    it = new QListWidgetItem();
	    addnew = true;
	  }else{ it = items.first(); }

	  it->setWhatsThis( QString(canmodify ? "cut": "copy")+"::::"+list[i].absoluteFilePath()); //used for drag and drop
	  it->setText(list[i].fileName());
	  it->setStatusTip(list[i].fileName());
	    //Since the icon/image is based on the filename - only update this for a new items (non-thumbnail)
	    // (This is the slowest part of the routine)
	    if(list[i].isImage() && (addnew || updateThumbs) ){
	      if(showThumbs){ 
		it->setIcon(LXDG::findIcon("fileview-preview","image-x-generic") );
		needThumbs << list[i].fileName();	
	      }else{ it->setIcon(LXDG::findIcon(list[i].iconfile(),"image-x-generic") ); }
	    }else if(addnew){
	      it->setIcon(LXDG::findIcon(list[i].iconfile(),"unknown") );
	    }
	listWidget->addItem(it);
	if(tmpSel.contains(list[i].absoluteFilePath())){ it->setSelected(true); }
	if(lastdir == CDIR+"/"+list[i].fileName()){ 
	  listWidget->setCurrentItem(it);
	  listWidget->scrollToItem(it);
	}
    }
    if(QTime::currentTime() > updatetime){ QApplication::processEvents(); updatetime = QTime::currentTime().addMSecs(500); }//keep the UI snappy while loading a directory
    if(DEBUG){ qDebug() << " - item finished:" << i << time.elapsed(); }
  }
  tmpSel.clear();
  if(DEBUG){ qDebug() << "Done with item loop:" << time.elapsed() << list.length(); }
  ui->actionStopLoad->setVisible(false);
  //Another check to ensure the current item is visible (or return to the same scroll position)
  if(stopload){ return; } //stop right now
  if(scrollpercent<0){
    if(showDetails){
      for(int t=0; t<treeWidget->columnCount(); t++){treeWidget->resizeColumnToContents(t); }
      if(treeWidget->currentItem()!=0){ treeWidget->scrollToItem(treeWidget->currentItem()); }
    }else{
      if(listWidget->currentItem()!=0){ listWidget->scrollToItem(listWidget->currentItem()); }
    }
  }else{
    if(showDetails){
      treeWidget->verticalScrollBar()->setValue( qRound(treeWidget->verticalScrollBar()->maximum()*scrollpercent) );
    }else{
      listWidget->horizontalScrollBar()->setValue( qRound(listWidget->horizontalScrollBar()->maximum()*scrollpercent) );
    }
  }

  
  if(stopload){ return; } //stop right now
  if(DEBUG){ qDebug() << "Assemble Status Message:" << time.elapsed(); }
  //Assemble any status message
  QString stats = QString(tr("Capacity: %1")).arg(LOS::FileSystemCapacity(CDIR));
  if(list.length()>0){
    stats.prepend("\t");
    if(numdirs < list.length()){
      //Has Files
      stats.prepend( QString(tr("Files: %1 (%2)")).arg(QString::number(list.length()-numdirs), LUtils::BytesToDisplaySize(filebytes)) );
    }
    if(numdirs > 0){
      //Has Dirs
      if(numdirs<list.length()){ stats.prepend(" / "); }//has files output already
      stats.prepend( QString(tr("Dirs: %1")).arg(QString::number(numdirs)) );
    }
    
  }
  if(stopload){ return; } //stop right now  
  if(!canmodify){ stats.prepend(tr("(Limited Access) ")); }
  ui->label_status->setText( stats.simplified() );
  if(DEBUG){ qDebug() << "DONE:" << time.elapsed(); }
  if(showThumbs){ thumbThread = QtConcurrent::run(this, &DirWidget::startLoadThumbs); }
}