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

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