source: src-qt4/EasyPBI/mainGUI.cpp @ cc7dbf3

9.2-releasereleng/10.0releng/10.0.1releng/10.0.2releng/10.0.3releng/10.1releng/10.1.1
Last change on this file since cc7dbf3 was cc7dbf3, checked in by Ken Moore <ken@…>, 19 months ago

Couple improvements to EasyPBI:
1) Allow the user to bypass the warning about an invalid FreeBSD port when adding to make port before/after (no bypass for creating a new module)
2) Make EasyPBI re-generate the scripts directory if it is missing and you try to save a script file to a module

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