source: src-qt4/EasyPBI/mainGUI.cpp @ 850f9fa

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3
Last change on this file since 850f9fa was da99d41, checked in by Ken Moore <ken@…>, 16 months ago

Fix a couple display quirks with AppCafe2 and EasyPBI

  • Property mode set to 100644
File size: 64.3 KB
Line 
1#include "mainGUI.h"
2#include "ui_mainGUI.h"
3#include "modBuild.h"
4#include "backend.h"
5#include "newModuleDialog.h"
6#include "preferencesDialog.h"
7#include "aboutDialog.h"
8
9MainGUI::MainGUI(QWidget *parent) :
10    QMainWindow(parent),
11    ui(new Ui::MainGUI)
12{
13        // NOTE: "plus"/"minus" icons are set in QtDesigner using the current theme
14        //      since none are available in the Qt Embedded resources
15       
16       //Setup Initial state of GUI objects and connect signal/slots
17       ui->setupUi(this);  //load the mainGUI.ui file
18        // Create the module class as necessary
19        currentModule = new ModBuild();
20        // Create the config class
21        settings = new Config();
22        //Setup the Menu items
23        ui->actionExit->setIcon(Backend::icon("close"));
24        ui->actionRefresh_Module->setIcon(Backend::icon("refresh"));
25        //Setup the pushbutton menu lists
26        menu_elOpts.addAction("binary");
27        menu_elOpts.addAction("linux");
28        menu_elOpts.addAction("keep");
29        menu_elOpts.addAction("replace");
30        menu_elOpts.addAction("nocrash");
31        //Setup Toolbar
32        ui->actionNew_Module->setIcon(Backend::icon("new"));
33        ui->actionLoad_Module->setIcon(Backend::icon("load"));
34        line_module = new QLineEdit(this);
35        line_module->setPlaceholderText(tr("No Module Loaded"));
36        line_module->setReadOnly(TRUE);
37        line_module->setFocusPolicy(Qt::NoFocus);
38        ui->toolBar->addWidget(line_module);
39        ui->toolBar->addSeparator();
40        radio_module_port = new QRadioButton(tr("FreeBSD Port"),this);
41        radio_module_port->setEnabled(FALSE);
42        ui->toolBar->addWidget(radio_module_port);
43        radio_module_local = new QRadioButton(tr("Local Sources"),this);
44        radio_module_local->setEnabled(FALSE);
45        ui->toolBar->addWidget(radio_module_local);
46        //Setup Module Editor
47        connect(ui->tabWidget, SIGNAL(currentChanged(int)),this,SLOT(slotModTabChanged(int)) ); //setup to refresh each tab once it is selected
48        // -- pbi.conf tab --
49        ui->push_change_progdir->setIcon(Backend::icon("load"));
50        ui->push_change_makeport->setIcon(Backend::icon("file"));
51        ui->push_addmakeopt->setIcon(Backend::icon("left"));
52        ui->push_addmakeopt->setMenu(&menu_addOpt);
53        connect(&menu_addOpt,SIGNAL(triggered(QAction*)),this,SLOT(slotAddMakeOption(QAction*)) );
54        ui->push_config_save->setIcon(Backend::icon("save"));
55        // -- resources tab --
56        ui->push_resources_savewrapper->setIcon(Backend::icon("save"));
57        connect(ui->listw_resources, SIGNAL(itemSelectionChanged()), this, SLOT(slotResourceChanged()) );
58        connect(ui->push_resources_savewrapper, SIGNAL(clicked()), this, SLOT(slotResourceScriptSaved()) );
59        // -- XDG entries tab --
60        connect(ui->radio_xdg_desktop,SIGNAL(clicked()),this,SLOT(slotXdgTypeChanged()) );
61        connect(ui->radio_xdg_menu,SIGNAL(clicked()),this,SLOT(slotXdgTypeChanged()) );
62        connect(ui->list_xdg_files,SIGNAL(itemSelectionChanged()), this, SLOT(slotXdgFileChanged()) );
63        ui->push_xdg_refresh->setIcon(Backend::icon("refresh"));
64        connect(ui->push_xdg_refresh, SIGNAL(clicked()), this, SLOT(slotXdgTypeChanged()) );
65        ui->push_xdg_exec->setIcon(Backend::icon("left"));
66        ui->push_xdg_exec->setMenu(&menu_bins);
67        connect(&menu_bins, SIGNAL(triggered(QAction*)), this, SLOT(slotAddBin(QAction*)) );
68        ui->push_xdg_savechanges->setIcon(Backend::icon("save"));
69        ui->push_xdg_menu->setIcon(Backend::icon("left"));
70        ui->push_xdg_menu->setMenu(&menu_validMenuCats);
71        connect(&menu_validMenuCats,SIGNAL(triggered(QAction*)),this,SLOT(slotAddMenuCat(QAction*)) );
72        ui->push_xdg_clearentry->setIcon(Backend::icon("file"));
73       
74        // -- Scripts tab --
75        ui->push_scripts_save->setIcon(Backend::icon("save"));
76        ui->push_scripts_create->setIcon(Backend::icon("new"));
77        ui->list_scripts_file->addItems(QStringList() << " ---"+tr("Installation Scripts")+"---" << "pre-portmake.sh" << "post-portmake.sh" << "pre-pbicreate.sh" << "pre-install.sh" << "post-install.sh" << "pre-remove.sh" );
78        connect(ui->list_scripts_file, SIGNAL(currentIndexChanged(int)), this, SLOT(slotScriptChanged(int)) );
79        // -- External links tab --
80        ui->push_el_file->setIcon(Backend::icon("left"));
81        ui->push_el_file->setMenu(&menu_el_bins);
82        connect(&menu_el_bins,SIGNAL(triggered(QAction*)),this,SLOT(slotELSetFile(QAction*)) );
83        ui->push_el_filetype->setIcon(Backend::icon("left"));
84        ui->push_el_filetype->setMenu(&menu_elOpts);
85        connect(&menu_elOpts,SIGNAL(triggered(QAction*)),this,SLOT(slotELSetType(QAction*)) );
86        //Setup PBI Builder
87        ui->push_build_stop->setIcon(Backend::icon("close"));
88        ui->push_build_save->setIcon(Backend::icon("save"));
89       
90      SetupDefaults(); //load program defaults
91      refreshGUI("all"); //make items visible/invisible as necessary
92     
93      //Connect "option changed" signals to the respective slot
94      // PBI tab
95      connect(ui->line_progname,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
96      connect(ui->line_progauthor,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
97      connect(ui->line_progversion,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
98      connect(ui->line_progweb,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
99      connect(ui->line_progdir,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
100      connect(ui->line_makeport,SIGNAL(textChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
101      connect(ui->list_progicon,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotOptionChanged(QString)) );
102      connect(ui->edit_makeopts,SIGNAL(textChanged()),this,SLOT(slotOptionChanged()) );
103      connect(ui->check_requiresroot, SIGNAL(clicked()),this,SLOT(slotOptionChanged()) );
104      // Rwsources tab
105      connect(ui->text_resources_script,SIGNAL(textChanged()),this,SLOT(slotResourceScriptChanged()) );
106      // XDG tab
107      connect(ui->line_xdg_name,SIGNAL(textChanged(QString)),this,SLOT(slotXDGOptionChanged(QString)) );
108      connect(ui->line_xdg_mimepatterns,SIGNAL(textChanged(QString)),this,SLOT(slotXDGOptionChanged(QString)) );
109      connect(ui->line_xdg_exec,SIGNAL(textChanged(QString)),this,SLOT(slotXDGOptionChanged(QString)) );
110      connect(ui->line_xdg_menu,SIGNAL(textChanged(QString)),this,SLOT(slotXDGOptionChanged(QString)) );
111      connect(ui->check_xdg_nodisplay,SIGNAL(clicked()),this,SLOT(slotXDGOptionChanged()) );
112      connect(ui->check_xdg_requiresroot,SIGNAL(clicked()),this,SLOT(slotXDGOptionChanged()) );
113      connect(ui->check_xdg_terminal,SIGNAL(clicked()),this,SLOT(slotXDGOptionChanged()) );
114      connect(ui->list_xdg_icon,SIGNAL(currentIndexChanged(QString)),this,SLOT(slotXDGOptionChanged(QString)) );
115      // Scripts tab
116      connect(ui->text_scripts_edit,SIGNAL(textChanged()),this,SLOT(slotScriptModified()) );
117       
118}
119
120MainGUI::~MainGUI()
121{
122  qDebug() << "Shutting down EasyPBI normally";
123}
124
125void PBM::checkGroupOperator()
126{
127   QString loginName = getlogin();
128   QStringList gNames;
129   if ( loginName == "root" )
130     return;
131
132   QString tmp;
133   QFile iFile("/etc/group");
134   if ( ! iFile.open(QIODevice::ReadOnly | QIODevice::Text))
135     return;
136               
137   while ( !iFile.atEnd() ) {
138     tmp = iFile.readLine().simplified();
139     if ( tmp.indexOf("operator") == 0 ) {
140        gNames = tmp.section(":", 3, 3).split(",");
141        break;
142     }
143   }
144   iFile.close();
145       
146   for ( int i = 0; i < gNames.size(); ++i )
147      if ( gNames.at(i).indexOf(loginName) == 0 )
148            return;
149
150   QMessageBox::information( this, tr("Error!"), tr("Installing applications has been disabled for this user. Please add the user to the operator group or restart as root.") );
151   close(); 
152}
153
154void MainGUI::slotSingleInstance(){
155  this->showNormal();
156  this->activateWindow();
157  this->raise();
158}
159
160void MainGUI::SetupDefaults(){
161    qDebug() << "Starting up EasyPBI (version "+settings->value("version")+")"; 
162    //Make sure that the program is not being started with root permissions
163    QString id = QProcessEnvironment::systemEnvironment().toStringList().filter("HOME=").join(" ").simplified();
164    if( id.contains("root") ){
165      qDebug() << "EasyPBI should not be run with root permissions! exiting.....";
166      exit(1);
167    }
168
169    //Load the current configuration settings
170    settings->readMachineArch(); //set the 64-bit flag as appropriate
171    //Scan for the external utilities needed to build PBI's
172    settings->scanForExternalUtilities();
173    //Load Preferences file if possible
174    settings->loadSettingsFile();
175    //create the EasyPBI directory structure if needed
176    if( !settings->checkDirectoryStructure() ){
177        QMessageBox::warning(this,tr("Permissions Error"), tr("There was an error trying to create the local EasyPBI directory structure. Please check the permissions for your home directory and restart EasyPBI.") );
178        exit(1);
179    }
180    //Pop up a warning box if some external resources are not available
181    bool chkOK = (settings->check("isMakeportAvailable") && settings->check("iscreateAvailable") && settings->check("isSUavailable") );
182    if( !chkOK ){
183        QMessageBox::warning(this, tr("Resources Unavailable"), tr("Some external resources could not be found, so the EasyPBI services that use these resources have been deactivated.")+"\n"+tr("Please open up the EasyPBI settings to correct this deficiency.") );
184    }
185    //Pop up a warning about a missing ports tree
186    if( !settings->check("isPortsAvailable") ){
187        QMessageBox::warning(this, tr("FreeBSD Ports Missing"), tr("The FreeBSD ports tree is missing from your system.")+"\n"+tr("Please open up the EasyPBI settings to correct this deficiency.") );
188    }
189    //Set a couple more internal flags
190    PBI_BUILDING_NOW.clear();
191    PBI_BUILD_TERMINATED=FALSE;
192}
193
194bool MainGUI::isValidPort(QString pPath){
195  bool ok = FALSE;
196  if( QFile::exists(pPath) && QFile::exists(pPath+"/Makefile") && QFile::exists(pPath+"/distinfo") ){
197    ok = TRUE;
198  }
199  return ok;
200}
201
202void MainGUI::refreshGUI(QString item){
203  //Enable/disable the interface appropriately
204 
205  //Stupid check to make sure that a module is actually loaded
206  if( currentModule->path().isEmpty() ){ 
207    ui->actionPackage_Module->setEnabled(FALSE);
208    ui->actionRefresh_Module->setEnabled(FALSE);
209    if(PBI_BUILDING_NOW.isEmpty() ){ui->toolBox->setEnabled(FALSE); return; }
210    else{ 
211      ui->toolBox->setItemEnabled(0,FALSE);
212      ui->toolBox->setItemEnabled(1,TRUE);
213      ui->toolBox->setCurrentIndex(1); 
214      item="pbibuild";
215    }
216  }else{ 
217    ui->toolBox->setEnabled(TRUE); 
218    ui->actionPackage_Module->setEnabled(TRUE); 
219    ui->actionRefresh_Module->setEnabled(TRUE);
220  }
221  //Figure out the type of module that is loaded
222  bool isport = radio_module_port->isChecked();
223  //See if we should refresh everything (default) 
224  bool doall = ( (item == "all") || item.isEmpty() );
225  bool doeditor = (item == "editor"); //also add a flag to just refresh the editor
226  //Refresh the desired tab(s)
227  // ------PBI.CONF------
228  if( doall || doeditor || (item == "pbiconf")){
229    if(isport){
230        ui->line_progversion->setVisible(FALSE); ui->label_progversion->setVisible(FALSE);
231        ui->line_progdir->setVisible(FALSE); ui->push_change_progdir->setVisible(FALSE); ui->label_progdir->setVisible(FALSE);
232        ui->line_makeport->setVisible(TRUE); ui->push_change_makeport->setVisible(TRUE); ui->label_makeport->setVisible(TRUE);
233        ui->edit_makeopts->setVisible(TRUE); ui->push_addmakeopt->setVisible(TRUE); ui->label_makeopts->setVisible(TRUE);
234        ui->list_portbefore->setVisible(TRUE); ui->push_addportbefore->setVisible(TRUE); ui->push_rmportbefore->setVisible(TRUE);ui->label_portbefore->setVisible(TRUE);
235        ui->list_portafter->setVisible(TRUE); ui->push_addportafter->setVisible(TRUE); ui->push_rmportafter->setVisible(TRUE); ui->label_portafter->setVisible(TRUE);
236    }else{
237        ui->line_progversion->setVisible(TRUE); ui->label_progversion->setVisible(TRUE);
238        ui->line_progdir->setVisible(TRUE); ui->push_change_progdir->setVisible(TRUE); ui->label_progdir->setVisible(TRUE);
239        ui->line_makeport->setVisible(FALSE); ui->push_change_makeport->setVisible(FALSE); ui->label_makeport->setVisible(FALSE);
240        ui->edit_makeopts->setVisible(FALSE); ui->push_addmakeopt->setVisible(FALSE); ui->label_makeopts->setVisible(FALSE);
241        ui->list_portbefore->setVisible(FALSE); ui->push_addportbefore->setVisible(FALSE); ui->push_rmportbefore->setVisible(FALSE);ui->label_portbefore->setVisible(FALSE);
242        ui->list_portafter->setVisible(FALSE); ui->push_addportafter->setVisible(FALSE); ui->push_rmportafter->setVisible(FALSE); ui->label_portafter->setVisible(FALSE);
243    }
244    //Display the variables from the currentModule structure
245    // -- check boxes
246    QString chk = currentModule->readValue("requiresroot").toLower();
247    if( (chk=="true") || (chk=="yes") ){ ui->check_requiresroot->setChecked(TRUE); }
248    else{ ui->check_requiresroot->setChecked(FALSE); }
249    // -- line edits
250    ui->line_progname->setText(currentModule->readValue("progname"));
251    ui->line_progversion->setText(currentModule->readValue("progversion"));
252    ui->line_progweb->setText(currentModule->readValue("progweb"));
253    ui->line_progauthor->setText(currentModule->readValue("progauthor"));
254    ui->line_progdir->setText(currentModule->readValue("packagedir"));
255    ui->line_makeport->setText(currentModule->readValue("makeport"));
256    ui->edit_makeopts->setPlainText(currentModule->readValue("makeoptions"));
257    // -- combo boxes (lists)
258    ui->list_portbefore->clear(); ui->list_portafter->clear(); ui->list_progicon->clear();
259    ui->list_portbefore->addItems( currentModule->readValue("makeportbefore").split(" ") );
260    ui->list_portafter->addItems( currentModule->readValue("makeportafter").split(" ") );
261    QStringList icons = currentModule->currentIcons;
262    if(icons.length() > 0){
263      for(int i=0; i<icons.length(); i++){
264        ui->list_progicon->addItem(QIcon(currentModule->path()+"/resources/"+icons[i]),icons[i]);
265      }     
266      int cicon = icons.indexOf(currentModule->readValue("progicon"));
267      if( cicon == -1 ){ 
268              ui->list_progicon->addItem(currentModule->readValue("progicon")); 
269              cicon = icons.indexOf(currentModule->readValue("progicon"));
270      }
271      ui->list_progicon->setCurrentIndex(cicon);
272    }else{
273      ui->list_progicon->addItem(currentModule->readValue("progicon"));
274    }
275    menu_addOpt.clear();
276    QStringList opts = currentModule->readValue("portoptions").split(" ",QString::SkipEmptyParts);
277    if(!opts.isEmpty()){
278      for(int i=0; i<opts.length(); i++){
279        menu_addOpt.addAction(opts[i]);
280      }
281    }
282    ui->push_config_save->setEnabled(FALSE);  //disable the save button until something changes
283  }
284  // -----RESOURCES--------
285  if( doall || doeditor || (item == "resources")){
286    //Get the all the current files in the resources category and add them to the list
287    QStringList rs = currentModule->filesAvailable("resources");
288    //disconnect the signal/slot connection to make sure we don't get an extra phantom refresh
289    disconnect(ui->listw_resources, SIGNAL(itemSelectionChanged()), this, SLOT(slotResourceChanged()) );
290    //Update the Widget
291    ui->listw_resources->clear();
292    ui->listw_resources->addItems(rs);
293    //re-connect the signal/slot
294    connect(ui->listw_resources, SIGNAL(itemSelectionChanged()), this, SLOT(slotResourceChanged()) );
295    //Load the file into the viewers
296    slotResourceChanged();
297  }
298  //------XDG------
299  if( doall || doeditor || (item == "xdg")){
300    slotXdgTypeChanged();
301  }
302  //------SCRIPTS-----
303  if( doall || doeditor || (item == "scripts")){
304    //Update the list of available scripts and determine if one needs to be read
305    bool loadScript = FALSE;
306    QString path = currentModule->path()+"/scripts/";
307    int currentIndex = ui->list_scripts_file->currentIndex();
308    for(int i=1; i< ui->list_scripts_file->count(); i++){ //Skip the first item (is nothing)
309      if( QFile::exists( path+ui->list_scripts_file->itemText(i) ) ){
310        if(i == currentIndex){ loadScript = TRUE; }
311        ui->list_scripts_file->setItemIcon(i,Backend::icon("file"));
312      }else{
313        ui->list_scripts_file->setItemIcon(i,Backend::icon("close"));
314      }
315    }
316    //Update the GUI appropriately
317    if(loadScript){
318      //Read and display the script
319      QStringList contents = ModBuild::readFile(path+ui->list_scripts_file->currentText());
320      ui->text_scripts_edit->setPlainText(contents.join("\n"));
321      //Setup display items
322      ui->push_scripts_create->setVisible(FALSE);
323      ui->push_scripts_remove->setVisible(TRUE);
324      ui->push_scripts_save->setVisible(TRUE);
325      ui->text_scripts_edit->setVisible(TRUE);
326    }else{
327      //Setup display items
328      ui->push_scripts_create->setVisible(TRUE);
329      ui->push_scripts_remove->setVisible(FALSE);
330      ui->push_scripts_save->setVisible(FALSE);
331      ui->text_scripts_edit->setVisible(FALSE);
332    }
333    if(currentIndex == 0){ ui->push_scripts_create->setVisible(FALSE); }
334    ui->push_scripts_save->setEnabled(FALSE); //disable the save button until something changes
335   
336  }
337  //------EXTERNAL-LINKS------
338  if( doall || doeditor || (item == "external-links")){
339    //nothing to make visible/invisible here
340    //Load the external-links file
341    ui->tree_el_view->clear();
342    QStringList cLinks = currentModule->externalLinks();
343    QStringList labels; labels << tr("File") << tr("Link To") << tr("File Type");
344    for( int i=0; i<cLinks.length(); i++ ){
345      QStringList link = cLinks[i].split("\t");
346      ui->tree_el_view->addTopLevelItem(new QTreeWidgetItem(link));
347    }
348    //Clear the input boxes
349    ui->line_el_file->clear();
350    ui->line_el_linkto->clear();
351    ui->line_el_filetype->clear();
352    //update the available binaries
353    menu_el_bins.clear();
354    QStringList cBins = currentModule->currentBins;
355    if(!cBins.isEmpty()){
356      for(int i=0; i<cBins.length(); i++){
357        menu_el_bins.addAction(cBins[i]);
358      } 
359    }
360  }
361  //------FREENAS PLUGINS-------
362  if( doall || doeditor || (item == "freenas")){
363    //nothing to make visible/invisible here
364  }
365  //------PBI BUILDER--------
366  if( doall || (item == "pbibuild")){
367    if(PBI_BUILDING_NOW.isEmpty()){
368      //only change things if there is nothing building at the moment
369      if(ui->text_build_log->toPlainText().isEmpty()){ ui->push_build_save->setEnabled(FALSE); }
370      else{ ui->push_build_save->setEnabled(TRUE); }
371    }
372    ui->push_build_start->setFocus();//make sure the focus starts out on the build button
373  }
374  //------OVERALL SETTINGS------
375  if( doall || doeditor ){
376    //Enable/disable the buttons that require the FreeBSD ports tree
377    if( settings->check("isportsavailable") ){
378      ui->push_change_makeport->setEnabled(TRUE);
379      ui->push_addportbefore->setEnabled(TRUE);
380      ui->push_addportafter->setEnabled(TRUE);
381    }else{
382      ui->push_change_makeport->setEnabled(FALSE);
383      ui->push_addportbefore->setEnabled(FALSE);
384      ui->push_addportafter->setEnabled(FALSE);
385    }
386    //Check for a 64-bit system to enable the 32-bit build option
387    if( settings->check("is64bit") && !currentModule->isLocalPBI ){ ui->check_build_32->setVisible(TRUE); }
388    else{ ui->check_build_32->setVisible(FALSE); ui->check_build_32->setChecked(FALSE); }
389    //Disable tabs that are not used when bulding local PBI's
390    if(currentModule->isLocalPBI){
391        ui->tabWidget->setTabEnabled(5,FALSE);
392    }else{
393        ui->tabWidget->setTabEnabled(5,TRUE);
394    }
395    //Set the default focus on the "load" button
396    this->setFocus();
397  }
398}
399/*----------------------------------
400   MENU OPTIONS
401  -----------------------------------
402*/
403
404void MainGUI::on_actionExit_triggered(){
405  qDebug() << "Close EasyPBI requested";
406  this->close();
407}
408
409void MainGUI::on_actionPreferences_triggered(){
410  //Open up the preferences dialog
411  PreferencesDialog dlg(this);
412  //make the dialog modal and wait for it to close
413  dlg.exec(); 
414  //Now reload the saved settings
415  settings->loadSettingsFile();
416  //Now refresh the GUI
417  refreshGUI("all");
418}
419void MainGUI::on_actionPackage_Module_triggered(){
420   currentModule->compressModule();
421   QMessageBox::information(this,tr("Success"),tr("A copy of the current module has been successfully packaged  within the module directory.") );
422
423}
424
425void MainGUI::on_actionRefresh_Module_triggered(){
426  QString modSel = currentModule->path(); //re-load the current module
427  bool ok = currentModule->loadModule(modSel); 
428  if(ok){ 
429    qDebug() << "Loaded module:"<<modSel;         
430    line_module->setText(modSel.replace(QDir::homePath(),"~")); 
431    if(currentModule->isLocalPBI){ radio_module_local->toggle(); }
432    else{ 
433      radio_module_port->toggle(); //Port PBI
434      if( settings->check("isportsavailable") ){ 
435        currentModule->readPortInformation(settings->value("portsdir")+"/"+currentModule->readValue("makeport"));
436      }
437    }
438    refreshGUI("all");
439  }
440}
441
442void MainGUI::on_actionFreeBSD_Ports_triggered(){
443  QString port;
444  if(!line_module->text().isEmpty()){
445        //Get the currently selected port
446        port = currentModule->readValue("makeport");
447  }
448  QString target_url = "http://www.freshports.org/" + port;
449  qDebug() << "Opening URL:" << target_url; 
450  target_url.prepend("xdg-open ");
451  system(target_url.toUtf8()); 
452}
453
454void MainGUI::on_actionPBI_Modules_triggered(){
455  //Open the PC-BSD wiki to the module builders guide
456   QString target_url = "http://wiki.pcbsd.org/index.php/PBI_Module_Builder_Guide";
457   qDebug() << "Opening URL:" << target_url; 
458   target_url.prepend("xdg-open ");
459   system(target_url.toUtf8());
460}
461
462void MainGUI::on_actionAbout_EasyPBI_triggered(){
463  aboutDialog dlg(this,settings->value("version"));
464  dlg.exec();
465}
466
467
468/*----------------------------------
469   TOOLBAR OPTIONS
470  -----------------------------------
471*/
472void MainGUI::on_actionNew_Module_triggered(){
473  qDebug() << "New Module triggered";
474  //Create and run the new dialog
475  NewModuleDialog* dlg = new NewModuleDialog(this, settings->value("portsdir"));
476  dlg->setDefaultIconFile(settings->value("defaulticon"));
477  dlg->exec();
478  //Determine if the action was cancelled
479  if( dlg->isAccepted ){
480    //Now create the new module
481    QString modPath, modType, modBase, oldIconPath;
482    modType = dlg->moduleType;
483    modBase = dlg->moduleData;
484    oldIconPath = dlg->moduleIcon;
485    modPath = settings->value("moduledir")+"/"+modBase.section("/",-1).toLower();
486          //modPath ->full path, modType->"local"or "port", modBase->makeport or packagedir
487    bool ok = currentModule->createNewModule(modPath,modType,modBase);
488    if(!ok){
489      QMessageBox::warning(this,tr("EasyPBI: Permissions Error"), tr("Could not create PBI module. Please check the directory permissions and try again."));
490    }else{
491      //MODULE CREATED, NOW FILL IT APPROPRIATELY
492      //Icon
493      currentModule->addResource(FALSE, oldIconPath); //copy the icon file into the module
494      currentModule->writeValue("progicon", oldIconPath.section("/",-1) );
495      //Load Port info if appropriate
496      if(currentModule->isPortPBI){
497        radio_module_port->toggle();
498        //Use the port info if possible
499        if( settings->check("isportsAvailable") ){
500          currentModule->readPortInformation(settings->value("portsdir")+"/"+modBase);
501          //Now save the detected information into the module
502          currentModule->writeValue("progname", currentModule->readValue("portname"));
503          currentModule->writeValue("progweb", currentModule->readValue("portwebsite"));
504          currentModule->writeValue("progauthor", currentModule->readValue("portauthor"));
505          currentModule->writePBIconf();
506        }
507      }else if(currentModule->isLocalPBI){
508        radio_module_local->toggle();
509             
510      }
511      //Now let the UI reflect the new module
512      line_module->setText( currentModule->path().replace(QDir::homePath(),"~") );     
513    }
514  }
515  //Refresh the UI
516  refreshGUI("all");
517  delete dlg;
518}
519
520void MainGUI::on_actionLoad_Module_triggered(){
521  QString modSel = QFileDialog::getExistingDirectory(this, tr("Select Module"), settings->value("moduledir"));
522  if(modSel.isEmpty()){return;} //action cancelled or closed
523  bool ok = currentModule->loadModule(modSel);
524  if(ok){ 
525    qDebug() << "Loaded module:"<<modSel;         
526    line_module->setText(modSel.replace(QDir::homePath(),"~")); 
527    if(currentModule->isLocalPBI){ radio_module_local->toggle(); }
528    else{ 
529      radio_module_port->toggle(); //Port PBI
530      if( settings->check("isportsavailable") ){ 
531        currentModule->readPortInformation(settings->value("portsdir")+"/"+currentModule->readValue("makeport"));
532      }
533    }
534    refreshGUI("all");
535  }
536}
537
538/*----------------------------------
539   MODULE EDITOR OPTIONS
540  -----------------------------------
541*/
542void MainGUI::slotModTabChanged(int newtab){
543  switch(newtab){
544    case 0:
545            refreshGUI("pbiconf"); break;
546    case 1:
547            refreshGUI("resources"); break;
548    case 2:
549            refreshGUI("xdg"); break;
550    case 3:
551            refreshGUI("scripts"); break;
552    case 4:
553            refreshGUI("external-links"); break;
554    case 5:
555            refreshGUI("freenas"); break;
556    default:
557            refreshGUI("editor"); break; //do all the module editor tabs
558  }       
559}
560
561/*----------------------------------
562   PBI.CONF OPTIONS
563  -----------------------------------
564*/
565void MainGUI::on_push_change_makeport_clicked(){
566  if( !settings->check("isportsavailable") ){
567    //No ports tree available
568    QMessageBox::warning(this,tr("EasyPBI: No FreeBSD Ports"), tr("The FreeBSD Ports tree could not be found on your system. You may fetch the ports tree through the EasyPBI menu or manually set the path to the port tree in the EasyPBI preferences if it is installed in a non-standard location."));
569    return;
570  }
571  //Prompt for a new port
572  QString portSel = QFileDialog::getExistingDirectory(this, tr("Select Port"), settings->value("portsdir"));
573  if(portSel.isEmpty()){return;} //action cancelled or closed   
574  //Check if the port is valid
575  if( !isValidPort(portSel) ){
576    QMessageBox::warning(this,tr("EasyPBI: Invalid Port"), tr("The directory selected is not a valid FreeBSD port. Please select a port directory which contains the appropriate Makefile and distinfo."));
577    return;
578  }
579  //Save the port info to the GUI
580  ui->line_makeport->setText(portSel.remove(settings->value("portsdir")+"/"));
581  ui->push_config_save->setEnabled(TRUE);
582}
583
584void MainGUI::on_push_change_progdir_clicked(){
585  //Prompt for a new directory
586  QString dirSel = QFileDialog::getExistingDirectory(this, tr("Select Package Directory"), QDir::homePath());
587  if(dirSel.isEmpty()){return;} //action cancelled or closed   
588  //Save the port info to the GUI
589  ui->line_progdir->setText(dirSel);
590  ui->push_config_save->setEnabled(TRUE);
591}
592
593void MainGUI::slotAddMakeOption(QAction* act){
594  qDebug() << "Trying to add build option:" << act->text();
595  QString opt = act->text();
596  if(opt.isEmpty() ){ return; } //Do nothing if nothing selected
597  //Check whther the option is set or unset
598  QString typ = opt.section("_",0,0,QString::SectionSkipEmpty).toLower(); //get the type
599  opt = opt.section("_",1,50,QString::SectionSkipEmpty); //trim off the type of setting
600  QString chk = currentModule->readValue("makeport").section("/",-1);
601  bool isSet;
602  if(typ == "with"){chk.append("_SET"); isSet=TRUE;}
603  else if(typ=="without"){chk.append("_UNSET"); isSet=FALSE;}
604  else{ qDebug() << "Error: Unknown option type:"<<typ<<"option:"<<opt; return; }
605  //Now read the current option settings
606  QStringList curr = ui->edit_makeopts->toPlainText().split("\n"); //split according to lines
607  bool found = FALSE;
608  for(int i=0; i<curr.length(); i++){
609    if(curr[i].contains(chk) ){ //look for optionsNG framework
610      found = TRUE;         
611      QStringList cOpts = curr[i].split(" ",QString::SkipEmptyParts);
612      if( !cOpts.contains(opt) ){
613        //Not found, add it to the end of the list
614        cOpts << opt;
615        curr[i] = cOpts.join(" ");
616      }
617    }else if(curr[i].contains(opt)){ //look for legacy options framework
618      QStringList cOpts = curr[i].split(" ",QString::SkipEmptyParts);
619      int index = cOpts.indexOf(opt);
620      if(index != -1){ //option currently set somehow
621        found = TRUE; 
622        if(isSet){ //option should be set
623          if( cOpts[index].contains("WITH_"+opt) ){} //Already set
624          else if( cOpts[index].contains("WITHOUT_"+opt) ){ cOpts[index] = "WITH_"+opt+"=true"; }
625          else if( curr[i].contains(chk.replace("_SET","_UNSET")) ){ cOpts.removeAt(index); found=FALSE;} //Remove the inverse option if it is set
626        }else{ //options should be unset
627          if( cOpts[index].contains("WITHOUT_"+opt) ){} //Already set
628          else if( cOpts[index].contains("WITH_"+opt) ){ cOpts[index] = "WITHOUT_"+opt+"=true"; }
629          else if( curr[i].contains(chk.replace("_UNSET","_SET")) ){ cOpts.removeAt(index); found=FALSE;} //Remove the inverse option if it is set
630        }
631        curr[i] = cOpts.join(" "); //put the line back together
632      }
633    } //end checking different options frameworks
634  } // end loop over lines
635  if(!found){
636    //Append the option to the end on a new line
637    curr << chk+"= "+opt;
638  }
639  //Now put the new options list back onto the GUI
640  ui->edit_makeopts->setPlainText(curr.join("\n"));
641  ui->push_config_save->setEnabled(TRUE);
642}
643
644void MainGUI::on_push_addportbefore_clicked(){
645  if( !settings->check("isportsavailable") ){
646    //No ports tree available
647    QMessageBox::warning(this,tr("EasyPBI: No FreeBSD Ports"), tr("The FreeBSD Ports tree could not be found on your system. You may fetch the ports tree through the EasyPBI menu or manually set the path to the port tree in the EasyPBI preferences if it is installed in a non-standard location."));
648  }
649  //Prompt for a new port
650  QString portSel = QFileDialog::getExistingDirectory(this, tr("Select Port"), settings->value("portsdir"));
651  if(portSel.isEmpty()){return;} //action cancelled or closed   
652  //Check if the port is valid
653  if( !isValidPort(portSel) ){
654    QMessageBox::warning(this,tr("EasyPBI: Invalid Port"), tr("The directory selected is not a valid FreeBSD port. Please select a port directory which contains the appropriate Makefile and distinfo files."));
655    return;
656  }
657  //Save the port info to the GUI
658  if(ui->list_portbefore->count() == 1 && ui->list_portbefore->currentText().isEmpty() ){ ui->list_portbefore->clear(); }
659  ui->list_portbefore->addItem(portSel.remove(settings->value("portsdir")+"/"));
660  ui->push_config_save->setEnabled(TRUE);
661}
662
663void MainGUI::on_push_rmportbefore_clicked(){
664  int index = ui->list_portbefore->currentIndex();
665  if(index != -1){
666    ui->list_portbefore->removeItem(index);
667  }
668  ui->push_config_save->setEnabled(TRUE);
669}
670
671void MainGUI::on_push_addportafter_clicked(){
672  if( !settings->check("isportsavailable") ){
673    //No ports tree available
674    QMessageBox::warning(this,tr("EasyPBI: No FreeBSD Ports"), tr("The FreeBSD Ports tree could not be found on your system. You may fetch the ports tree through the EasyPBI menu or manually set the path to the port tree in the EasyPBI preferences if it is installed in a non-standard location."));
675  }
676  //Prompt for a new port
677  QString portSel = QFileDialog::getExistingDirectory(this, tr("Select Port"), settings->value("portsdir"));
678  if(portSel.isEmpty()){return;} //action cancelled or closed   
679  //Check if the port is valid
680  if( !isValidPort(portSel) ){
681    QMessageBox::warning(this,tr("EasyPBI: Invalid Port"), tr("The directory selected is not a valid FreeBSD port. Please select a port directory which contains the appropriate Makefile and distinfo files."));
682    return;
683  }
684  //Save the port info to the GUI
685  if(ui->list_portafter->count() == 1 && ui->list_portafter->currentText().isEmpty() ){ ui->list_portafter->clear(); }
686  ui->list_portafter->addItem(portSel.remove(settings->value("portsdir")+"/"));
687  ui->push_config_save->setEnabled(TRUE);
688}
689
690void MainGUI::on_push_rmportafter_clicked(){
691  int index = ui->list_portafter->currentIndex();
692  if(index != -1){
693    ui->list_portafter->removeItem(index);
694  }
695  ui->push_config_save->setEnabled(TRUE);
696}
697
698void MainGUI::on_push_config_save_clicked(){
699  //Save the current settings to the backend structures
700    //global settings for all modules
701    currentModule->writeValue("progname",ui->line_progname->text());
702    currentModule->writeValue("progweb",ui->line_progweb->text());
703    currentModule->writeValue("progauthor",ui->line_progauthor->text());
704    currentModule->writeValue("progicon",ui->list_progicon->currentText());
705    if(ui->check_requiresroot->isChecked()){ currentModule->writeValue("requiresroot", "true"); }
706    else{ currentModule->writeValue("requiresroot","false"); }
707    //Module-dependant settings
708    bool newport = FALSE;
709    if( radio_module_port->isChecked() ){ //FreeBSD port module
710        if(currentModule->readValue("makeport") != ui->line_makeport->text()){ newport=TRUE; }
711        currentModule->writeValue("makeport",ui->line_makeport->text());
712        currentModule->writeValue("makeoptions",ui->edit_makeopts->toPlainText());
713        QString tmp;
714        for(int i=0; i < ui->list_portbefore->count(); i++){
715          tmp.append(" "+ui->list_portbefore->itemText(i) );
716        }
717        currentModule->writeValue("makeportbefore",tmp.simplified());
718        tmp.clear();
719        for(int i=0; i < ui->list_portafter->count(); i++){
720          tmp.append(" "+ui->list_portafter->itemText(i) );
721        }
722        currentModule->writeValue("makeportafter",tmp.simplified());
723       
724    }else{ //local sources module
725        currentModule->writeValue("packagedir",ui->line_progdir->text());
726        currentModule->writeValue("progversion",ui->line_progversion->text());
727    }
728  //save the new settings to pbi.conf
729  bool ok = currentModule->writePBIconf();
730  if(!ok){
731    //Display a warning that the file could not be saved
732    qDebug() << "Error: pbi.conf could not be written:" << currentModule->path()+"/pbi.conf";
733    QMessageBox::warning(this,tr("EasyPBI Error"), tr("The PBI configuration file could not be saved. Please check your file permissions before trying again."));
734  }else if(newport){
735    //Refresh the port information if the main port changed
736    currentModule->readPortInformation(settings->value("portsdir")+"/"+ui->line_makeport->text());
737    refreshGUI("pbiconf");
738  }
739}
740
741void MainGUI::slotOptionChanged(QString tmp){
742  tmp.clear(); //just to remove compiler warning about unused variable
743  ui->push_config_save->setEnabled(TRUE);       
744}
745
746/*------------------------------------------------
747   RESOURCE EDITOR OPTIONS
748  -------------------------------------------------
749*/
750void MainGUI::slotResourceChanged(){
751  //Get the current file selected
752  QString cfile;
753  if(ui->listw_resources->currentRow() != -1){ cfile = ui->listw_resources->currentItem()->text(); }
754  if(cfile.isEmpty()){ //no item selected
755    ui->push_resources_savewrapper->setVisible(FALSE);
756    ui->text_resources_script->setVisible(FALSE);
757    ui->label_resources_description->setVisible(FALSE);
758    ui->label_resources_icon->setVisible(FALSE);
759         
760  }else{ //item selected
761    QString path = currentModule->path() + "/resources/";
762    if( cfile.endsWith(".png") || cfile.endsWith(".jpg") ){
763      //Image file, show full size
764      QPixmap img(path+cfile);
765      ui->label_resources_icon->setPixmap(img);
766      ui->label_resources_icon->setVisible(TRUE);
767      QString desc = QString::number(img.width()) +" x "+QString::number(img.height())+" "+cfile.section(".",-1).toUpper();
768      ui->label_resources_description->setText(desc);
769      ui->label_resources_description->setVisible(TRUE);
770      //hide the other widgets
771      ui->push_resources_savewrapper->setVisible(FALSE);
772      ui->text_resources_script->setVisible(FALSE);
773    }else{
774      ui->push_resources_savewrapper->setVisible(TRUE);
775      QStringList contents = ModBuild::readFile(path+cfile);
776      ui->text_resources_script->clear();
777      ui->text_resources_script->setText(contents.join("\n"));
778      ui->text_resources_script->setVisible(TRUE);
779      //hide the other widgets
780      ui->label_resources_description->setVisible(FALSE);
781      ui->label_resources_icon->setVisible(FALSE);
782    }
783  }
784  ui->push_resources_savewrapper->setEnabled(FALSE);
785 
786}
787
788void MainGUI::on_push_resources_add_clicked(){
789  //Get the desired file
790  QStringList iFiles = QFileDialog::getOpenFileNames(this, tr("Select Resources"), settings->value("icondir") );
791  //Check that there were file selected
792  if(iFiles.isEmpty()){ return; }
793  //Now add these files to the module
794  for(int i=0; i<iFiles.length(); i++){
795    currentModule->addResource(FALSE,iFiles[i]);
796  }
797  //Now update the GUI
798  refreshGUI("resources");
799}
800
801void MainGUI::on_push_resources_remove_clicked(){
802  //Get the currently selected resource
803  QString cfile;
804  if(ui->listw_resources->currentRow() != -1){ cfile = ui->listw_resources->currentItem()->text(); }
805  //Check that there is something selected 
806  if(cfile.isEmpty()){ return; }
807  //Remove the resource
808  if(currentModule->removeResource(cfile)){
809      qDebug() << "Removed Resource:" << cfile;
810  }else{
811      qDebug() << "Error: Could not remove resource:"<<cfile;
812  }
813  //Refresh the GUI
814  refreshGUI("resources");
815}
816
817void MainGUI::on_push_resources_mkwrapper_clicked(){
818  //Get the desired filename for the wrapper script
819  bool ok;
820  QString cFile = QInputDialog::getText(this, tr("New Wrapper Script"), tr("Filename")+":", QLineEdit::Normal, "",&ok);
821  //Check for a valid input
822  if(!ok || cFile.isEmpty()){ return; }
823  //Now create the new file
824  currentModule->addResource(TRUE,cFile);
825  //Refresh the GUI
826  refreshGUI("resources");
827}
828
829void MainGUI::slotResourceScriptSaved(){
830  //get the current file and path
831  QString cfile;
832  if(ui->listw_resources->currentRow() != -1){ cfile = ui->listw_resources->currentItem()->text(); }
833  if(cfile.isEmpty()){ return; } // do nothing if no file selected
834  QString filePath = currentModule->path() + "/resources/" + cfile;
835  //Read the current text for the resource
836  QStringList contents = ui->text_resources_script->toPlainText().split("\n");
837  //overwrite the resource with the new contents
838  ModBuild::createFile(filePath,contents);
839  ui->push_resources_savewrapper->setEnabled(FALSE);
840}
841
842void MainGUI::slotResourceScriptChanged(){
843  ui->push_resources_savewrapper->setEnabled(TRUE);     
844}
845/*------------------------------------------------
846   XDG EDITOR OPTIONS
847  -------------------------------------------------
848*/
849void MainGUI::slotXdgTypeChanged(){
850  //Update the file list appropriately
851  if(ui->radio_xdg_desktop->isChecked()){
852    //update the files available
853    ui->list_xdg_files->clear();
854    ui->list_xdg_files->addItems(currentModule->filesAvailable("xdg-desktop"));
855    //Set the visibility
856        //Current file
857        ui->label_xdg_name->setVisible(TRUE); ui->line_xdg_name->setVisible(TRUE);
858        ui->label_xdg_exec->setVisible(TRUE); ui->line_xdg_exec->setVisible(TRUE); ui->push_xdg_exec->setVisible(TRUE);
859        ui->label_xdg_icon->setVisible(TRUE); ui->list_xdg_icon->setVisible(TRUE);
860        ui->label_xdg_menu->setVisible(FALSE); ui->line_xdg_menu->setVisible(FALSE); ui->push_xdg_menu->setVisible(FALSE);
861        ui->check_xdg_nodisplay->setVisible(TRUE);
862        ui->check_xdg_terminal->setVisible(TRUE);
863        ui->label_xdg_mimepatterns->setVisible(FALSE); ui->line_xdg_mimepatterns->setVisible(FALSE);
864       
865  }else if(ui->radio_xdg_menu->isChecked()){
866    //update the files available
867    ui->list_xdg_files->clear();
868    ui->list_xdg_files->addItems(currentModule->filesAvailable("xdg-menu"));     
869    //Set the visibility
870        //Current file
871        ui->label_xdg_name->setVisible(TRUE); ui->line_xdg_name->setVisible(TRUE);
872        ui->label_xdg_exec->setVisible(TRUE); ui->line_xdg_exec->setVisible(TRUE); ui->push_xdg_exec->setVisible(TRUE);
873        ui->label_xdg_icon->setVisible(TRUE); ui->list_xdg_icon->setVisible(TRUE);
874        ui->label_xdg_menu->setVisible(TRUE); ui->line_xdg_menu->setVisible(TRUE); ui->push_xdg_menu->setVisible(TRUE);
875        ui->check_xdg_nodisplay->setVisible(TRUE);
876        ui->check_xdg_terminal->setVisible(TRUE);
877        ui->label_xdg_mimepatterns->setVisible(TRUE); ui->line_xdg_mimepatterns->setVisible(TRUE);
878       
879  }
880  //Select the first file in the list if one is available
881  if( ui->list_xdg_files->count() > 0){ ui->list_xdg_files->setCurrentRow(0); }
882  //Update the program icon list for new entries
883  //QStringList icons = currentModule->currentIcons;
884
885  //Update the buttons that only need a refresh when the type changes (such as menu's)
886  //Available binaries pushbuttons
887  menu_bins.clear();
888  QStringList cBins = currentModule->currentBins;
889  if(!cBins.isEmpty()){
890    for(int i=0; i<cBins.length(); i++){
891      menu_bins.addAction(cBins[i]);
892    } 
893  }
894  //Menu categories
895  QString recMenu = currentModule->readValue("portmenucategory");
896  QStringList cats = currentModule->validMenuCategories;
897  menu_validMenuCats.clear();
898  for(int i=0; i<cats.length(); i++){
899    if(recMenu==cats[i]){ //Add an icon showing the recommended menu category
900      menu_validMenuCats.addAction(Backend::icon("start"),cats[i]);     
901    }else{
902      menu_validMenuCats.addAction(cats[i]);
903    }
904  }
905  //Now update read the currently selected file
906  slotXdgFileChanged();
907}
908
909void MainGUI::slotXdgFileChanged(){     
910  bool clearUI =FALSE;
911  if(ui->list_xdg_files->currentRow() == -1){ clearUI=TRUE; }
912
913  //Reset the icon list
914  ui->list_xdg_icon->clear();
915  QStringList icons = currentModule->currentIcons;
916  if(icons.length() > 0){
917      for(int i=0; i<icons.length(); i++){
918        ui->list_xdg_icon->addItem(QIcon(currentModule->path()+"/resources/"+icons[i]),icons[i]);
919      }     
920  }
921  //Get the selected file
922  QString file;
923  if( !clearUI ){ file = ui->list_xdg_files->currentItem()->text(); }
924  if( clearUI || file.isEmpty() ){
925    //Clear the UI lines
926    ui->line_xdg_name->clear();
927    ui->line_xdg_exec->clear();
928    ui->line_xdg_menu->clear();
929    ui->line_xdg_mimepatterns->clear();
930    ui->check_xdg_terminal->setChecked(FALSE);
931    ui->check_xdg_nodisplay->setChecked(FALSE);
932    ui->check_requiresroot->setChecked(FALSE);
933    ui->push_xdg_savechanges->setEnabled(FALSE);
934    ui->push_xdg_savenew->setEnabled(FALSE);
935    //Make sure we don't have any of the structures loaded from previously
936    currentModule->loadDesktop("");
937    currentModule->loadMenu("");
938    currentModule->loadMime("");
939    //Now return
940    return; 
941  }
942  //Now setup the UI as appropriate
943  if(ui->radio_xdg_desktop->isChecked()){
944    //Load the file
945    currentModule->loadDesktop(file);
946    //update the file info on the GUI
947    ui->line_xdg_name->setText( currentModule->readValue("desktopname") );
948    ui->line_xdg_exec->setText( currentModule->readValue("desktopexec") ); 
949    //comboboxes
950    int cicon = icons.indexOf(currentModule->readValue("desktopicon"));
951    if( cicon == -1 ){ 
952      ui->list_xdg_icon->addItem(currentModule->readValue("desktopicon")); 
953      cicon = icons.indexOf(currentModule->readValue("desktopicon"));
954    }
955    ui->list_xdg_icon->setCurrentIndex(cicon);
956
957    //Checkboxes
958    QString chk = currentModule->readValue("desktopterminal").toLower();
959    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_terminal->setChecked(TRUE); }
960    else{ ui->check_xdg_terminal->setChecked(FALSE); }
961    chk = currentModule->readValue("desktopnodisplay").toLower();
962    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_nodisplay->setChecked(TRUE); }
963    else{ ui->check_xdg_nodisplay->setChecked(FALSE); }
964    chk = currentModule->readValue("desktoprequiresroot").toLower();
965    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_requiresroot->setChecked(TRUE); }
966    else{ ui->check_xdg_requiresroot->setChecked(FALSE); }
967       
968  }else if(ui->radio_xdg_menu->isChecked()){
969    //Load the file
970    currentModule->loadMenu(file);
971    //update the file info on the GUI
972    ui->line_xdg_name->setText( currentModule->readValue("menuname") );
973    ui->line_xdg_exec->setText( currentModule->readValue("menuexec") ); 
974    ui->line_xdg_menu->setText( currentModule->readValue("menucategories") );
975    //comboboxes
976          //icons
977    int cicon = icons.indexOf(currentModule->readValue("menuicon"));
978    if( cicon == -1 ){ 
979      ui->list_xdg_icon->addItem(currentModule->readValue("menuicon")); 
980      cicon = icons.indexOf(currentModule->readValue("menuicon"));
981    }
982    ui->list_xdg_icon->setCurrentIndex(cicon);
983   
984    //Checkboxes
985    QString chk = currentModule->readValue("menuterminal").toLower();
986    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_terminal->setChecked(TRUE); }
987    else{ ui->check_xdg_terminal->setChecked(FALSE); }
988    chk = currentModule->readValue("menunodisplay").toLower();
989    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_nodisplay->setChecked(TRUE); }
990    else{ ui->check_xdg_nodisplay->setChecked(FALSE); }
991    chk = currentModule->readValue("menurequiresroot").toLower();
992    if( (chk == "true") || (chk=="yes") ){ ui->check_xdg_requiresroot->setChecked(TRUE); }
993    else{ ui->check_xdg_requiresroot->setChecked(FALSE); }
994   
995    //Load the XDG-MIME file associations
996    QString mime = currentModule->readValue("menumimetype");
997    QStringList mimeavailable = currentModule->filesAvailable("xdg-mime");
998    bool found = FALSE;
999    for( int i=0; i<mimeavailable.length(); i++){
1000      currentModule->loadMime(mimeavailable[i]);
1001      if(currentModule->readValue("mimetype") == mime){
1002        found = TRUE;
1003        break;
1004      }
1005    }
1006    //qDebug() << "mimetype detected:" << mime;
1007    if(found){
1008      ui->line_xdg_mimepatterns->setText( currentModule->readValue("mimepatterns") ); 
1009    }else{
1010      currentModule->loadMime(""); //Make sure we don't have any mime file loaded
1011      ui->line_xdg_mimepatterns->clear();
1012    }
1013   
1014  }else{
1015    //do nothing, unknown radio button selected (or none)
1016  }
1017  ui->push_xdg_savechanges->setEnabled(FALSE);
1018  ui->push_xdg_savenew->setEnabled(FALSE);
1019}
1020
1021void MainGUI::slotAddMenuCat(QAction* act){
1022  //get the selected menu category
1023  QString newcat = act->text();
1024  //Read the current categories
1025  QStringList oldcats = ui->line_xdg_menu->text().split(";", QString::SkipEmptyParts);
1026  for(int i=0; i<oldcats.length(); i++){
1027    oldcats[i] = oldcats[i].simplified();
1028    if(oldcats[i] == newcat){return;} //category already in the list, do nothing
1029  }
1030  //Add the item
1031  oldcats << newcat;
1032  //Now replace the line onto the GUI
1033  ui->line_xdg_menu->setText(oldcats.join("; "));
1034}
1035
1036void MainGUI::slotAddBin(QAction* act){
1037  //replace the current executable with the new one
1038  ui->line_xdg_exec->setText(act->text().section("/",-1) );     
1039}
1040
1041void MainGUI::on_push_xdg_remove_clicked(){
1042  //Figure out if a file is selected
1043  if( ui->list_xdg_files->currentItem()->text().isEmpty() ){ return; }
1044  //Now remove the file
1045  bool ok = FALSE;
1046  if( ui->radio_xdg_desktop->isChecked() ){
1047    ok = currentModule->removeDesktop();
1048  }else if( ui->radio_xdg_menu->isChecked() ){
1049    ok = currentModule->removeMenu();
1050  }
1051  //Now inform the user if there was an error
1052  if(!ok){
1053    QMessageBox::warning(this, tr("EasyPBI Error"), tr("Could not remove the XDG entry.")+"\n"+tr("Check the file permissions and try again") );
1054  }
1055  //Now refresh the GUI
1056  refreshGUI("xdg");
1057 
1058}
1059
1060void MainGUI::on_push_xdg_savechanges_clicked(){
1061  //save the current UI settings to the module structure then save the file
1062  bool ok = FALSE;
1063  if( ui->radio_xdg_desktop->isChecked() ){
1064    currentModule->writeValue("desktopname",ui->line_xdg_name->text());
1065    currentModule->writeValue("desktopgenericname",ui->line_xdg_name->text().toLower());
1066    currentModule->writeValue("desktopexec",ui->line_xdg_exec->text());
1067    currentModule->writeValue("desktopicon",ui->list_xdg_icon->currentText());
1068    QString checked = "false";
1069    if(ui->check_xdg_terminal->isChecked()){ checked="true"; }
1070    currentModule->writeValue("desktopterminal",checked);
1071    checked = "false";
1072    if(ui->check_xdg_nodisplay->isChecked()){ checked="true"; }
1073    currentModule->writeValue("desktopnodisplay",checked);
1074    checked = "false";
1075    if(ui->check_xdg_requiresroot->isChecked()){ checked="true"; }
1076    currentModule->writeValue("desktoprequiresroot", checked);
1077    //Now save the file
1078    ok = currentModule->writeDesktop();
1079   
1080  }else if( ui->radio_xdg_menu->isChecked() ){
1081    currentModule->writeValue("menuname",ui->line_xdg_name->text());
1082    currentModule->writeValue("menugenericname",ui->line_xdg_name->text().toLower());
1083    currentModule->writeValue("menuexec",ui->line_xdg_exec->text());
1084    currentModule->writeValue("menuicon",ui->list_xdg_icon->currentText());
1085    currentModule->writeValue("menucategories", ui->line_xdg_menu->text());
1086    QString checked = "false";
1087    if(ui->check_xdg_terminal->isChecked()){ checked="true"; }
1088    currentModule->writeValue("menuterminal",checked);
1089    checked = "false";
1090    if(ui->check_xdg_nodisplay->isChecked()){ checked="true"; }
1091    currentModule->writeValue("menunodisplay",checked);
1092    checked = "false";
1093    if(ui->check_xdg_requiresroot->isChecked()){ checked="true"; }
1094    currentModule->writeValue("menurequiresroot", checked);
1095    //Setup the mime type associations as appropriate
1096    checkMime();
1097    //Now save the file
1098    ok = currentModule->writeMenu();   
1099  }
1100  //Now inform the user if there was an error
1101  if(!ok){
1102    QMessageBox::warning(this, tr("EasyPBI Error"), tr("Could not save the changes to the XDG entry.")+"\n"+tr("Check the file permissions and try again") );
1103  }
1104  //Now refresh the GUI
1105  //refreshGUI("xdg"); //refresh the entire tab
1106  slotXdgFileChanged(); //only update the proper half of the tab
1107}
1108
1109void MainGUI::on_push_xdg_savenew_clicked(){
1110  //Get the filename we want to save
1111  QString filename;
1112  //Now check that the filename does not already exist
1113  QStringList cFiles;
1114  if(ui->radio_xdg_desktop->isChecked() ){
1115    filename = ui->line_xdg_exec->text().section("/",-1);
1116    cFiles = currentModule->filesAvailable("xdg-desktop").replaceInStrings(".desktop","");
1117  }else if(ui->radio_xdg_menu->isChecked() ){
1118    filename = ui->line_xdg_exec->text().section("/",-1);
1119    cFiles = currentModule->filesAvailable("xdg-menu").replaceInStrings(".desktop","");
1120  }
1121  if(filename.isEmpty()){ return;}
1122 
1123  if(cFiles.indexOf(filename) != -1){
1124    int num = 1;
1125    while(cFiles.indexOf(filename+QString::number(num)) != -1){ num++; }
1126    filename.append( QString::number(num) );
1127  }
1128  //save the current UI settings to the module structure then save the file
1129  bool ok = FALSE;
1130  if( ui->radio_xdg_desktop->isChecked() ){
1131    currentModule->loadDesktop(filename+".desktop"); //get the new file ready
1132    currentModule->writeValue("desktopname",ui->line_xdg_name->text());
1133    currentModule->writeValue("desktopgenericname",ui->line_xdg_name->text().toLower());
1134    currentModule->writeValue("desktopexec",ui->line_xdg_exec->text());
1135    currentModule->writeValue("desktopicon",ui->list_xdg_icon->currentText());
1136    QString checked = "false";
1137    if(ui->check_xdg_terminal->isChecked()){ checked="true"; }
1138    currentModule->writeValue("desktopterminal",checked);
1139    checked = "false";
1140    if(ui->check_xdg_nodisplay->isChecked()){ checked="true"; }
1141    currentModule->writeValue("desktopnodisplay",checked);
1142    checked = "false";
1143    if(ui->check_xdg_requiresroot->isChecked()){ checked="true"; }
1144    currentModule->writeValue("desktoprequiresroot", checked);
1145    //Now save the file
1146    ok = currentModule->writeDesktop();
1147   
1148  }else if( ui->radio_xdg_menu->isChecked() ){
1149    currentModule->loadMenu(filename+".desktop"); //get the new file ready
1150    //Update the MIME associations
1151    checkMime();
1152    //Save the MENU values
1153    currentModule->writeValue("menuname",ui->line_xdg_name->text());
1154    currentModule->writeValue("menugenericname",ui->line_xdg_name->text().toLower());
1155    currentModule->writeValue("menuexec",ui->line_xdg_exec->text());
1156    currentModule->writeValue("menuicon",ui->list_xdg_icon->currentText());
1157    currentModule->writeValue("menucategories", ui->line_xdg_menu->text());
1158    QString checked = "false";
1159    if(ui->check_xdg_terminal->isChecked()){ checked="true"; }
1160    currentModule->writeValue("menuterminal",checked);
1161    checked = "false";
1162    if(ui->check_xdg_nodisplay->isChecked()){ checked="true"; }
1163    currentModule->writeValue("menunodisplay",checked);
1164    checked = "false";
1165    if(ui->check_xdg_requiresroot->isChecked()){ checked="true"; }
1166    currentModule->writeValue("menurequiresroot", checked);
1167    //Now save the file
1168    ok = currentModule->writeMenu();   
1169  }
1170  //Now inform the user if there was an error
1171  if(!ok){
1172    QMessageBox::warning(this, tr("EasyPBI Error"), tr("Could not save the changes to the XDG entry.")+"\n"+tr("Check the file permissions and try again") );
1173  }
1174  //Now refresh the GUI
1175  refreshGUI("xdg");
1176}
1177
1178void MainGUI::on_push_xdg_clearentry_clicked(){
1179  //Clear the UI
1180        //reset the item selected to nothing
1181        ui->list_xdg_files->setCurrentRow(-1);
1182        //De-activate the "save" button
1183        ui->push_xdg_savechanges->setEnabled(FALSE);
1184        //Now clear the
1185        slotXdgFileChanged();
1186}
1187
1188void MainGUI::checkMime(){
1189    //This function will check the UI for differences in the MIME patterns
1190      // and update/create the MIME file appropriately
1191      // The MENU mime type will also be appropriately set
1192       
1193    QString menumimetype = currentModule->readValue("menumimetype");
1194    QString menumimepat = ui->line_xdg_mimepatterns->text();
1195    QString cmimetype = currentModule->readValue("mimetype");
1196    QString cmimepat = currentModule->readValue("mimepatterns");
1197    if( menumimepat != cmimepat ){ //something different about the mime patterns
1198        //  ---- Change the MIME file as well ----
1199          //Delete MIME file
1200        if(menumimepat.isEmpty()){
1201          currentModule->removeMime();
1202          currentModule->writeValue("menumimetype",""); //set MENU value
1203               
1204          //Create new MIME file
1205        }else if( cmimetype.isEmpty() || (ui->line_xdg_exec->text() != currentModule->readValue("menuexec")) ){
1206          QString exec = ui->line_xdg_exec->text().simplified();
1207          menumimetype = "application/x-"+exec;
1208          QString newfile = exec+"-xdg.xml";
1209          currentModule->loadMime(newfile); //setup structure
1210          currentModule->writeValue("mimetype",menumimetype); //set mime type
1211          currentModule->writeValue("mimepatterns",menumimepat); //set mime patterns
1212          currentModule->writeMime(); //save the MIME file (using default mime info)
1213               
1214          currentModule->writeValue("menumimetype",menumimetype); //set MENU value
1215               
1216          //Overwrite existing MIME file
1217        }else{
1218          currentModule->writeValue("mimepatterns", menumimepat); //overwrite mime patterns
1219          currentModule->writeMime(); //overwrite the MIME file
1220               
1221          currentModule->writeValue("menumimetype",cmimetype); //set MENU value
1222        }
1223    }
1224}
1225
1226void MainGUI::slotXDGOptionChanged(QString tmp){
1227  tmp.clear(); //remove warning about unused variables
1228  ui->push_xdg_savechanges->setEnabled(TRUE);
1229  ui->push_xdg_savenew->setEnabled(TRUE);
1230}
1231
1232/*------------------------------------------------
1233   SCRIPTS EDITOR OPTIONS
1234  -------------------------------------------------
1235*/
1236void MainGUI::slotScriptChanged(int index){
1237  index=0; //just to remove the warning about unused variables
1238  refreshGUI("scripts");
1239}
1240
1241void MainGUI::on_push_scripts_create_clicked(){
1242  //Setup display items
1243  ui->push_scripts_create->setVisible(FALSE);
1244  ui->push_scripts_remove->setVisible(FALSE);
1245  ui->push_scripts_save->setVisible(TRUE);
1246  ui->text_scripts_edit->setVisible(TRUE);
1247  ui->text_scripts_edit->clear();
1248  ui->push_scripts_save->setEnabled(FALSE); //disable the save button until something changes
1249}
1250
1251void MainGUI::on_push_scripts_remove_clicked(){
1252  //Get the current file
1253  QString filename = ui->list_scripts_file->currentText();
1254  //Remove the file
1255  QDir dir(currentModule->path()+"/scripts");
1256  dir.remove(filename);
1257  //refresh the UI
1258  refreshGUI("scripts");
1259}
1260
1261void MainGUI::on_push_scripts_save_clicked(){
1262  //Get the current file text
1263  QStringList contents = ui->text_scripts_edit->toPlainText().split("\n");
1264  //get the current file
1265  QString filename = currentModule->path() + "/scripts/"+ui->list_scripts_file->currentText();
1266  //Save the file
1267  bool ok = ModBuild::createFile(filename,contents);
1268  //display a warning if error
1269  if(!ok){
1270    QMessageBox::warning(this,tr("Error Saving File"), tr("Could not save the script")+"\n"+tr("Please check the file permissions and try again") );
1271  }
1272  //Now refresh the UI
1273  refreshGUI("scripts");
1274}
1275
1276void MainGUI::slotScriptModified(){
1277  ui->push_scripts_save->setEnabled(TRUE);     
1278}
1279/*------------------------------------------------
1280   EXTERNAL-LINKS EDITOR OPTIONS
1281  -------------------------------------------------
1282*/
1283void MainGUI::on_push_el_add_clicked(){
1284  //Read the user inputs
1285  QString file = ui->line_el_file->text();
1286  QString linkto = ui->line_el_linkto->text();
1287  QString opts = ui->line_el_filetype->text();
1288  //check for valid inputs
1289  if( file.isEmpty() || linkto.isEmpty() || opts.isEmpty() ){ return; }
1290  //Add the link
1291  currentModule->addExternalLink(file, linkto, opts.split(",") );
1292  //Save the file
1293  currentModule->writeExternalLinks();
1294  //Refresh the UI
1295  refreshGUI("external-links");
1296}
1297
1298void MainGUI::on_push_el_remove_clicked(){
1299  //Get the currently selected link
1300  QTreeWidgetItem *line = ui->tree_el_view->currentItem();
1301  if(line->columnCount() != 3){ return; }
1302  QString file = line->text(0);
1303  QString linkto = line->text(1);
1304  //Remove the link
1305  currentModule->removeExternalLink(file,linkto);
1306  //Save the file
1307  currentModule->writeExternalLinks();
1308  //Refresh the UI
1309  refreshGUI("external-links");
1310}
1311
1312void MainGUI::slotELSetFile(QAction* act){
1313  //get the selected file and set it in the UI
1314  ui->line_el_file->setText( act->text() );
1315  ui->line_el_linkto->setText( act->text() );
1316}
1317
1318void MainGUI::slotELSetType(QAction* act){
1319  //Get the current types
1320  QStringList types = ui->line_el_filetype->text().split(",", QString::SkipEmptyParts);
1321  //get the new type
1322  QString ntype  = act->text();
1323  //Now properly add the type as appropriate
1324  bool ok = FALSE;
1325  for(int i=0; i<types.length(); i++){
1326    //Check for special cases
1327    if( (types[i] == "keep") && (ntype=="replace") ){
1328      types[i] = ntype;
1329      ok = TRUE;
1330      break;
1331    }else if( (types[i] == "replace") && (ntype=="keep") ){
1332      types[i] = ntype;
1333      ok = TRUE;
1334      break;
1335    }else if( (types[i]=="binary") && (ntype=="linux") ){
1336      types[i] = ntype;
1337      ok = TRUE;
1338      break;
1339    }else if( (types[i]=="linux") && (ntype=="binary") ){
1340      types[i] = ntype;
1341      ok = TRUE;
1342      break;
1343    }else if( types[i] == ntype ){
1344      ok=TRUE;
1345      break;
1346    }
1347  }
1348  if(!ok){ types << ntype; } //append the type to the list
1349  //Add the new types to the UI
1350  ui->line_el_filetype->setText( types.join(",") );
1351}
1352/*------------------------------------------------
1353   FREENAS PLUGINS EDITOR OPTIONS
1354  -------------------------------------------------
1355*/
1356
1357
1358/*------------------------------------------------
1359   PBI BUILDER OPTIONS
1360  -------------------------------------------------
1361*/
1362void MainGUI::on_push_build_start_clicked(){
1363  //Check GUI to make sure settings are set before running
1364  bool gostatus = TRUE;
1365  QString outdir = settings->value("pbidir");
1366  if (outdir.isEmpty() ){gostatus=FALSE;}
1367  //QString sigfile = "";ui->linePBIDigSigFile->text(); //this one can be empty
1368  QString modDir = currentModule->path();
1369  if(modDir.isEmpty()){gostatus=FALSE;}
1370  if(!gostatus){
1371    QMessageBox::warning(this,tr("Error"),tr("Invalid PBI Settings"));
1372    return;
1373  }
1374 
1375  //Generate the PBI build command
1376  QString cmd;
1377  // -- PBI from ports
1378  if(radio_module_port->isChecked()){
1379    //Check that the ports tree is available
1380    if( !settings->check("isportsavailable") ){ 
1381      qDebug() << "Cannot build a PBI from ports without the FreeBSD ports tree available";
1382      return;
1383    }
1384    //Setup the pbi_makeport command from GUI settings
1385    cmd = settings->value("pbi_makeport");
1386    if(ui->check_build_32->isChecked()){ cmd += " -32"; }
1387    cmd += " -c " + modDir;
1388    if(settings->value("portsdir") != "/usr/ports"){ cmd += " -d " + settings->value("portsdir"); }
1389    cmd += " -o " + outdir;
1390    cmd += " --delbuild";
1391    if( settings->check("usetmpfs") ){ cmd += " --tmpfs"; }
1392    if( settings->check("usecache") ){ 
1393      cmd += " --pkgdir " + settings->value("cachedir");
1394      //Remove known "bad" packages (ones that routinely cause failures)
1395      QDir cDir( settings->value("cachedir") );
1396      QStringList filters = settings->list("skippkgs");
1397      QStringList badFiles = cDir.entryList(filters, QDir::Files | QDir:: NoDotAndDotDot);
1398      for(int i=0; i<badFiles.length(); i++){ cDir.remove(badFiles[i]); }
1399    }
1400    if( settings->check("usesignature") && QFile::exists(settings->value("sigfile")) ){ cmd += " --sign " + settings->value("sigfile"); }
1401   
1402  // -- PBI from local directory
1403  }else if(radio_module_local->isChecked() ){
1404        //get the base command
1405        cmd = settings->value("pbi_create");
1406        //Setup the ports options if non-standard port location
1407        if(settings->value("portsdir") != "/usr/ports"){ cmd += " -d " + settings->value("portsdir"); }
1408        //Setup the output directory
1409        cmd += " -o "+outdir;
1410        //Load the module
1411        cmd += " -c "+modDir;
1412        //Sign the PBI
1413        if( settings->check("usesignature") && QFile::exists(settings->value("sigfile")) ){ cmd += " --sign " + settings->value("sigfile"); }
1414        //Now setup the directory to package
1415        cmd += " "+ currentModule->readValue("packagedir");
1416  }
1417  //Display the command created in hte terminal
1418  qDebug() << "Build PBI command created:"<<cmd;
1419 
1420  //Receive User verification before beginning build process due to:
1421  //  -- long time required, internet connection required, root permissions required
1422  QMessageBox verify(this);
1423  verify.setText(tr("Are you sure you wish to start the PBI build?"));
1424  verify.setInformativeText(tr("This requires an active internet connection and root permissions. The time required to build a PBI varies depending upon system specifications and ports to be compiled."));
1425  verify.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
1426  verify.setDefaultButton(QMessageBox::Yes);
1427  int ret = verify.exec();
1428  if(ret != QMessageBox::Yes){return;}
1429
1430  //Add the necessary glue to the command to run the pbi build
1431  cmd.prepend(settings->value("su_cmd")+" \"");
1432  cmd.append("\"");
1433  qDebug() << "Actual command used:" << cmd;
1434
1435  //Setup the displays
1436  ui->push_build_stop->setEnabled(TRUE);
1437  ui->push_build_save->setEnabled(FALSE);
1438  ui->check_build_32->setEnabled(FALSE);
1439  ui->push_build_start->setEnabled(FALSE); //disable the button so they do not start more than 1 build at a time
1440  ui->text_build_log->clear(); //clear the display in case this is not the first run
1441  ui->line_build_module->setText(currentModule->path());
1442  ui->line_build_outputdir->setText(settings->value("pbidir"));
1443  //Setup Process connections
1444  p = new QProcess(this);
1445  p->setProcessChannelMode(QProcess::MergedChannels);
1446  p->setProcessEnvironment( QProcessEnvironment::systemEnvironment() );
1447  connect(p,SIGNAL(readyReadStandardOutput()),this,SLOT(slotUpdatePBIBuild()) );
1448  connect(p,SIGNAL(finished(int,QProcess::ExitStatus)),this,SLOT(slotPBIbuildFinished(int,QProcess::ExitStatus)) );
1449  connect(p,SIGNAL(error(QProcess::ProcessError)),this,SLOT(slotBuildError(QProcess::ProcessError)) );
1450  //Setup the flag for the finishing checks
1451  PBI_BUILDING_NOW=outdir+":::"+currentModule->readValue("progname");
1452  //Start the Process
1453  qDebug() << "Starting the PBI build process...";
1454  ui->toolBox->setItemText(0,tr("PBI Builder (Working)"));
1455  p->start(cmd);
1456}
1457
1458void MainGUI::on_push_build_stop_clicked(){
1459  slotKillPBIBuild();
1460}
1461
1462void MainGUI::on_push_build_save_clicked(){
1463  //Have user select a filename/location to save the log
1464  QString filename = QFileDialog::getSaveFileName(this,tr("Save Log"),settings->value("progdir")+"/build.log",tr("Log Files")+" (*.log *.txt)");
1465  if(filename.isEmpty()){return;} //User cancelled the process
1466  //Open the file (as new)
1467  QFile *file = new QFile(filename);
1468  file->open(QIODevice::WriteOnly);
1469  //Save the log into the file
1470  file->write(ui->text_build_log->toPlainText().toUtf8());
1471  file->close();
1472}
1473
1474void MainGUI::slotUpdatePBIBuild(){
1475  QString tmp = p->readAllStandardOutput();
1476  if( tmp.startsWith("\n") ){tmp.remove(0,0);} //remove newline at the beginning (too much whitespace in log)
1477  if( tmp.endsWith("\n") ){tmp.chop(1);} //remove newline at the end (already accounted for by appending)
1478  if(!tmp.isEmpty()){ ui->text_build_log->append( tmp ); }
1479  //qDebug() << "Update output: " << tmp;
1480}
1481
1482void MainGUI::slotPBIbuildFinished(int exitCode,QProcess::ExitStatus exitStatus){
1483  //Check to see if the PBI process finished successfully
1484  qDebug() << "PBI build process Finished" << exitStatus << exitCode;
1485  //Check that the new PBI exists
1486  QDir outdir( PBI_BUILDING_NOW.section(":::",0,0) );
1487  QString pbiname= PBI_BUILDING_NOW.section(":::",1,1).toLower().remove(" ");
1488  QFileInfoList fL = outdir.entryInfoList( QStringList() << pbiname+"*.pbi" ,QDir::Files | QDir::NoSymLinks);
1489  bool success = FALSE;
1490  for(int i=0; i<fL.length(); i++){
1491          qint64 msdiff = QDateTime::currentMSecsSinceEpoch() - fL[i].created().toMSecsSinceEpoch();
1492          if(msdiff < 30000){ success = true; break; } //if less than a 30sec since creation of file - success
1493  }
1494 
1495  if(exitCode == 0 && success){
1496      QMessageBox::information(this,tr("PBI Build Success"),tr("The PBI finished building successfully"));
1497  }else if(exitCode == 0 && PBI_BUILD_TERMINATED){
1498      //The user killed the process - No Message
1499  }else{
1500    QMessageBox::warning(this,tr("PBI Build Failure"),tr("The PBI failed to build.")+"\n"+tr("Please check the build log to find the cause of the failure and adjust the module accordingly"));
1501  }
1502  ui->push_build_start->setEnabled(TRUE);
1503  ui->push_build_save->setEnabled(TRUE);
1504  ui->push_build_stop->setEnabled(FALSE);
1505  ui->check_build_32->setEnabled(TRUE);
1506  p->close();
1507  PBI_BUILDING_NOW.clear();
1508  PBI_BUILD_TERMINATED=FALSE;
1509  ui->toolBox->setItemText(0,tr("PBI Builder (Finished)"));
1510  delete p;
1511}
1512
1513void MainGUI::slotKillPBIBuild(){
1514  if( p->state()==QProcess::Running ){
1515    //qDebug() << "Process PID:" << p->pid();
1516    PBI_BUILD_TERMINATED=TRUE;   
1517    p->terminate();
1518    ui->text_build_log->append("---PBI Build Terminated---");
1519  }
1520}
1521
1522void MainGUI::slotBuildError(QProcess::ProcessError error){
1523  qDebug() << "QProcess PBI Build error#" << error;
1524}
Note: See TracBrowser for help on using the repository browser.