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"
9 #include "FunctionalBlock.h"
10 #include <QDomDocument>
11 #include <QDomElement>
14 #include "NewProjectDialog.h"
16 MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) {
18 versionMaj = VERSION_MAJ;
19 versionMin = VERSION_MIN;
23 params = new Parameters();
25 params->loadBlastConfiguration("blastconfig.xml");
27 // first load external sources
28 params->loadSources();
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();
38 params->loadReferencesFromLib();
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();
49 params->loadImplementationsFromLib();
52 catch(Exception err) {
53 cerr << qPrintable(err.getDefaultMessage()) << endl;
54 cerr << "Aborting ..." << endl;
58 cout << "all references and implementations are loaded" << endl;
60 params->createDelayBlock();
62 // create the menu, action, ...
63 dispatcher = new Dispatcher(params,this);
64 params->setDispatcher(dispatcher);
66 // creating block library
67 library = new BlockLibraryWidget(dispatcher,params);
68 params->isCurrentProject = false;
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);
79 setWindowTitle("blast - top group");
80 setFocusPolicy(Qt::StrongFocus);
89 MainWindow::~MainWindow() {}
91 void MainWindow::initialize() {
96 stackedWidget->setCurrentIndex(0);
97 enableProjectActions(true,PROJECT_NEW | PROJECT_OPEN, OP_RAZ);
98 enableAnalysisActions(false);
100 stackedWidget->setCurrentIndex(0);
105 void MainWindow::readSettings() {
107 settings.beginGroup("init");
108 checkNewVersion = settings.value("check_new_version").toString();
110 if (checkNewVersion.isEmpty()) {
111 checkNewVersion = "true";
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);
123 void MainWindow::writeSettings() {
125 settings.beginGroup("init");
126 settings.setValue("check_new_version",checkNewVersion);
130 void MainWindow::slotCheckNewVersion(QNetworkReply *reply) {
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;
139 cout << "dernière version : " << qPrintable(txt) << ", version actuelle = " << qPrintable(currentVer) << endl;
143 cout << "erreur = " << qPrintable(reply->errorString()) << endl;
145 reply->deleteLater();
148 void MainWindow::enableProjectActions(bool enbMenu, quint16 mask, quint8 op) {
150 projectMenu->setEnabled(true);
153 projectMenu->setEnabled(false);
157 projectMenuEnb = projectMenuEnb | mask;
159 else if (op == OP_REM) {
160 projectMenuEnb = (projectMenuEnb | mask) ^ mask;
162 else if (op == OP_RAZ) {
163 projectMenuEnb = mask;
167 if (projectMenuEnb & PROJECT_NEW) {
168 newProject->setEnabled(true);
171 newProject->setEnabled(false);
173 if (projectMenuEnb & PROJECT_OPEN) {
174 openProject->setEnabled(true);
177 openProject->setEnabled(false);
179 if (projectMenuEnb & PROJECT_SAVE) {
180 saveProject->setEnabled(true);
183 saveProject->setEnabled(false);
185 if (projectMenuEnb & PROJECT_SAVEAS) {
186 saveAsProject->setEnabled(true);
189 saveAsProject->setEnabled(false);
191 if (projectMenuEnb & PROJECT_CLOSE) {
192 closeProject->setEnabled(true);
195 closeProject->setEnabled(false);
197 if (projectMenuEnb & PROJECT_LIB) {
198 openLibrary->setEnabled(true);
201 openLibrary->setEnabled(false);
205 void MainWindow::enableAnalysisActions(bool enbMenu, quint16 mask, quint8 op) {
207 analysisMenu->setEnabled(true);
210 analysisMenu->setEnabled(false);
214 analysisMenuEnb = analysisMenuEnb | mask;
216 else if (op == OP_REM) {
217 analysisMenuEnb = (analysisMenuEnb | mask) ^ mask;
219 else if (op == OP_RAZ) {
220 analysisMenuEnb = mask;
224 if (analysisMenuEnb & ANALYSIS_ANALYZE) {
225 graphAnalysis->setEnabled(true);
228 graphAnalysis->setEnabled(false);
230 if (analysisMenuEnb & ANALYSIS_GENERATE) {
231 generateVHDL->setEnabled(true);
234 generateVHDL->setEnabled(false);
238 void MainWindow::createMenus(){
240 allMenuBar = menuBar();
242 projectMenu = allMenuBar->addMenu(tr("&Project"));
243 analysisMenu = allMenuBar->addMenu(tr("&Analysis"));
244 toolsMenu = allMenuBar->addMenu(tr("&Tools"));
246 projectMenu->addAction(newProject);
247 projectMenu->addAction(openProject);
248 projectMenu->addAction(saveProject);
249 projectMenu->addAction(saveAsProject);
250 projectMenu->addAction(closeProject);
251 projectMenu->addAction(openLibrary);
253 analysisMenu->addAction(graphAnalysis);
254 analysisMenu->addAction(generateVHDL);
256 toolsMenu->addAction(vhdlToXmlAct);
261 void MainWindow::createActions() {
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
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()));
310 void MainWindow::save(QString projectFile) {
311 params->save(projectFile);
314 void MainWindow::slotLoadProject(){
316 params->projectFile = QFileDialog::getOpenFileName(0, "select a project file", "save/",tr("sauvegardes (*.xml)"));
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);
329 msgBox.setText("Cannot open the project.");
330 msgBox.setStandardButtons(QMessageBox::Cancel);
331 msgBox.setDefaultButton(QMessageBox::Cancel);
339 void MainWindow::slotNewProject(){
341 NewProjectDialog* dialog = new NewProjectDialog(params);
342 int ret = dialog->exec();
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();
351 params->isCurrentProject = true;
355 bool MainWindow::slotCloseProject(){
357 bool doClose = false;
359 if(params->isCurrentProject) {
360 if (params->unsaveModif) {
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);
367 int ret = msgBox.exec();
370 case QMessageBox::Save :
374 case QMessageBox::Discard :
383 // removing the GroupWidget from stack
384 QWidget *widget = stackedWidget->widget(1);
385 stackedWidget->removeWidget(widget);
386 stackedWidget->setCurrentIndex(0);
388 dispatcher->closeCurrentProject();
390 params->isCurrentProject = false;
391 params->unsaveModif = false;
392 params->projectFile = QString();
401 void MainWindow::slotVHDLToXml() {
405 void MainWindow::slotSaveProject(){
406 if(params->projectFile != QString()){
407 save(params->projectFile);
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);
426 void MainWindow::slotOpenBlockLibrary() {
427 dispatcher->showBlocksLibrary();
431 void MainWindow::slotGraphAnalysis() {
434 params->getGraph()->computeOutputPatterns(1);
437 cerr << qPrintable(e.getMessage()) << endl;
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);
452 void MainWindow::slotGenerateVHDL() {
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;
459 if (! baseDir.exists("src")) {
460 baseDir.mkdir("src");
462 if (! baseDir.exists("testbench")) {
463 baseDir.mkdir("testbench");
465 if (! baseDir.exists("Makefile")) {
466 QFile make("/home/sdomas/Projet/Blast/code/blast/Makefile-isim");
467 QString dest = params->projectPath;
472 QString dest = params->projectPath;
475 params->getGraph()->generateVHDL(dest);
478 cerr << qPrintable(e.getMessage()) << endl;
482 void MainWindow::addTopGroup(GroupWidget *_topGroup) {
483 topGroup = _topGroup;
484 stackedWidget->addWidget(topGroup);
485 stackedWidget->setCurrentIndex(1);
488 void MainWindow::removeTopGroup() {
489 stackedWidget->removeWidget(topGroup);
490 topGroup->deleteLater();
491 stackedWidget->setCurrentIndex(0);
494 void MainWindow::closeEvent(QCloseEvent *event) {
496 if (params->isCurrentProject) {
501 library->deleteLater();
506 void MainWindow::mousePressEvent(QMouseEvent *e) {
508 if (dispatcher->getCurrentGroup() != NULL) {
509 dispatcher->setCurrentGroupWidget(dispatcher->getCurrentGroup());
511 QMainWindow::mousePressEvent(e);
514 void MainWindow::focusInEvent(QFocusEvent *e) {
516 if(params->currentWindow != this){
517 params->setCurrentWindow(this);
518 changeConnectionMode(false);