Bug Summary

File:OMOptim/OMOptim/build/../GUI/MainWindow.cpp
Warning:line 1114, column 1
Potential leak of memory pointed to by 'widget'

Annotated Source Code

[?] Use j/k keys for keyboard navigation

1// $Id$
2/**
3 @file MainWindow.h
4 @brief Comments for file documentation.
5 @author Hubert Thieriot, hubert.thieriot@mines-paristech.fr
6 Company : CEP - ARMINES (France)
7 http://www-cep.ensmp.fr/english/
8 @version
9*/
10
11#include <iostream>
12
13#include "MainWindow.h"
14#include "MOThreads.h"
15#include "newprojectform.h"
16#include "ListInfo.h"
17#include "MOVector.h"
18#include "Variable.h"
19#include "TabOMC.h"
20#include "Tabs/MOTab.h"
21#include "OMOptimGuiTools.h"
22#include "GuiTools.h"
23#include "Problems.h"
24#include "Results.h"
25#include "ProblemInterfaces.h"
26#include "widgetloadexemodel.h"
27#include "scriptparseromoptim.h"
28#include "Dialogs/HelpDlg.h"
29#include "ScriptTextDlg.h"
30#include "OpenModelica.h"
31
32namespace Ui
33{
34class MainWindowClass;
35}
36
37
38MainWindow::MainWindow(Project* project,QWidget *parent)
39 : QMainWindow(parent), _ui(new Ui::MainWindowClass)
40{
41
42 this->resize(800, 600);
43 this->setStyleSheet("QMainWindow::separator {height:0;width:0}");
44
45 //************************
46 // Basic initialization
47 //************************
48 _ui->setupUi(this);
49 _project = project;
50
51 // Recent Files
52 createRecentFilesMenu();
53
54 //***********************
55 // Main window gui
56 //***********************
57 // Tabs
58 _tabMain = new MOMainTab(this,_project);
59 _tabProject = new TabProject(_project,_recentFileActs,this);
60 _tabProject->setWindowTitle("Project");
61 _tabProject->setBackgroundRole(QPalette::Window);
62 _tabProject->setAutoFillBackground(true);
63 _tabMain->addTab(_tabProject,"Project");
64 _tabMain->setCurrentWidget(_tabProject);
65
66 // Side part
67 _ui->splitterH->insertWidget(1,_tabMain);
68 _ui->splitterH->setStretchFactor(1,10);
69 delete _ui->widgetToDelete;
70
71 addDockWidget(Qt::BottomDockWidgetArea,_ui->dockLog,Qt::Vertical);
72
73 // Actions
74 QList<QAction*> dispActions;
75 dispActions << _ui->dockLog->toggleViewAction();
76 _ui->menuDisplay->addActions(dispActions);
77
78
79
80 // Trees
81 _casesTree = new OMCasesCombiner(_project->problems(),_project->results(),this);
82 _casesTreeView = new OMCasesTreeView(_project,_casesTree,this);
83 _ui->dockOMCases->setWidget(_casesTreeView);
84
85 _ui->treeModItem->setModel(_project->modItemsTree());
86 _ui->treeModItem->setContextMenuPolicy(Qt::CustomContextMenu);
87 _ui->treeModItem->setDragEnabled(true);
88 _ui->treeModItem->setDragDropMode(QAbstractItemView::DragDrop);
89
90 // progress dock
91 // hide title
92 QWidget* taskTitleWidget = new QWidget(this); /* where this a QMainWindow object */
93 _ui->dockProgress->setTitleBarWidget( taskTitleWidget );
94
95
96 // text log
97 _textLog=new MyTextLog(this);
98 _ui->layoutTextLog->addWidget(_textLog);
99 _textLog->setOpenExternalLinks(true);
100
101 // limit the size of omc and debug log
102 _ui->textOMC->document()->setMaximumBlockCount(1000);
103 _ui->textDebug->document()->setMaximumBlockCount(1000);
104 _textLog->document()->setMaximumBlockCount(1000);
105
106 //Error, msg and progress
107 _widgetProgress = new WidgetProgress(this);
108 _ui->layoutProgress->addWidget(_widgetProgress);
109 displayProgress(0);
110
111
112
113 //Create the Statusbar
114 _statusBar = new QStatusBar();
115 _statusBar->setObjectName("statusBar");
116 _statusBar->setContentsMargins(0, 0, 1, 0);
117 _stProgressBar = new QProgressBar;
118 _stProgressBar->setMaximumWidth(300);
119 _stProgressBar->setTextVisible(false);
120 //_statusBar->addPermanentWidget(_stProgressBar);
121 _statusBar->setVisible(false);
122 this->setStatusBar(_statusBar);
123
124
125 connectProject();
126 actualizeGuiFromProject();
127
128 //*********************************
129 // Signals for gui
130 //*********************************
131 connect(_casesTreeView, SIGNAL(doubleClicked(QModelIndex))"2""doubleClicked(QModelIndex)",this, SLOT(enableOMCaseTab(QModelIndex))"1""enableOMCaseTab(QModelIndex)");
132 connect(_ui->treeModItem, SIGNAL(clicked(QModelIndex))"2""clicked(QModelIndex)",this, SLOT(onSelectedModItem(QModelIndex))"1""onSelectedModItem(QModelIndex)");
133 connect(this, SIGNAL(sendInfo(Info))"2""sendInfo(Info)",this, SLOT( displayInfo(Info))"1""displayInfo(Info)");
134 connect (_ui->treeModItem,SIGNAL(customContextMenuRequested(const QPoint &))"2""customContextMenuRequested(const QPoint &)",
135 this,SLOT(showModItemsTreePopup(const QPoint &))"1""showModItemsTreePopup(const QPoint &)");
136 connect (_tabMain,SIGNAL(customContextMenuRequested(const QPoint &))"2""customContextMenuRequested(const QPoint &)",
137 this,SLOT(showTabTitlePopup(const QPoint &))"1""showTabTitlePopup(const QPoint &)");
138 connect(_tabProject,SIGNAL(newProject())"2""newProject()",this,SLOT(newProject())"1""newProject()");
139 connect(_tabProject,SIGNAL(loadProject())"2""loadProject()",this,SLOT(loadProject())"1""loadProject()");
140
141
142 // Menus
143 connect( _ui->actionNewProject, SIGNAL( triggered() )"2""triggered()",this, SLOT( newProject())"1""newProject()");
144 connect( _ui->actionSaveProject, SIGNAL( triggered() )"2""triggered()",this, SLOT( saveProject())"1""saveProject()");
145 connect( _ui->actionLoadProject, SIGNAL( triggered() )"2""triggered()",this, SLOT( loadProject())"1""loadProject()");
146 connect( _ui->actionQuit, SIGNAL( triggered() )"2""triggered()",this, SLOT( quit())"1""quit()");
147 connect( _ui->actionOMCShell,SIGNAL( triggered() )"2""triggered()",this, SLOT( newOMCShell())"1""newOMCShell()");
148 connect( _ui->actionOMCClear,SIGNAL( triggered() )"2""triggered()",this, SLOT( OMCClear())"1""OMCClear()");
149 connect( _ui->actionSettings,SIGNAL( triggered() )"2""triggered()",this, SLOT(openSettings())"1""openSettings()");
150 connect( _ui->actionClearRecent, SIGNAL(triggered())"2""triggered()", this, SLOT(clearRecentFilesMenu())"1""clearRecentFilesMenu()");
151 connect( _ui->actionLoadMoFile, SIGNAL(triggered())"2""triggered()", this, SLOT(loadMoFile())"1""loadMoFile()");
152 connect( _ui->actionLoadModelicaLibrary, SIGNAL(triggered())"2""triggered()", this, SLOT(loadModelicaLibrary())"1""loadModelicaLibrary()");
153 connect( _ui->actionLoadExecutableModel, SIGNAL(triggered())"2""triggered()", this, SLOT(loadExecutableModel())"1""loadExecutableModel()");
154 connect( _ui->actionRefreshModTree, SIGNAL(triggered())"2""triggered()",this,SLOT(refreshModelTree())"1""refreshModelTree()");
155 connect( _ui->actionHelp, SIGNAL(triggered())"2""triggered()",this, SLOT(openUserManual())"1""openUserManual()");
156 connect( _ui->actionStartOmc,SIGNAL(triggered())"2""triggered()",_project->moomc(),SLOT(startServer())"1""startServer()");
157 connect( _ui->actionClearLog,SIGNAL(triggered())"2""triggered()",this,SLOT(clearLog())"1""clearLog()");
158 connect( _ui->actionLoadCases,SIGNAL(triggered())"2""triggered()",this,SLOT(loadCases())"1""loadCases()");
159 connect( _ui->actionLaunchScript2,SIGNAL(triggered())"2""triggered()",this,SLOT(launchScript())"1""launchScript()");
160 connect( _ui->actionDispScriptFunctions,SIGNAL(triggered())"2""triggered()",this,SLOT(dispScriptFunctions())"1""dispScriptFunctions()");
161 connect( _ui->actionLaunchScriptText,SIGNAL(triggered())"2""triggered()",this,SLOT(launchScriptText())"1""launchScriptText()");
162 connect( _ui->actionExportProject,SIGNAL(triggered())"2""triggered()",this,SLOT(exportFolder())"1""exportFolder()");
163
164 //*********************************
165 // Signals for informations
166 //*********************************
167 connect(InfoSender::instance(),SIGNAL(setCurrentTask(QString))"2""setCurrentTask(QString)",this,SLOT(setStatusBarText(QString))"1""setStatusBarText(QString)");
168 connect(InfoSender::instance(),SIGNAL(increaseTaskProgress())"2""increaseTaskProgress()",this,SLOT(increaseStProgressBar())"1""increaseStProgressBar()");
169 connect(InfoSender::instance(),SIGNAL(noCurrentTask())"2""noCurrentTask()",this,SLOT(eraseStatusBarText())"1""eraseStatusBarText()");
170 connect(InfoSender::instance(), SIGNAL(sent(Info))"2""sent(Info)",this, SLOT( displayInfo(Info))"1""displayInfo(Info)");
171
172
173 //*********************************
174 // Signals for ModItem
175 //*********************************
176 connect(_ui->treeModItem, SIGNAL(clicked(QModelIndex))"2""clicked(QModelIndex)",this, SLOT(onSelectedModItem(QModelIndex))"1""onSelectedModItem(QModelIndex)");
177 connect( _ui->pushLoadMoFile, SIGNAL(clicked())"2""clicked()", this, SLOT(loadMoFile())"1""loadMoFile()");
178
179 //*********************************
180 // Signals for About dialogs
181 //*********************************
182 connect(_ui->actionAboutQt, SIGNAL(triggered())"2""triggered()",this, SLOT(dispAboutQt())"1""dispAboutQt()");
183 connect( _ui->actionAboutOMOptim, SIGNAL(triggered())"2""triggered()", this, SLOT(dispAboutOMOptim())"1""dispAboutOMOptim()");
184
185
186
187
188 //*********************************
189 // Signals for plugins
190 //*********************************
191 connect(_ui->actionLoadPlugins,SIGNAL(triggered())"2""triggered()",this,SLOT(loadPlugins())"1""loadPlugins()");
192
193
194 //*********************************
195 // Reload gui configuration
196 //*********************************
197 readSettings();
198
199 //*********************************
200 // Configuration
201 //*********************************
202
203 updateProblemsMenu();
204}
205
206MainWindow::~MainWindow()
207{
208 delete _ui;
209}
210
211void MainWindow::clearLog()
212{
213 _textLog->clear();
214 _ui->textDebug->clear();
215 _ui->textOMC->clear();
216}
217
218void MainWindow::displayInfo(Info i)
219{
220 if(i.infoMsg.isEmpty() && i.infoType!=ListInfo::TASK)
221 return ;
222
223 QTextCharFormat infoFormat;
224
225 // stylize message
226 QString prefix;
227 QString suffix;
228
229 switch(i.infoType)
230 {
231 case ListInfo::NORMAL2 :
232 case ListInfo::TASK :
233 prefix = "";
234 suffix = "";
235 infoFormat.setForeground(Qt::black);
236 infoFormat.setFontWeight(QFont::Normal);
237 break;
238 case ListInfo::WARNING2 :
239 prefix = "<b><font color='#FF7700'>Warning : ";
240 suffix = "</font></b>";
241 infoFormat.setForeground(QBrush(QColor(255,119,0)));
242 infoFormat.setFontWeight(QFont::Bold);
243 break;
244 case ListInfo::ERROR2 :
245 prefix = "<b><font color='red'>Error : ";
246 suffix = "</font></b>";
247 infoFormat.setForeground(Qt::red);
248 infoFormat.setFontWeight(QFont::Bold);
249 break;
250
251 case ListInfo::OMCNORMAL2 :
252 prefix = "OMCNormal :";
253 suffix = "";
254 infoFormat.setForeground(Qt::black);
255 infoFormat.setFontWeight(QFont::Normal);
256 break;
257 case ListInfo::OMCWARNING2 :
258 prefix = "OMCWarning :";
259 suffix = "";
260 infoFormat.setForeground(Qt::darkYellow);
261 infoFormat.setFontWeight(QFont::Bold);
262 break;
263 case ListInfo::OMCERROR2 :
264 prefix = "<b><font color='red'>OMCError : ";
265 suffix = "</font></b>";
266 infoFormat.setForeground(Qt::red);
267 infoFormat.setFontWeight(QFont::Bold);
268 break;
269 case ListInfo::INFODEBUG :
270 prefix = "<b><font color='blue'>Debug : ";
271 suffix = "</font></b>";
272 infoFormat.setForeground(Qt::blue);
273 infoFormat.setFontWeight(QFont::Bold);
274 break;
275 }
276
277 // QString msg = prefix + i.infoMsg + suffix;
278 QString timePrefix = "["+QTime::currentTime().toString()+"] ";
279 QString msg = timePrefix + i.infoMsg;
280 // display
281 switch(i.infoType)
282 {
283 case ListInfo::NORMAL2 :
284 case ListInfo::WARNING2 :
285 case ListInfo::ERROR2 :
286 case ListInfo::TASK :
287 if(!i.infoMsg.isEmpty())
288 {
289 _textLog->setCurrentCharFormat(infoFormat);
290 _textLog->append(msg);
291 }
292 break;
293 case ListInfo::OMCNORMAL2 :
294 case ListInfo::OMCWARNING2 :
295 case ListInfo::OMCERROR2 :
296 _ui->textOMC->setCurrentCharFormat(infoFormat);
297 _ui->textOMC->append(msg);
298 break;
299 case ListInfo::INFODEBUG :
300 _ui->textDebug->setCurrentCharFormat(infoFormat);
301 _ui->textDebug->append(msg);
302 break;
303 }
304
305 if(i.infoType==ListInfo::TASK)
306 {
307 setStatusBarText(msg);
308 }
309}
310
311
312void MainWindow::onStartedOMCThread(QString _name)
313{
314 QString msg;
315 msg.sprintf("%s started",_name.toLatin1().data());
316 _ui->textOMC->append(msg);
317}
318void MainWindow::onFinishedOMCThread(QString _name)
319{
320 QString msg;
321 msg.sprintf("%s finished",_name.utf16());
322 _ui->textOMC->append(msg);
323}
324void MainWindow::onTerminatingOMCThread(QString _name)
325{
326 QString msg;
327 msg.sprintf("%s terminated",_name.utf16());
328 _ui->textOMC->append(msg);
329}
330
331void MainWindow::newProject()
332{
333 // Opening Form
334 newProjectForm *form = new newProjectForm();
335 form->show();
336
337 //Saving form information
338 if (form->exec() == QDialog::Accepted) {
339
340 // project information
341 _project->clear();
342 _project->setName(form->projectName);
343 _project->setIsDefined(true);
344
345 // save it (as it is first save, it will ask for path)
346 saveProject();
347
348 // actualize gui
349 actualizeGuiFromProject();
350 }
351}
352
353void MainWindow::saveProject()
354{
355 if (!_project->isDefined())
356 {
357 // project does not exist
358 }
359 else
360 {
361 QString _filePath = _project->filePath() ;
362 if(_filePath.length())
363 {
364 _project->save(true);
365 }
366 else
367 {
368 _filePath = QFileDialog::getSaveFileName(
369 this,
370 "MO - Save Project",
371 _project->name()+".min",
372 "MO project (*.min)" );
373 if(!_filePath.isNull())
374 {
375 _project->setFilePath(_filePath);
376 _project->save(true);
377 }
378 }
379
380 updateRecentFilesList(_filePath);
381
382 actualizeGuiFromProject();
383 }
384
385
386}
387void MainWindow::loadProject()
388{
389
390
391 QString filename = QFileDialog::getOpenFileName(
392 this,
393 qAppName()+" - Open Project",
394 getLastProjectFolder(),
395 "project (*.min)" );
396
397 if (!filename.isNull())
398 {
399 OMOptimGuiTools::consolidateModelsPath(filename,this);
400 bool loaded = _project->load(filename);
401
402 if(loaded)
403 {
404 updateRecentFilesList(filename);
405 QFileInfo info = QFileInfo(filename);
406 setLastProjectFolder(info.absolutePath());
407 }
408
409 }
410
411 //update GUI
412 actualizeGuiFromProject();
413
414 refreshModelTreeView();
415}
416
417void MainWindow::loadProject(QString filename)
418{
419 OMOptimGuiTools::consolidateModelsPath(filename,this);
420 bool loaded = _project->load(filename);
421 if(loaded)
422 {
423 updateRecentFilesList(filename);
424 QFileInfo info = QFileInfo(filename);
425 setLastProjectFolder(info.absolutePath());
426 }
427
428 //update GUI
429 actualizeGuiFromProject();
430
431 refreshModelTreeView();
432}
433
434void MainWindow::launchScript()
435{
436
437
438 QString filename = QFileDialog::getOpenFileName(
439 this,
440 qAppName()+" - Open script",
441 getLastProjectFolder(),
442 "All files (*.*)" );
443
444 if(!filename.isNull())
445 _project->launchScript(QFileInfo(filename));
446}
447
448void MainWindow::dispScriptFunctions()
449{
450 TextDlg dlg(_project->scriptParser()->helpText(),"Script functions",this);
451 dlg.exec();
452}
453
454void MainWindow::launchScriptText()
455{
456 ScriptTextDlg dlg(_project->scriptParser(),_project,this);
457 dlg.exec();
458}
459
460void MainWindow::exportFolder()
461{
462 QString folderPath = QFileDialog::getExistingDirectory(
463 this,
464 "OMOptim - Export project folder",
465 _project->folder().absolutePath());
466
467 if(!folderPath.isEmpty())
468 {
469 QDir folder(folderPath);
470 if(!folder.entryList(QDir::NoDotAndDotDot | QDir::Dirs | QDir::Files).isEmpty())
471 {
472 QMessageBox msgbox(QMessageBox::Warning,"Consolidate folder","Please select an empty folder",
473 QMessageBox::Cancel|QMessageBox::Retry,this);
474
475 int ret = msgbox.exec();
476 if(ret == QMessageBox::Retry)
477 this->exportFolder();
478 return;
479 }
480 bool includeMSL;
481 if(QMessageBox::Yes == QMessageBox::question(this,"Export folder","Includes Modelica Standard Library within .mo file ?",QMessageBox::Yes | QMessageBox::No,QMessageBox::No))
482 includeMSL = true;
483 else
484 includeMSL = false;
485 _project->exportProjectFolder(folder,includeMSL);
486 }
487}
488
489
490void MainWindow::loadPlugins()
491{
492 // get last plugin folder
493 QSettings settings("MO", "Settings");
494 QString folder = settings.value("MO/recentPluginsFolder").toString();
495
496 QString filters = "All files (*.*)";
497#ifdef WIN32
498 filters = "OMOptim plugins (*.dll);; All files (*.*)";
499#endif
500 QStringList filenames = QFileDialog::getOpenFileNames(
501 this,
502 "OMOptim - Load plugins",
503 folder,
504 filters );
505
506 foreach (QString fileName, filenames)for (auto _container_ = QtPrivate::qMakeForeachContainer(filenames
); _container_.control && _container_.i != _container_
.e; ++_container_.i, _container_.control ^= 1) for (QString fileName
= *_container_.i; _container_.control; _container_.control =
0)
507 {
508 _project->loadPlugin(fileName,true,true);
509 }
510
511 if(filenames.size()>0)
512 {
513 QDir dir(filenames.at(0));
514 settings.setValue("MO/recentPluginsFolder",dir.absolutePath());
515 }
516}
517
518void MainWindow::loadCases()
519{
520 // start with project folder
521 QString folder = _project->folder().absolutePath();
522
523 QString problemsFolder = QFileDialog::getExistingDirectory(
524 this,
525 "OMOptim - Load problems",
526 folder);
527
528 _project->addOMCases(problemsFolder);
529}
530
531void MainWindow::connectProject()
532{
533
534 // first disconnect existing signal-slots
535 _project->disconnect(this);
536 _project->_mofilesWatcher.disconnect(this);
537
538
539 connect(_project, SIGNAL(projectAboutToBeReset())"2""projectAboutToBeReset()",this, SLOT(onProjectAboutToBeReset())"1""onProjectAboutToBeReset()");
540 connect(_project, SIGNAL(projectChanged())"2""projectChanged()",this, SLOT( actualizeGuiFromProject())"1""actualizeGuiFromProject()");
541 connect(_project, SIGNAL(sendProgress(float))"2""sendProgress(float)", this, SLOT(displayProgress(float))"1""displayProgress(float)");
542 connect(_project, SIGNAL(sendProgress(float,int,int))"2""sendProgress(float,int,int)", this, SLOT(displayProgress(float,int,int))"1""displayProgress(float,int,int)");
543
544
545 //*********************************
546 // Signals for problems
547 //*********************************
548 connect( _project, SIGNAL(addedProblem(Problem*))"2""addedProblem(Problem*)",this, SLOT(onAddedProblem(Problem*))"1""onAddedProblem(Problem*)");
549 connect( _project, SIGNAL(beforeRemoveProblem(Problem*))"2""beforeRemoveProblem(Problem*)",this, SLOT(removeProblemTab(Problem*))"1""removeProblemTab(Problem*)");
550 connect( _project, SIGNAL(problemBegun(Problem*))"2""problemBegun(Problem*)",this,SLOT(onProblemBegun(Problem*))"1""onProblemBegun(Problem*)");
551 connect( _project, SIGNAL(problemFinished(Problem*,Result*))"2""problemFinished(Problem*,Result*)",this,SLOT(onProblemFinished(Problem*,Result*))"1""onProblemFinished(Problem*,Result*)");
552 connect( _project, SIGNAL(newProblemProgress(float))"2""newProblemProgress(float)",this,SLOT(onNewProblemProgress(float))"1""onNewProblemProgress(float)");
553 connect( _project, SIGNAL(newProblemProgress(float,int,int))"2""newProblemProgress(float,int,int)",this,SLOT(onNewProblemProgress(float,int,int))"1""onNewProblemProgress(float,int,int)");
554
555
556 _widgetProgress->disconnect(SIGNAL(askProblemStop(Problem*))"2""askProblemStop(Problem*)");
557 connect( _widgetProgress, SIGNAL(askProblemStop(Problem*))"2""askProblemStop(Problem*)",_project,SLOT(onProblemStopAsked(Problem*))"1""onProblemStopAsked(Problem*)");
558
559
560 //*********************************
561 // Signals for problem interfaces
562 //*********************************
563 connect(_project,SIGNAL(interfacesModified())"2""interfacesModified()",this,SLOT(updateProblemsMenu())"1""updateProblemsMenu()");
564
565 //*********************************
566 // Signals for solved problems
567 //*********************************
568 connect(_project, SIGNAL(beforeRemoveResult(Result*))"2""beforeRemoveResult(Result*)",this, SLOT(removeResultTab(Result*))"1""removeResultTab(Result*)");
569 connect(_project, SIGNAL(addedResult(Result*))"2""addedResult(Result*)",this, SLOT(onAddedResult(Result*))"1""onAddedResult(Result*)");
570
571 //*********************************
572 // Signals for model
573 //*********************************
574 connect(&_project->_mofilesWatcher,SIGNAL(fileChanged(const QString&))"2""fileChanged(const QString&)",this,SLOT(onMoFileChanged(const QString&))"1""onMoFileChanged(const QString&)");
575 connect(_project,SIGNAL(modItemsTreeRefreshed())"2""modItemsTreeRefreshed()",this,SLOT(refreshModelTreeView())"1""refreshModelTreeView()");
576
577 //*********************************
578 // Signals for MOomc
579 //*********************************
580 connect(_project->moomc(),SIGNAL(startOMCThread(QString))"2""startOMCThread(QString)",this,SLOT(onStartedOMCThread(QString))"1""onStartedOMCThread(QString)");
581 connect(_project->moomc(),SIGNAL(finishOMCThread(QString))"2""finishOMCThread(QString)",this,SLOT(onFinishedOMCThread(QString))"1""onFinishedOMCThread(QString)");
582
583
584}
585
586
587void MainWindow::actualizeGuiFromProject()
588{
589 _tabProject->actualizeGuiFromProject();
590
591 // Menus and buttons
592 _ui->actionSaveProject->setEnabled(_project->isDefined());
593 _ui->menuProblems->setEnabled(_project->isDefined());
594 _ui->actionDatabases->setEnabled(_project->isDefined());
595 _ui->actionOMCShell->setEnabled(_project->isDefined());
596 _ui->actionOMCClear->setEnabled(_project->isDefined());
597 _ui->actionLoadMoFile->setEnabled(_project->isDefined());
598 _ui->actionLoadModelicaLibrary->setEnabled(_project->isDefined());
599
600 QString windowTitle = "OMOptim - "+_project->name();
601 if(!_project->isSaved()&& _project->isDefined())
602 windowTitle.append("*");
603 this->setWindowTitle(windowTitle);
604}
605
606
607void MainWindow::newOMCShell()
608{
609 if(_project->isDefined())
610 {
611 //adding tab
612 TabOMC* newTab = new TabOMC(_project);
613 newTab->setBackgroundRole(QPalette::Window);
614 newTab->setAutoFillBackground(true);
615 newTab->setWindowTitle("OMC");
616
617 //Adding tab
618 _tabMain->addTab(newTab,"OMC");
619 _tabMain->setCurrentWidget(newTab);
620 }
621}
622
623void MainWindow::openSettings()
624{
625 DlgSettings *dlg = new DlgSettings(true);
626 dlg->exec();
627}
628
629void MainWindow::OMCClear()
630{
631 if(_project->isDefined())
632 {
633 _project->moomc()->clear();
634 }
635}
636
637
638void MainWindow::enableOMCaseTab(QModelIndex index)
639{
640 if(index.isValid())
641 {
642 OMCase* selectedCase = _casesTree->item(index);
643 _tabMain->enableCaseTab(selectedCase);
644 }
645}
646
647void MainWindow::quit()
648{
649 _project->terminateOms();
650
651 if(!_project->isSaved() && _project->isDefined())
652 {
653 QMessageBox msgBox;
654 msgBox.setText("The project has been modified.");
655 msgBox.setInformativeText("Do you want to save your changes?");
656 msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
657 msgBox.setDefaultButton(QMessageBox::Save);
658 int ret = msgBox.exec();
659 switch (ret)
660 {
661 case QMessageBox::Save:
662 _project->save(true);
663 qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->quit();
664 break;
665 case QMessageBox::Discard:
666 qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->quit();
667 break;
668 case QMessageBox::Cancel:
669 // Cancel was clicked
670 break;
671 default:
672 // should never be reached
673 break;
674 }
675 }
676 // if the slot is activated by the File->Quit menuitem.
677 QAction *pActionQuit = qobject_cast<QAction*>(const_cast<QObject*>(sender()));
678 if (pActionQuit)
679 qApp(static_cast<QApplication *>(QCoreApplication::instance
()))
->quit();
680}
681void MainWindow::onProjectAboutToBeReset()
682{
683 // deleting tabs
684 while(_tabMain->count()>1)
685 {
686 _tabMain->removeTab(1);
687 }
688
689 _casesTreeView->reset();
690 _ui->treeModItem->reset();
691
692 actualizeGuiFromProject();
693}
694
695void MainWindow::onAddedProblem(Problem* newProblem)
696{
697 // Creating problem tab
698 ProblemInterface* itf = (_project->problemsInterfaces()).interfaceOf(newProblem);
699
700 QTime elapsed;
701 if(itf)
702 {
703 elapsed.restart();
704 _tabMain->addProblemTab(newProblem,itf->createProblemTab(newProblem,this));
705 }
706
707 _tabMain->enableCaseTab(newProblem);
708}
709
710void MainWindow::onAddedResult(Result* newResult)
711{
712 // Creating problem tab
713 ProblemInterface* itf = _project->problemsInterfaces().interfaceOf(newResult);
714
715 QTime elapsed;
716 if(itf)
717 {
718 elapsed.restart();
719 _tabMain->addResultTab(newResult,itf->createResultTab(newResult,this));
720 }
721
722 _tabMain->enableCaseTab(newResult);
723}
724
725void MainWindow::removeResult()
726{
727 // SLOT : sender is menu, data is containing problem number
728 QAction *action = qobject_cast<QAction *>(sender());
729 if (action)
730 {
731 int iPb = action->data().toInt();
732 if((iPb>-1) && (iPb<_project->results()->rowCount()))
733 removeResult(_project->results()->at(iPb));
734 }
735}
736
737
738void MainWindow::removeResult(Result* result)
739{
740 QMessageBox msgBox;
741 msgBox.setText("Removing solved problem cannot be undone.");
742 QString msg;
743 msg.sprintf("Are you sure you want to remove %s ?",result->name().toLatin1().data());
744 msgBox.setInformativeText(msg);
745 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
746 msgBox.setDefaultButton(QMessageBox::Yes);
747
748 if(msgBox.exec() == QMessageBox::Yes)
749 {
750 _project->removeResult(result);
751 }
752}
753
754void MainWindow::removeResultTab(Result* result)
755{
756 //remove tab
757 _tabMain->removeTab(MOTabBase::TABSOLVEDPROBLEM,result->name());
758}
759
760void MainWindow::removeProblem()
761{
762 // SLOT : sender is menu, data is containing problem number
763 QAction *action = qobject_cast<QAction *>(sender());
764 if (action)
765 {
766 int iPb = action->data().toInt();
767 if((iPb>-1) && (iPb<_project->problems()->rowCount()))
768 removeProblem(_project->problems()->at(iPb));
769 }
770}
771
772
773void MainWindow::removeProblem(Problem* problem)
774{
775
776 QMessageBox msgBox;
777 msgBox.setText("Removing problem cannot be undone.");
778 QString msg;
779 msg.sprintf("Are you sure you want to remove %s ?",problem->name().toLatin1().data());
780 msgBox.setInformativeText(msg);
781 msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::Cancel);
782 msgBox.setDefaultButton(QMessageBox::Yes);
783
784 if(msgBox.exec() == QMessageBox::Yes)
785 {
786 _project->removeProblem(problem);
787 }
788}
789
790void MainWindow::removeProblemTab(Problem* problem)
791{
792 //remove tab
793 _tabMain->removeTab(MOTabBase::TABPROBLEM,problem->name());
794}
795
796void MainWindow::renameProblem()
797{
798 // SLOT : sender is menu, data is containing problem number
799 QAction *action = qobject_cast<QAction *>(sender());
800 if (action)
801 {
802 int iPb = action->data().toInt();
803 if((iPb>-1) && (iPb<_project->problems()->rowCount()))
804 renameProblem(_project->problems()->at(iPb));
805 }
806
807}
808
809void MainWindow::renameProblem(Problem* problem)
810{
811 bool ok;
812 QString newName = QInputDialog::getText(this, "Rename...",
813 "New name :", QLineEdit::Normal,problem->name(),&ok);
814
815 if (ok && !newName.isEmpty())
816 {
817 _project->renameProblem(problem,newName);
818 }
819}
820
821
822void MainWindow::renameResult()
823{
824 // SLOT : sender is menu, data is containing problem number
825 QAction *action = qobject_cast<QAction *>(sender());
826 if (action)
827 {
828 int iPb = action->data().toInt();
829 if((iPb>-1) && (iPb<_project->results()->rowCount()))
830 renameResult(_project->results()->at(iPb));
831 }
832
833}
834void MainWindow::renameResult(Result* result)
835{
836 bool ok;
837 QString newName = QInputDialog::getText(this, "Rename...",
838 "New name :", QLineEdit::Normal,result->name(),&ok);
839
840 if (ok && !newName.isEmpty())
841 {
842 _project->renameResult(result,newName);
843 }
844}
845
846
847
848
849
850void MainWindow::rightClickedOnCase(const QPoint & iPoint)
851{
852 //Popup on cases tree
853 QModelIndex index ;
854 index = _casesTreeView->indexAt(iPoint);
855 QModelIndexList indexes = _casesTreeView->selectionModel()->selectedIndexes();
856
857 if ( !index.isValid() == -1 )
858 {
859 // no item selected
860 }
861 else
862 {
863 if(indexes.contains(index))
864 {
865 QMenu* caseMenu = NULL__null;
866 OMCase* selectedCase = _casesTree->item(index);
867
868 if(_project->problems()->contains(selectedCase))
869 caseMenu = GuiTools::createProblemPopupMenu(_project,this,_casesTreeView->mapToGlobal(iPoint),dynamic_cast<Problem*>(selectedCase),index.row());
870 if(_project->results()->contains(selectedCase))
871 caseMenu = GuiTools::createResultPopupMenu(_project,this,_casesTreeView->mapToGlobal(iPoint),dynamic_cast<Result*>(selectedCase),index.row());
872
873 if(caseMenu)
874 caseMenu->exec(_casesTreeView->mapToGlobal(iPoint));
875 }
876 }
877}
878
879
880void MainWindow::showModItemsTreePopup(const QPoint & iPoint)
881{
882 // Popup on ModItem Tree
883 QModelIndex index ;
884 index = _ui->treeModItem->indexAt(iPoint);
885 if ( !index.isValid())
886 {
887 // no item selected
888 }
889 else
890 {
891 ModItem* selectedModItem = static_cast<ModItem*>(index.internalPointer());
892 QMenu * modClassMenu= OMOptimGuiTools::newModItemPopupMenu(_project,_ui->treeModItem->mapToGlobal(iPoint),selectedModItem);
893 if(modClassMenu)
894 modClassMenu->exec(_ui->treeModItem->mapToGlobal(iPoint));
895 }
896}
897
898
899void MainWindow::updateRecentFilesList(QString fileName)
900{
901 QSettings settings("MO", "Settings");
902 QStringList files = settings.value("MO/recentFileList").toStringList();
903
904 files.removeAll(fileName);
905 files.prepend(fileName);
906
907 while (files.size() > MaxRecentFiles)
908 {
909 files.removeLast();
910 }
911
912 settings.setValue("MO/recentFileList", files);
913}
914
915void MainWindow::setLastProjectFolder(QString folderName)
916{
917 QSettings settings("MO", "Settings");
918 settings.setValue("MO/recentProjectFolder", folderName);
919}
920
921void MainWindow::setLastDatabaseFolder(QString folderName)
922{
923 QSettings settings("MO", "Settings");
924 settings.setValue("MO/recentDatabseFolder", folderName);
925}
926
927QString MainWindow::getLastProjectFolder()
928{
929 QSettings settings("MO", "Settings");
930 return settings.value("MO/recentProjectFolder").toString();
931}
932
933QString MainWindow::getLastDatabaseFolder()
934{
935 QSettings settings("MO", "Settings");
936 return settings.value("MO/recentDatabaseFolder").toString();
937}
938
939void MainWindow::createRecentFilesMenu()
940{
941
942 _recentFileActs.clear();
943 QAction* newAction;
944 QSettings settings("MO", "Settings");
945 QStringList files = settings.value("MO/recentFileList").toStringList();
946
947 int numRecentFiles = qMin(files.size(), (int)MaxRecentFiles);
948
949 for (int i = 0; i < numRecentFiles; ++i) {
950 newAction = new QAction(this);
951 QString text = tr("&%1 %2").arg(i + 1).arg(QFileInfo(files[i]).fileName());
952 newAction->setText(text);
953 newAction->setData(files[i]);
954 newAction->setVisible(true);
955 connect(newAction, SIGNAL(triggered())"2""triggered()",
956 this, SLOT(openRecentFile())"1""openRecentFile()");
957 _recentFileActs.push_back(newAction);
958 _ui->menuFile->insertAction(_ui->actionQuit,newAction);
959 }
960
961 //_separatorAct->setVisible(numRecentFiles > 0);
962 _ui->menuFile->insertSeparator(_ui->actionQuit);
963}
964
965
966void MainWindow::clearRecentFilesMenu()
967{
968 QSettings settings("MO", "Settings");
969 QStringList files;
970 settings.setValue("MO/recentFileList", QStringList());
971
972 createRecentFilesMenu();
973}
974
975void MainWindow::openRecentFile()
976{
977 QAction *action = qobject_cast<QAction *>(sender());
978 if (action)
979 {
980 loadProject(action->data().toString());
981 }
982}
983
984void MainWindow::displayProgress(float fraction)
985{
986 if(fraction==0)
987 {
988 _ui->dockProgress->hide();
989 //_widgetProgress->hide();
990 _widgetProgress->setProgress(0);
991 }
992 else
993 {
994 _ui->dockProgress->show();
995 //_widgetProgress->show();
996 _widgetProgress->setProgress(fraction);
997 }
998}
999
1000void MainWindow::displayProgress(float fraction,int curEval,int totalEval)
1001{
1002 if(fraction==0)
1003 {
1004 _ui->dockProgress->hide();
1005 //_widgetProgress->hide();
1006 _widgetProgress->setProgress(0,curEval,totalEval);
1007 }
1008 else
1009 {
1010 _ui->dockProgress->show();
1011 //_widgetProgress->show();
1012 _widgetProgress->setProgress(fraction,curEval,totalEval);
1013 }
1014}
1015
1016void MainWindow::onProblemBegun(Problem* problem)
1017{
1018 _widgetProgress->setCurProblem(problem);
1019 _ui->dockProgress->show();
1020 //_widgetProgress->show();
1021 _widgetProgress->newTask("Running "+problem->name()+"...");
1022}
1023
1024void MainWindow::onProblemFinished(Problem*,Result*)
1025{
1026 _ui->dockProgress->hide();
1027 //_widgetProgress->hide();
1028}
1029
1030void MainWindow::onNewProblemProgress(float fraction)
1031{
1032 _widgetProgress->setProgress(fraction);
1033}
1034
1035
1036void MainWindow::onNewProblemProgress(float fraction,int curEval,int totalEval)
1037{
1038 _widgetProgress->setProgress(fraction,curEval,totalEval);
1039}
1040
1041void MainWindow::showModItem(ModItem* modClass)
1042{
1043 _ui->treeModItem->expand(_project->modItemsTree()->indexOf(modClass));
1044}
1045
1046void MainWindow::onMoFileChanged(const QString &moFile)
1047{
1048 // first remove from watcher to avoid multiple asking
1049 _project->_mofilesWatcher.removePath(moFile);
1050
1051 QMessageBox msgbox(QMessageBox::Question,"Reload .mo file","Model file has been modified. Do you want to reload it ? \n"+moFile,
1052 QMessageBox::No|QMessageBox::Yes,this);
1053 if(msgbox.exec()==QMessageBox::Yes)
1054 {
1055 _project->loadMoFile(moFile,true,true);
1056 refreshModelTreeView();
1057 }
1058 // restore watcher
1059 _project->_mofilesWatcher.addPath(moFile);
1060}
1061
1062void MainWindow::loadMoFile()
1063{
1064 //get last .mo folder
1065 QSettings settings("OMOptim", "Settings");
1066 QString lastMoFolder = settings.value("LastMoFolder").toString();
1067
1068 QStringList fileNames = QFileDialog::getOpenFileNames(
1069 this,
1070 "MO - Add .mo file to project",
1071 lastMoFolder,
1072 "Modelica file (*.mo)" );
1073
1074 for(int i=0;i<fileNames.size();i++)
1075 _project->loadMoFile(fileNames.at(i));
1076
1077 refreshModelTreeView();
1078
1079 // save last .mo folder
1080 if(fileNames.size())
1081 {
1082 QFileInfo loaded(fileNames.at(0));
1083 lastMoFolder = loaded.absoluteDir().absolutePath();
1084 settings.setValue("LastMoFolder",lastMoFolder);
1085 }
1086}
1087
1088void MainWindow::loadModelicaLibrary()
1089{
1090 _project->loadModelicaLibrary();
1091 refreshModelTreeView();
1092}
1093
1094void MainWindow::loadExecutableModel()
1095{
1096 WidgetLoadExeModel* widget = new WidgetLoadExeModel(_project,this);
1
Memory is allocated
1097 QString name;
1098 bool isloaded =false;
1099 while((name.isEmpty() || _project->modItemsTree()->findInDescendants(name)) && !isloaded )
2
Assuming the condition is false
3
Assuming the condition is false
4
Loop condition is false. Execution continues on line 1095
1100 {
1101 if(widget->exec() == QDialog::Accepted)
1102 {
1103 name = widget->name();
1104 if( !widget->name().isEmpty() && !_project->modItemsTree()->findInDescendants(name))
1105 {
1106 _project->loadExecutableModel(name, widget->exeFileInfo(),widget->inputFileInfo());
1107 refreshModelTreeView();
1108 isloaded =true;
1109 }
1110 }
1111 else
1112 break;
1113 }
1114}
5
Potential leak of memory pointed to by 'widget'
1115
1116void MainWindow::refreshModelTree()
1117{
1118 _project->refreshAllMod();
1119 refreshModelTreeView();
1120}
1121
1122void MainWindow::refreshModelTreeView()
1123{
1124 _ui->treeModItem->setModel(NULL__null);
1125 _ui->treeModItem->setModel(_project->modItemsTree());
1126}
1127
1128void MainWindow::updateProblemsMenu()
1129{
1130 _ui->menuProblems->clear();
1131 ProblemInterface* itf;
1132 QStringList problemTypes;
1133 QMenu* curMenu;
1134
1135 for(int i=0;i<_project->problemsInterfaces().uniqueInterfaces().size();i++)
1136 {
1137 itf = _project->problemsInterfaces().uniqueInterfaces().at(i);
1138 problemTypes = itf->problemTypes();
1139
1140 if(problemTypes.size()>1)
1141 {
1142 curMenu = new QMenu(itf->name(),_ui->menuProblems);
1143 _ui->menuProblems->addMenu(curMenu);
1144 }
1145 else
1146 curMenu = _ui->menuProblems;
1147
1148 for(int j=0;j<itf->problemTypes().size();j++)
1149 {
1150 QAction *action = new QAction(itf->problemTypes().at(j),this);
1151 action->setData(itf->problemTypes().at(j));
1152 connect(action,SIGNAL(triggered())"2""triggered()",this,SLOT(onPushedNewProblem())"1""onPushedNewProblem()");
1153
1154 curMenu->addAction(action);
1155 }
1156 }
1157}
1158
1159void MainWindow::onPushedNewProblem()
1160{
1161 QAction *action = qobject_cast<QAction *>(sender());
1162 QString problemType = action->data().toString();
1163 ProblemInterface *itf = _project->problemsInterfaces().value(problemType,NULL__null);
1164 if(itf)
1165 {
1166 bool pursue = true;
1167
1168 WidgetSelectModModel* widgetSelect;
1169
1170 QStringList modelsList;
1171
1172 if(itf)
1173 {
1174 switch(itf->modelNeeds(problemType))
1175 {
1176 case ProblemInterface::NOMODEL:
1177 break;
1178 case ProblemInterface::ONEMODEL:
1179 case ProblemInterface::SEVERALMODELS:
1180 widgetSelect = new WidgetSelectModModel(_project->modItemsTree(),itf->modelNeeds(problemType),this);
1181 if(widgetSelect->exec()==QDialog::Accepted)
1182 {
1183
1184 QList<ModItem*> models = widgetSelect->_selectedModels;
1185 for(int i=0;i<models.size();i++)
1186 modelsList.push_back(models.at(i)->name());
1187
1188 }
1189 else
1190 pursue = false;
1191 delete widgetSelect;
1192 break;
1193 }
1194 if(pursue)
1195 _project->addNewProblem(itf,modelsList,problemType);
1196 }
1197
1198 }
1199}
1200
1201void MainWindow::onSelectedModItem(QModelIndex index)
1202{
1203 if(index.isValid())
1204 {
1205 ModItem* modClass = static_cast<ModItem*>(index.internalPointer());
1206
1207 if(modClass)
1208 _project->setCurModItem(modClass);
1209 }
1210 else
1211 _project->setCurModItem(NULL__null);
1212}
1213
1214void MainWindow::closeEvent(QCloseEvent *event)
1215{
1216 _project->scriptParser()->stop();
1217 QSettings settings("MO", "GUI_");
1218 settings.setValue(QApplication::applicationName()+"/geometry", saveGeometry());
1219 settings.setValue(QApplication::applicationName()+"/windowState", saveState());
1220 QMainWindow::closeEvent(event);
1221}
1222
1223void MainWindow::readSettings()
1224{
1225 QSettings settings("MO", "GUI");
1226 restoreGeometry(settings.value(QApplication::applicationName()+"/geometry").toByteArray());
1227 restoreState(settings.value(QApplication::applicationName()+"/windowState").toByteArray());
1228}
1229
1230void MainWindow::dispAboutOMOptim()
1231{
1232 AboutOMOptim dlg(this);
1233 dlg.exec();
1234}
1235
1236void MainWindow::dispAboutQt()
1237{
1238 QMessageBox::aboutQt(this,"About Qt");
1239}
1240
1241void MainWindow::openUserManual()
1242{
1243 QStringList pathTries;
1244
1245 pathTries << QApplication::applicationDirPath().replace("\\", "/")+QDir::separator()+"../share/doc/omc/OpenModelicaUsersGuide.pdf";
1246 pathTries << OpenModelica::home().replace("\\", "/").append("/share/doc/omc/OpenModelicaUsersGuide.pdf");
1247
1248 int iTry=0;
1249 bool openOk=false;
1250 while(iTry<pathTries.size()&&!openOk)
1251 {
1252 openOk = QDesktopServices::openUrl(QUrl(QString("file:///").append(pathTries.at(iTry))));
1253 iTry++;
1254 }
1255}
1256
1257//! shows the progress bar contained inside the status bar
1258//! @see hideProgressBar()
1259void MainWindow::showStatusBar()
1260{
1261 _statusBar->setVisible(true);
1262}
1263
1264//! hides the progress bar contained inside the status bar
1265//! @see showProgressBar()
1266void MainWindow::hideStatusBar()
1267{
1268 _statusBar->setVisible(false);
1269}
1270
1271//! increases the value of the progress bar contained inside the status bar
1272void MainWindow::increaseStProgressBar()
1273{
1274 _stProgressBar->setValue(_stProgressBar->value()+1);
1275}
1276
1277
1278void MainWindow::setStatusBarText(QString text)
1279{
1280 _statusBar->setVisible(true);
1281 _statusBar->showMessage(text);
1282}
1283
1284void MainWindow::eraseStatusBarText()
1285{
1286 _statusBar->hide();
1287 _statusBar->clearMessage();
1288}