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

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