//=========================================== // Lumina-DE source code // Copyright (c) 2013, Ken Moore // Available under the 3-clause BSD license // See the LICENSE file for full details //=========================================== #include "LFileDialog.h" #include "ui_LFileDialog.h" LFileDialog::LFileDialog(QWidget *parent) : QDialog(parent), ui(new Ui::LFileDialog() ){ ui->setupUi(this); //load the designer file //set the output flags to the defaults appSelected = false; setDefault = false; appExec.clear(); appPath.clear(); appFile.clear(); settings = new QSettings("lumina-desktop", "lumina-open", this); //Connect the signals/slots connect(ui->combo_apps, SIGNAL(currentIndexChanged(int)), this, SLOT(updateUI()) ); connect(ui->radio_rec, SIGNAL(toggled(bool)), this, SLOT(radioChanged()) ); connect(ui->radio_avail, SIGNAL(toggled(bool)), this, SLOT(radioChanged()) ); connect(ui->radio_custom, SIGNAL(toggled(bool)), this, SLOT(radioChanged()) ); } LFileDialog::~LFileDialog(){ } // ---------- // PUBLIC // ---------- void LFileDialog::setFileInfo(QString filename, QString extension, bool isFile){ //Set the labels for the file qDebug() << "SetFileInfo:" << filename << extension << isFile; filePath = filename; //save for later ui->label_file->setText( this->fontMetrics().elidedText( filename, Qt::ElideMiddle, 300 ) ); bool shownetwork = false; if(isFile){ ui->label_extension->setText( "("+extension+")"); } else if(extension=="email"){ ui->label_extension->setText( QString(tr("(Email Link)")) ); shownetwork = true; } else if(extension.startsWith("x-scheme-handler/")){ ui->label_extension->setText( QString(tr("(Internet URL - %1)")).arg(extension.section("/",-1)) ); shownetwork = true; } else{ui->label_extension->setText("("+extension+" link)"); } fileEXT = extension; //NOTE: this is the mime-type for the file now, not the extension generateAppList(shownetwork); } //static functions QString LFileDialog::getDefaultApp(QString extension){ if(!extension.contains("/")){ return ""; } qDebug() << "Get Default App:" << extension; return LXDG::findDefaultAppForMime(extension); } void LFileDialog::setDefaultApp(QString extension, QString appFile){ if(!extension.contains("/")){ extension = LXDG::findAppMimeForFile(appFile); } //mime type default: set on the system itself if(appFile.endsWith(".desktop")){ appFile = appFile.section("/",-1); } //only need the relative path LXDG::setDefaultAppForMime(extension, appFile); } // ----------- // PRIVATE // ----------- QStringList LFileDialog::getPreferredApplications(){ QStringList out; //First list all the applications registered for that same mimetype QString mime = fileEXT; out << LXDG::findAvailableAppsForMime(mime); //Now search the internal settings for that extension and find any applications last used QStringList keys = settings->allKeys(); for(int i=0; i<keys.length(); i++){ if(keys[i].startsWith("default/")){ continue; } //ignore the defaults (they will also be in the main) if(keys[i].toLower() == fileEXT.toLower()){ QStringList files = settings->value(keys[i]).toString().split(":::"); qDebug() << "Found Files:" << keys[i] << files; bool cleaned = false; for(int j=0; j<files.length(); j++){ if(QFile::exists(files[j])){ out << files[j]; } else{ files.removeAt(j); j--; cleaned=true; } //file no longer available - remove it } if(cleaned){ settings->setValue(keys[i], files.join(":::")); } //update the registry if(!out.isEmpty()){ break; } //already found files } } //Make sure we don't have any duplicates before we return the list out.removeDuplicates(); return out; } void LFileDialog::setPreferredApplication(QString desktopfile){ QStringList keys = settings->allKeys(); for(int i=0; i<keys.length(); i++){ if(keys[i].toLower() == fileEXT.toLower()){ QStringList files = settings->value(keys[i]).toString().split(":::"); files.removeAll(desktopfile); QStringList newfiles; newfiles << desktopfile; //Only keep the 5 most recent preferred applications per extension for(int j=0; j<5 && j<files.length(); j++){ newfiles << files[j]; } settings->setValue(keys[i], newfiles.join(":::")); return; } } //No key found for this extension - make a new one settings->setValue(fileEXT.toLower(), desktopfile); } QString LFileDialog::translateCat(QString cat){ QString out; if(cat=="Audio"){ out = tr("Audio"); } else if(cat=="Video"){ out = tr("Video"); } else if(cat=="Multimedia"){ out = tr("Multimedia"); } else if(cat=="Development"){ out = tr("Development"); } else if(cat=="Education"){ out = tr("Education"); } else if(cat=="Game"){ out = tr("Game"); } else if(cat=="Graphics"){ out = tr("Graphics"); } else if(cat=="Network"){ out = tr("Network"); } else if(cat=="Office"){ out = tr("Office"); } else if(cat=="Science"){ out = tr("Science"); } else if(cat=="Settings"){ out = tr("Settings"); } else if(cat=="System"){ out = tr("System"); } else if(cat=="Utility"){ out = tr("Utilities"); } else if(cat=="Other"){ out = tr("Other"); } else{ out = cat; } return out; } // ----------------- // PRIVATE SLOTS // ----------------- void LFileDialog::updateUI(){ //Check for a selected application bool good = false; if(ui->radio_custom->isChecked()){ if(!ui->line_bin->text().isEmpty()){ QString bin = ui->line_bin->text(); good = LUtils::isValidBinary(bin); //Now verify that the file exists and is executable if( good ){ ui->label_goodbin->setPixmap(QPixmap(":/icons/good.png")); }else{ ui->label_goodbin->setPixmap(QPixmap(":/icons/bad.png")); } } } else if(ui->radio_rec->isChecked()){ good = true; //a valid app is always selected on this page if it is available } else if(ui->combo_apps->count() > 0 && !ui->combo_apps->currentData().toString().isEmpty() ){ good=true; } ui->tool_ok->setEnabled(good); } void LFileDialog::generateAppList(bool shownetwork){ //Now load the preferred applications XDGDesktopList applist; applist.updateList(); PREFAPPS = getPreferredApplications(); qDebug() << "Preferred Apps:" << PREFAPPS; ui->combo_rec->clear(); //Now get the application mimetype for the file extension (if available) QStringList mimetypes = LXDG::findAppMimeForFile(filePath, true).split("::::"); //use all mimetypes mimetypes.removeDuplicates(); QString defapp = getDefaultApp(mimetypes.first()); //default application if(!defapp.isEmpty() && !PREFAPPS.contains(defapp) ){ PREFAPPS << defapp; } //ensure this is listed in the preferred apps list //Now add all the detected applications QHash< QString, QList<XDGDesktop*> > hash = LXDG::sortDesktopCats( applist.apps(false,true) ); QStringList cat = hash.keys(); cat.sort(); //sort alphabetically ui->combo_apps->clear(); for(int c=0; c<cat.length(); c++){ QList<XDGDesktop*> app = hash[cat[c]]; if(app.length()<1){ continue; } if(ui->combo_apps->count() >1){ ui->combo_apps->insertSeparator(ui->combo_apps->count()); } ui->combo_apps->addItem(translateCat(cat[c])); ui->combo_apps->insertSeparator(ui->combo_apps->count()); for(int a=0; a<app.length(); a++){ if(shownetwork && (cat[c].toLower()=="network" || cat[c].toLower()=="utility") ){ //Need to show preferred internet applications - look for ones that handle URL's if(app[a]->exec.contains("%u") || app[a]->exec.contains("%U")){ //qDebug() << "Add to Preferred Apps:" << app[a]->filePath; PREFAPPS << app[a]->filePath; } } ui->combo_apps->addItem(LXDG::findIcon(app[a]->icon, "application-x-desktop"), app[a]->name, app[a]->filePath); //Check to see if this app matches the mime type if(!mimetypes.isEmpty()){ QStringList tmp = mimetypes; tmp << app[a]->mimeList; if(tmp.removeDuplicates() > 0 ){ // also put this app in the preferred list //qDebug() << "Mimetype match:" << mimetypes << app[a]->mimeList; PREFAPPS.append(app[a]->filePath); //If this is the first preferred app found - select this app initially if(ui->combo_apps->currentIndex()<=0){ ui->combo_apps->setCurrentIndex(ui->combo_apps->count()-1); } } } } } if(ui->combo_apps->currentIndex()<=0){ ui->combo_apps->setCurrentIndex(2); } //Start on the first "real" app - not the first category header //Now add all the preferred applications PREFAPPS.removeDuplicates(); for(int i=0; i<PREFAPPS.length(); i++){ XDGDesktop dFile(PREFAPPS[i]); if( dFile.isValid() ){ QString txt = dFile.name; if(PREFAPPS[i] == defapp){ txt.prepend( tr("[default] ") ); } ui->combo_rec->addItem( LXDG::findIcon(dFile.icon, "application-x-desktop"), txt); if(i==0){ ui->combo_rec->setCurrentIndex(0); } //make sure the first item is selected }else{ PREFAPPS.removeAt(i); //invalid app i--; } } //Update the UI if(PREFAPPS.isEmpty()){ ui->radio_rec->setEnabled(false); //no preferred apps ui->radio_avail->setChecked(true); }else{ ui->radio_rec->setChecked(true); } } void LFileDialog::radioChanged(){ if(ui->radio_rec->isChecked()){ ui->stackedWidget->setCurrentWidget(ui->page_rec); }else if(ui->radio_avail->isChecked()){ ui->stackedWidget->setCurrentWidget(ui->page_avail); }else{ ui->stackedWidget->setCurrentWidget(ui->page_custom); } //ui->check_default->setEnabled( !ui->radio_custom->isChecked() ); updateUI(); } /*void LFileDialog::on_group_binary_toggled(bool checked){ ui->label_goodbin->setVisible(checked); ui->line_bin->setVisible(checked); ui->tool_findBin->setVisible(checked); updateUI(); }*/ void LFileDialog::on_tool_ok_clicked(){ appSelected = true; setDefault = ui->check_default->isChecked(); if(ui->radio_custom->isChecked()){ appExec = ui->line_bin->text(); }else if(ui->radio_rec->isChecked()){ //application selected XDGDesktop app(PREFAPPS[ui->combo_rec->currentIndex()]); //Set the output variables appExec = app.getDesktopExec(); appPath = app.path; appFile = app.filePath; setPreferredApplication(app.filePath); //bump this to the top of the preferred list for next time }else{ //application selected XDGDesktop app(ui->combo_apps->currentData().toString()); //Set the output variables appExec = app.getDesktopExec(); appPath = app.path; appFile = app.filePath; setPreferredApplication(app.filePath); //save this app to this extension as a recommendation } this->close(); } void LFileDialog::on_tool_cancel_clicked(){ appSelected = false; this->close(); } void LFileDialog::on_tool_findBin_clicked(){ QString filepath = QFileDialog::getOpenFileName(this, tr("Find Application Binary"), QDir::homePath() ); if(filepath.isEmpty()){ return; } ui->line_bin->setText(filepath); } void LFileDialog::on_line_bin_textChanged(){ updateUI(); }