]> AND Private Git Repository - blast.git/blob - MainWindow.cpp
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
moved vhdl gen. into block
[blast.git] / MainWindow.cpp
1 #include "MainWindow.h"
2 #include "Dispatcher.h"
3 #include "Parameters.h"
4 #include "BlockLibraryWidget.h"
5 #include "GroupWidget.h"
6 #include "GroupScene.h"
7 #include "VHDLConverter.h"
8 #include "Graph.h"
9 #include "FunctionalBlock.h"
10 #include <QDomDocument>
11 #include <QDomElement>
12 #include <QDomText>
13 #include <sstream>
14 #include "NewProjectDialog.h"
15
16 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
17
18   versionMaj = VERSION_MAJ;
19   versionMin = VERSION_MIN;
20   revision = REVISION;
21
22   // reading parameters
23   params  = new Parameters();
24   try {    
25     params->loadBlastConfiguration("blastconfig.xml");
26
27     if (!QFileInfo::exists(params->refLib)) {
28       params->loadReferencesFromXml();
29       int ret = QMessageBox::question(this,tr("Building references library"),tr("The reference block library does not exists.\n References have been read directly from the xml descriptions of blocks.\n It can be saved into a library in order to start application faster. "), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
30       if (ret == QMessageBox::Ok) {
31         params->saveReferencesToLib();
32       }
33     }
34     else {      
35       params->loadReferencesFromLib();
36     }
37
38     if (!QFileInfo::exists(params->implLib)) {
39       params->loadImplementationsFromXml();
40       int ret = QMessageBox::question(this,tr("Building implementations library"),tr("The block implementations library does not exists.\nImplementations have been read directly from the xml descriptions.\n It can be saved into a library in order to start application faster. "), QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
41       if (ret == QMessageBox::Ok) {
42         params->saveImplementationsToLib();
43       }
44     }
45     else {
46       params->loadImplementationsFromLib();
47     }
48   }
49   catch(Exception err) {
50     cerr << qPrintable(err.getDefaultMessage()) << endl;
51     cerr << "Aborting ..." << endl;
52     exit(1);
53   }
54
55   cout << "all references and implementations are loaded" << endl;
56
57   params->createDelayBlock();
58
59   // create the menu, action, ...
60   dispatcher = new Dispatcher(params,this);
61   params->setDispatcher(dispatcher);
62
63   // creating block library
64   library = new BlockLibraryWidget(dispatcher,params);
65   params->isCurrentProject = false;
66
67   QLabel* labDefault = new QLabel("BLAST: BLock ASsembler Tool");
68   stackedWidget = new QStackedWidget;
69   stackedWidget->addWidget(labDefault);
70   stackedWidget->setCurrentIndex(0);
71   this->setCentralWidget(stackedWidget);
72   this->setMinimumSize(800,600);
73
74   createActions();
75   createMenus(); 
76   setWindowTitle("blast - top group");
77   setFocusPolicy(Qt::StrongFocus);
78   setFocus();
79
80   readSettings();
81
82   initialize();
83
84 }
85
86 MainWindow::~MainWindow() {}
87
88 void MainWindow::initialize() {
89
90   projectMenuEnb = 0;
91   analysisMenuEnb = 0;
92
93   stackedWidget->setCurrentIndex(0);
94   enableProjectActions(true,PROJECT_NEW | PROJECT_OPEN, OP_RAZ);
95   enableAnalysisActions(false);
96
97   stackedWidget->setCurrentIndex(0);
98
99   resize(500,300);
100 }
101
102 void MainWindow::readSettings() {
103   QSettings settings;
104   settings.beginGroup("init");
105   checkNewVersion = settings.value("check_new_version").toString();
106   settings.endGroup();
107   if (checkNewVersion.isEmpty()) {
108     checkNewVersion = "true";
109   }
110   /*
111   cout << "test nouvelle version : " << qPrintable(checkNewVersion) << endl;
112   QUrl url("http://www.hrafnheim.fr/download/Cartomagic/carto_currentversion.txt");
113   QNetworkRequest request(url);
114   manager = new QNetworkAccessManager(this);
115   connect(manager,SIGNAL(finished(QNetworkReply*)), this, SLOT(slotCheckNewVersion(QNetworkReply*)));
116   manager->get(request);
117   */
118 }
119
120 void MainWindow::writeSettings() {
121   QSettings settings;
122   settings.beginGroup("init");
123   settings.setValue("check_new_version",checkNewVersion);
124   settings.endGroup();
125 }
126
127 void MainWindow::slotCheckNewVersion(QNetworkReply *reply) {
128
129   if (reply->error() == QNetworkReply::NoError) {
130     QString txt = reply->readAll();
131     QString currentVer = QString("%1.%2.%3").arg(versionMaj).arg(versionMin).arg(revision);
132     if (txt.contains(currentVer)) {
133       cout << "a jour" << endl;
134     }
135     else {
136       cout << "dernière version : " << qPrintable(txt) << ", version actuelle = " << qPrintable(currentVer) << endl;
137     }
138   }
139   else {
140     cout << "erreur = " << qPrintable(reply->errorString()) << endl;
141   }
142   reply->deleteLater();
143 }
144
145 void MainWindow::enableProjectActions(bool enbMenu, quint16 mask, quint8 op) {
146   if (enbMenu) {
147     projectMenu->setEnabled(true);
148   }
149   else {
150     projectMenu->setEnabled(false);
151   }
152
153   if (op == OP_ADD) {
154     projectMenuEnb = projectMenuEnb | mask;
155   }
156   else if (op == OP_REM) {
157     projectMenuEnb = (projectMenuEnb | mask) ^ mask;
158   }
159   else if (op == OP_RAZ) {
160     projectMenuEnb = mask;
161   }
162
163
164   if (projectMenuEnb & PROJECT_NEW) {
165     newProject->setEnabled(true);
166   }
167   else {
168     newProject->setEnabled(false);
169   }
170   if (projectMenuEnb & PROJECT_OPEN) {
171     openProject->setEnabled(true);
172   }
173   else {
174     openProject->setEnabled(false);
175   }
176   if (projectMenuEnb & PROJECT_SAVE) {
177     saveProject->setEnabled(true);
178   }
179   else {
180     saveProject->setEnabled(false);
181   }
182   if (projectMenuEnb & PROJECT_SAVEAS) {
183     saveAsProject->setEnabled(true);
184   }
185   else {
186     saveAsProject->setEnabled(false);
187   }
188   if (projectMenuEnb & PROJECT_CLOSE) {
189     closeProject->setEnabled(true);
190   }
191   else {
192     closeProject->setEnabled(false);
193   }
194   if (projectMenuEnb & PROJECT_LIB) {
195     openLibrary->setEnabled(true);
196   }
197   else {
198     openLibrary->setEnabled(false);
199   }
200 }
201
202 void MainWindow::enableAnalysisActions(bool enbMenu, quint16 mask, quint8 op) {
203   if (enbMenu) {
204     analysisMenu->setEnabled(true);
205   }
206   else {
207     analysisMenu->setEnabled(false);
208   }
209
210   if (op == OP_ADD) {
211     analysisMenuEnb = analysisMenuEnb | mask;
212   }
213   else if (op == OP_REM) {
214     analysisMenuEnb = (analysisMenuEnb | mask) ^ mask;
215   }
216   else if (op == OP_RAZ) {
217     analysisMenuEnb = mask;
218   }
219
220
221   if (analysisMenuEnb & ANALYSIS_ANALYZE) {
222     graphAnalysis->setEnabled(true);
223   }
224   else {
225     graphAnalysis->setEnabled(false);
226   }
227   if (analysisMenuEnb & ANALYSIS_GENERATE) {
228     generateVHDL->setEnabled(true);
229   }
230   else {
231     generateVHDL->setEnabled(false);
232   }
233 }
234
235 void MainWindow::createMenus(){
236
237   allMenuBar = menuBar();
238
239   projectMenu = allMenuBar->addMenu(tr("&Project"));
240   analysisMenu = allMenuBar->addMenu(tr("&Analysis"));
241   toolsMenu = allMenuBar->addMenu(tr("&Tools"));
242
243   projectMenu->addAction(newProject);
244   projectMenu->addAction(openProject);
245   projectMenu->addAction(saveProject);
246   projectMenu->addAction(saveAsProject);
247   projectMenu->addAction(closeProject);
248   projectMenu->addAction(openLibrary);
249
250   analysisMenu->addAction(graphAnalysis);
251   analysisMenu->addAction(generateVHDL);
252
253   toolsMenu->addAction(vhdlToXmlAct);
254
255
256 }
257
258 void MainWindow::createActions() {
259
260   newProject = new QAction(tr("&New project"), this);
261   newProject->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
262   newProject->setStatusTip(tr("Create a new project"));
263   connect(newProject, SIGNAL(triggered()), this, SLOT(slotNewProject()));
264
265   openProject = new QAction(tr("&Open project"), this);
266   openProject->setIcon(QPixmap::fromImage(QImage("icons/load.png")));
267   openProject->setStatusTip(tr("Open an existing project"));
268   connect(openProject, SIGNAL(triggered()), this, SLOT(slotLoadProject()));
269
270   saveProject = new QAction(tr("&Save project"), this);
271   saveProject->setIcon(QPixmap::fromImage(QImage("icons/save.png")));
272   saveProject->setStatusTip(tr("Save the current project"));
273   connect(saveProject, SIGNAL(triggered()), this, SLOT(slotSaveProject()));
274
275   saveAsProject = new QAction(tr("&Save project as..."), this);
276   saveAsProject->setIcon(QPixmap::fromImage(QImage("icons/save-as.png")));
277   saveAsProject->setStatusTip(tr("Save the current project as..."));
278   connect(saveAsProject, SIGNAL(triggered()), this, SLOT(slotSaveAsProject()));
279
280   closeProject = new QAction(tr("&Close project"), this);
281   closeProject->setIcon(QPixmap::fromImage(QImage("icons/close.png")));
282   closeProject->setStatusTip(tr("Close the current project"));
283   connect(closeProject, SIGNAL(triggered()), this, SLOT(slotCloseProject()));
284
285   openLibrary = new QAction(tr("Open block &Library"), this);
286   openLibrary->setIcon(QPixmap::fromImage(QImage("icons/add_block.png")));
287   openLibrary->setStatusTip(tr("Open block library window"));
288   connect(openLibrary, SIGNAL(triggered()), this, SLOT(slotOpenBlockLibrary()));
289
290   vhdlToXmlAct = new QAction(tr("&XML generator"), this);
291   vhdlToXmlAct->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
292   vhdlToXmlAct->setStatusTip(tr("Create a new XML generator"));
293   connect(vhdlToXmlAct, SIGNAL(triggered()), this, SLOT(slotVHDLToXml()));
294
295   graphAnalysis = new QAction(tr("&graph analysis"), this);
296   graphAnalysis->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
297   graphAnalysis->setStatusTip(tr("validate the graph"));
298   connect(graphAnalysis, SIGNAL(triggered()), this, SLOT(slotGraphAnalysis()));
299
300   generateVHDL = new QAction(tr("generate &VHDL"), this);
301   generateVHDL->setIcon(QPixmap::fromImage(QImage("icons/new.ico")));
302   generateVHDL->setStatusTip(tr("generate the VHDL code for the whole design"));
303   connect(generateVHDL, SIGNAL(triggered()), this, SLOT(slotGenerateVHDL()));
304
305 }
306
307 void MainWindow::save(QString projectFile) {
308   params->save(projectFile);
309 }
310
311 void MainWindow::slotLoadProject(){
312
313   params->projectFile = QFileDialog::getOpenFileName(0, "select a project file", "save/",tr("sauvegardes (*.xml)"));
314
315   if(! params->projectFile.isEmpty()){
316     GroupWidget* topGroup = dispatcher->loadProject(params->projectFile);
317     if (topGroup != NULL) {
318       addTopGroup(topGroup);
319       library->updateComboScene();
320       params->isCurrentProject = true;
321       enableProjectActions(true, PROJECT_CLOSE | PROJECT_SAVE | PROJECT_SAVEAS | PROJECT_LIB, OP_RAZ);
322       enableAnalysisActions(true, ANALYSIS_ANALYZE, OP_RAZ);
323     }
324     else {
325       QMessageBox msgBox;
326       msgBox.setText("Cannot open the project.");      
327       msgBox.setStandardButtons(QMessageBox::Cancel);
328       msgBox.setDefaultButton(QMessageBox::Cancel);
329
330       msgBox.exec();
331     }
332   }
333 }
334
335
336 void MainWindow::slotNewProject(){
337
338   NewProjectDialog* dialog = new NewProjectDialog(params);
339   int ret = dialog->exec();
340
341   if (ret == 1) {
342     enableProjectActions(true, PROJECT_CLOSE | PROJECT_SAVE | PROJECT_SAVEAS | PROJECT_LIB, OP_RAZ);
343     enableAnalysisActions(true, ANALYSIS_ANALYZE | ANALYSIS_GENERATE, OP_RAZ);
344     GroupWidget* topGroup = dispatcher->createTopScene();
345     addTopGroup(topGroup);
346     library->updateComboScene();
347     library->show();
348     params->isCurrentProject = true;
349   }
350 }
351
352 bool MainWindow::slotCloseProject(){
353
354   bool doClose = false;
355
356   if(params->isCurrentProject) {
357     if (params->unsaveModif) {
358       QMessageBox msgBox;
359       msgBox.setText("The project has been modified.");
360       msgBox.setInformativeText("Do you want to save your changes?");
361       msgBox.setStandardButtons(QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
362       msgBox.setDefaultButton(QMessageBox::Save);
363
364       int ret = msgBox.exec();
365
366       switch(ret) {
367       case QMessageBox::Save :
368         slotSaveProject();
369         doClose = true;
370         break;
371       case QMessageBox::Discard :
372         doClose = true;
373         break;
374       }
375     }
376     else {
377       doClose = true;
378     }
379     if (doClose) {
380       // removing the GroupWidget from stack
381       QWidget *widget = stackedWidget->widget(1);
382       stackedWidget->removeWidget(widget);
383       stackedWidget->setCurrentIndex(0);
384
385       dispatcher->closeCurrentProject();
386
387       params->isCurrentProject = false;
388       params->unsaveModif = false;
389       params->projectFile = QString();
390
391       initialize();
392     }
393   }
394   return doClose;
395 }
396
397
398 void MainWindow::slotVHDLToXml() {
399   new VHDLConverter();
400 }
401
402 void MainWindow::slotSaveProject(){
403   if(params->projectFile != QString()){
404     save(params->projectFile);
405   } else {
406     slotSaveAsProject();
407   }
408 }
409
410 void MainWindow::slotSaveAsProject(){
411   if(params->isCurrentProject){
412     QFileDialog dial(0, "Select a file", "save/");
413     dial.setDefaultSuffix(".xml");
414     dial.setAcceptMode(QFileDialog::AcceptSave);
415     if(dial.exec() == QFileDialog::AcceptSave){
416       params->projectFile = dial.selectedFiles().at(0);
417       if(params->projectFile != QString())
418         save(params->projectFile);
419     }
420   }
421 }
422
423 void MainWindow::slotOpenBlockLibrary() {
424   dispatcher->showBlocksLibrary();
425 }
426
427
428 void MainWindow::slotGraphAnalysis() {
429   bool compat = true;
430   try {    
431     params->getGraph()->computeOutputPatterns(1);
432   }
433   catch(Exception e) {
434     cerr << qPrintable(e.getMessage()) << endl;
435     compat = false;
436     if (e.getType() == IP_AP_NOTCOMPAT) {
437       FunctionalBlock* toBlock = (FunctionalBlock*)(e.getSource());
438       QString msg = tr("");
439       msg.append(toBlock->getName());
440       msg += " is not compatible with its input pattern.\nDo you want to launch automatic modification process to ensure the compatibility ?";
441       int ret = QMessageBox::question(this,tr("Building references library"),msg, QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Ok);
442       if (ret == QMessageBox::Ok) {
443         dispatcher->findGraphModifications(toBlock);
444       }
445     }
446   }
447 }
448
449 void MainWindow::slotGenerateVHDL() {
450   try {
451     params->getGraph()->generateVHDL(params->projectPath);
452   }
453   catch(Exception e) {
454     cerr << qPrintable(e.getMessage()) << endl;
455   }
456 }
457
458 void MainWindow::addTopGroup(GroupWidget *_topGroup) {
459   topGroup = _topGroup;
460   stackedWidget->addWidget(topGroup);
461   stackedWidget->setCurrentIndex(1);
462 }
463
464 void MainWindow::removeTopGroup() {
465   stackedWidget->removeWidget(topGroup);
466   topGroup->deleteLater();
467   stackedWidget->setCurrentIndex(0);
468 }
469
470 void MainWindow::closeEvent(QCloseEvent *event) {
471
472   if (params->isCurrentProject) {
473     slotCloseProject();
474     event->ignore();
475   }
476   else {
477     library->deleteLater();
478   }
479
480 }
481
482 void MainWindow::mousePressEvent(QMouseEvent *e) {
483
484   if (dispatcher->getCurrentGroup() != NULL) {
485     dispatcher->setCurrentGroupWidget(dispatcher->getCurrentGroup());
486   }
487   QMainWindow::mousePressEvent(e);
488 }
489
490 void MainWindow::focusInEvent(QFocusEvent *e) {
491 /*
492   if(params->currentWindow != this){
493     params->setCurrentWindow(this);
494     changeConnectionMode(false);
495   }
496   */
497 }