00001 #include "constants.h"
00002
00003 #include "mainwindow.h"
00004 #include "editor.h"
00005 #include "state.h"
00006 #include "transition.h"
00007 #include "ialgorithm.h"
00008 #include "igraphviz.h"
00009
00010 #include <QApplication>
00011 #include <QStatusBar>
00012 #include <QToolBar>
00013 #include <QAction>
00014 #include <QActionGroup>
00015 #include <QMenu>
00016 #include <QMenuBar>
00017 #include <QMessageBox>
00018 #include <QHBoxLayout>
00019 #include <QGraphicsScene>
00020 #include <QCloseEvent>
00021
00022
00023 #include <QLabel>
00024 #include <QLineEdit>
00025 #include <QPushButton>
00026 #include <QCheckBox>
00027 #include <QFileDialog>
00028 #include <QGridLayout>
00029
00030 #include <QtDebug>
00031 #include <QDesktopWidget>
00032
00033 #include <QRegExp>
00034 #include <QPluginLoader>
00035
00036 #include "stdio.h"
00037
00038 #if QT_VERSION < 0x040500
00039 # error "Minimal required Qt's version is 4.5.0!"
00040 #endif
00041
00042 MainWindow::MainWindow(const QString &fileName)
00043 {
00044
00045 const QString build_version = QT_VERSION_STR;
00046 const QString runtime_version = qVersion();
00047
00048 DBGLOG("\nQt build version=" << build_version <<
00049 "\nQt runtime version=" << runtime_version);
00050
00051 if (build_version != runtime_version)
00052 {
00053 RELLOG("Qt build version=" << build_version <<
00054 "\nQt runtime version=" << runtime_version);
00055 RELLOG("Qt build and runtime version are inconsitent, unexpected behavior can occure!\n"
00056 << "Please run program rather with same Qt version as which application is compiled again\n"
00057 << "or recompile it with Qt version which you are using.");
00058 }
00059
00060 setWindowTitle(QString("%1 - %2")
00061 .arg(PROGRAM_NAME)
00062 .arg(NEW_FILENAME));
00063 setWindowIcon(QIcon(":images/snaptogrid.xpm"));
00064
00065 editor = new Editor(this);
00066
00067 createStatusBar();
00068 createActions();
00069 createToolBars();
00070 createMenus();
00071
00072 editor->setAction((Editor::EAction) INIT_ACTION);
00073 actionChanged((Editor::EAction) INIT_ACTION);
00074
00075 connect(editor, SIGNAL(actionChanged(int)),
00076 this, SLOT(actionChanged(int)));
00077
00078 connect(editor, SIGNAL(canUndoChanged(bool)),
00079 editUndo, SLOT(setEnabled(bool)));
00080 connect(editor, SIGNAL(canRedoChanged(bool)),
00081 editRedo, SLOT(setEnabled(bool)));
00082 connect(editor, SIGNAL(showUndoStackAvailable(bool)),
00083 editShowUndoStack, SLOT(setEnabled(bool)));
00084
00085 connect(editor, SIGNAL(canNewFile(bool)),
00086 fileNew, SLOT(setEnabled(bool)));
00087 connect(editor, SIGNAL(canOpenFile(bool)),
00088 fileOpen, SLOT(setEnabled(bool)));
00089 connect(editor, SIGNAL(canSaveFile(bool)),
00090 fileSave, SLOT(setEnabled(bool)));
00091
00092 connect(editor, SIGNAL(itemsAvailable(bool)),
00093 this, SLOT(setItemsAvailable(bool)));
00094 connect(editor, SIGNAL(toolsAvailable(bool)),
00095 this, SLOT(setToolsAvailable(bool)));
00096 connect(editor, SIGNAL(utilsAvailable(bool)),
00097 this, SLOT(setUtilsAvailable(bool)));
00098
00099 connect(editor, SIGNAL(canZoomIn(bool)),
00100 zoomIn, SLOT(setEnabled(bool)));
00101 connect(editor, SIGNAL(canZoomOut(bool)),
00102 zoomOut, SLOT(setEnabled(bool)));
00103
00104 connect(editor, SIGNAL(showChanged(bool,bool)),
00105 this, SLOT(actualizeChecking(bool,bool)));
00106
00107 connect(editor, SIGNAL(isChanged(bool)),
00108 fileSave, SLOT(setEnabled(bool)));
00109
00110 setCentralWidget(editor);
00111
00112 QDesktopWidget desktopWidget;
00113 QRect screenResolution = desktopWidget.screenGeometry();
00114 DBGLOG("Screen resolution is " << screenResolution.width() << "x" << screenResolution.height());
00115
00116
00117 #ifdef TESTING_USE_SMALLER_WINDOW
00118 setGeometry(screenResolution.width()-640,100,600, 600);
00119 #else
00120 if(screenResolution.width() > 400 && screenResolution.height() > 200)
00121 setGeometry(200, 100, screenResolution.width()-400, screenResolution.height()-200);
00122 #endif
00123
00124 loadPlugins();
00125
00126 if (!fileName.isEmpty())
00127 editor->openFile(fileName);
00128 }
00129
00130 void MainWindow::loadPlugins()
00131 {
00132
00133 foreach (QObject *plugin, QPluginLoader::staticInstances())
00134 {
00135 IAlgorithmHolder *algHolder = qobject_cast<IAlgorithmHolder*>(plugin);
00136 if (algHolder)
00137 {
00138 processAlgorithmsPlugin(algHolder);
00139 }
00140 }
00141
00142
00143 QDir pluginsDir = QDir(qApp->applicationDirPath());
00144 pluginsDir.cd("plugins");
00145 DBGLOG("Libraries in plugins directory: " << pluginsDir.entryList(QDir::Files));
00146 foreach (QString fileName, pluginsDir.entryList(QDir::Files))
00147 {
00148 DBGLOG("Trying to load: " << pluginsDir.absoluteFilePath(fileName));
00149 QPluginLoader loader(pluginsDir.absoluteFilePath(fileName));
00150 QObject *plugin = loader.instance();
00151 if (plugin)
00152 {
00153 IAlgorithmHolder *algHolder = qobject_cast<IAlgorithmHolder*>(plugin);
00154 if (algHolder)
00155 {
00156 processAlgorithmsPlugin(algHolder);
00157 continue;
00158 }
00159 IGraphViz *graphVizWrapper = qobject_cast<IGraphViz*>(plugin);
00160 if (graphVizWrapper)
00161 {
00162 processGraphVizPlugin(graphVizWrapper);
00163 continue;
00164 }
00165 }
00166 else
00167 {
00168 DBGLOG(DBGPAR(loader.errorString()));
00169 }
00170 }
00171 }
00172
00173 void MainWindow::processAlgorithmsPlugin(IAlgorithmHolder *algHolder)
00174 {
00175 QStringList supportedVersions;
00176 supportedVersions << PROGRAM_VERSION;
00177
00178 const QString version = algHolder->getVersion();
00179 if (supportedVersions.contains(version))
00180 {
00181 DBGLOG_AI(DBGPAR(algHolder->getPluginName()));
00182
00183 QMenu *menu = algorithmMenu;
00184 static bool s_DynamicPlugins = false;
00185 if (algHolder->getPluginName() != "Basic automata algorthms")
00186 {
00187 if (!s_DynamicPlugins)
00188 {
00189 s_DynamicPlugins = true;
00190 algorithmMenu->addSeparator();
00191 }
00192 menu = new QMenu(algHolder->getPluginName(),algorithmMenu);
00193 algorithmMenu->addMenu(menu);
00194 }
00195
00196 foreach(QSharedPointer<IAlgorithm> alg, algHolder->getAlgorithms())
00197 {
00198 QAction *action = menu->addAction(alg->getName(), editor, SLOT(runAlgorithm()));
00199 action->setData(editor->addAlgorithm(alg));
00200 }
00201
00202 DBGLOG("Plugin" << algHolder->getPluginName() << "loaded successfully.");
00203 }
00204 else
00205 {
00206 RELLOG("Plugin " << algHolder->getPluginName() <<
00207 " has version" << version << "which isn't supported!");
00208 }
00209 }
00210
00211 void MainWindow::processGraphVizPlugin(IGraphViz *graphVizWrapper)
00212 {
00213 QStringList supportedVersions;
00214 supportedVersions << PROGRAM_VERSION;
00215
00216 const QString version = graphVizWrapper->getVersion();
00217 if (supportedVersions.contains(version))
00218 {
00219 DBGLOG("GraphVizWrapper plugin found.");
00220 editor->addGraphVizDrawAlgorithm(graphVizWrapper);
00221 }
00222 else
00223 {
00224 RELLOG("Found unsupported GraphVizWrapper plugin (version " << version << ")!");
00225 }
00226 }
00227
00228 void MainWindow::createStatusBar()
00229 {
00230 statusBar()->showMessage(tr("Ready ..."),5000);
00231 }
00232
00233 void MainWindow::setStatusBar(const QString& s)
00234 {
00235 statusBar()->showMessage(s);
00236 }
00237
00238 void MainWindow::setStatusBar(const QString& s, int ms)
00239 {
00240 statusBar()->showMessage(s,ms);
00241 }
00242
00243 void MainWindow::createActions()
00244 {
00245 Q_ASSERT(editor && "has to be already created because is used here in connect!");
00246
00247
00248 fileNew = new QAction(QIcon(":/images/filenew.png"), tr("&New file"), this);
00249 fileNew->setShortcut(tr("Ctrl+N"));
00250 fileNew->setStatusTip(tr("Create a new file"));
00251 connect(fileNew,SIGNAL(triggered()),this,SLOT(newFile()));
00252
00253 fileOpen = new QAction(QIcon(":/images/fileopen.png"), tr("&Open file"), this);
00254 fileOpen->setShortcut(tr("Ctrl+O"));
00255 fileOpen->setStatusTip(tr("Open an existing file"));
00256 connect(fileOpen, SIGNAL(triggered()), this, SLOT(openFile()));
00257
00258 fileSave = new QAction(QIcon(":/images/filesave.png"), tr("&Save"), this);
00259 fileSave->setShortcut(tr("Ctrl+S"));
00260 fileSave->setStatusTip(tr("Save changes in current file"));
00261 connect(fileSave, SIGNAL(triggered()), this, SLOT(save()));
00262
00263 fileSaveAs = new QAction(QIcon(":/images/filesaveas.png"), tr("&Save As ..."), this);
00264 fileSaveAs->setShortcut(tr("Ctrl+Shift+S"));
00265 fileSaveAs->setStatusTip(tr("Save current file as ..."));
00266 connect(fileSaveAs, SIGNAL(triggered()), this, SLOT(saveAs()));
00267
00268 fileExport = new QAction(QIcon(":/images/fileexport.png"), tr("&Export"), this);
00269 fileExport->setShortcut(tr("Ctrl+E"));
00270 fileExport->setStatusTip(tr("Export to ..."));
00271 connect(fileExport, SIGNAL(triggered()), this, SLOT(exportTo()));
00272
00273 fileQuit = new QAction(QIcon(":/images/editdelete.png"), tr("&Quit"), this);
00274 fileQuit->setShortcut(tr("Ctrl+Q"));
00275 fileQuit->setStatusTip(tr("Quit application"));
00276 connect(fileQuit, SIGNAL(triggered()), this, SLOT(close()));
00277
00278
00279 editUndo = new QAction(QIcon(":/images/undo.png"), tr("&Undo"), this);
00280 editUndo->setShortcut(tr("Ctrl+Z"));
00281 editUndo->setStatusTip(tr("Undo prevousious action"));
00282 editUndo->setEnabled(false);
00283 connect(editUndo, SIGNAL(triggered()), editor, SLOT(undo()));
00284
00285 editRedo = new QAction(QIcon(":/images/redo.png"), tr("&Redo"), this);
00286 editRedo->setShortcut(tr("Ctrl+Y"));
00287 editRedo->setStatusTip(tr("Redo prevousious action"));
00288 editRedo->setEnabled(false);
00289 connect(editRedo, SIGNAL(triggered()), editor, SLOT(redo()));
00290
00291 editCopy = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
00292 editCopy->setShortcut(tr("Ctrl+C"));
00293 editCopy->setStatusTip(tr("Copy selection"));
00294 connect(editCopy, SIGNAL(triggered()), this, SLOT(copy()));
00295
00296 editPaste = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
00297 editPaste->setShortcut(tr("Ctrl+V"));
00298 editPaste->setStatusTip(tr("Paste items from clipboard"));
00299 connect(editPaste, SIGNAL(triggered()), this, SLOT(paste()));
00300
00301 editCut = new QAction(QIcon(":/images/cut.png"), tr("&Cut"), this);
00302 editCut->setShortcut(tr("Ctrl+X"));
00303 editCut->setStatusTip(tr("Remove selected items and store it to clipboard"));
00304 connect(editCut, SIGNAL(triggered()), this, SLOT(cut()));
00305
00306 editRemove = new QAction(QIcon(":/images/delete.png"), tr("&Remove"), this);
00307 editRemove->setShortcut(tr("Delete"));
00308 editRemove->setStatusTip(tr("Remove selected items"));
00309 connect(editRemove, SIGNAL(triggered()), this, SLOT(remove()));
00310
00311 zoomIn = new QAction(QIcon(":/images/zoomin.png"), tr("Zoom&In"), this);
00312 zoomIn->setShortcut(tr("Ctrl++"));
00313 zoomIn->setStatusTip(tr("Zoom in the scene"));
00314 connect(zoomIn, SIGNAL(triggered()), editor, SLOT(zoomIn()));
00315
00316 zoomOut = new QAction(QIcon(":/images/zoomout.png"), tr("Zoom&Out"), this);
00317 zoomOut->setShortcut(tr("Ctrl+-"));
00318 zoomOut->setStatusTip(tr("Zoom out the scene"));
00319 connect(zoomOut, SIGNAL(triggered()), editor, SLOT(zoomOut()));
00320
00321 resetZoom = new QAction(QIcon(":/images/resetzoom.png"), tr("&Reset zoom"), this);
00322 resetZoom->setShortcut(tr("Ctrl+0"));
00323 resetZoom->setStatusTip(tr("Reset scene zoom to original state."));
00324 connect(resetZoom, SIGNAL(triggered()), editor, SLOT(resetZoom()));
00325
00326 editShowUndoStack = new QAction(tr("Show undo stack"), this);
00327 editShowUndoStack->setStatusTip(tr("Show/Hide undo stack"));
00328 editShowUndoStack->setCheckable(true);
00329 connect(editShowUndoStack, SIGNAL(triggered(bool)), editor, SLOT(showUndoView(bool)));
00330 connect(editor, SIGNAL(undoViewClosed()), this, SLOT(undoViewClosed()));
00331
00332 editGridRect = new QAction(QIcon(":/images/grid.xpm"), tr("Set grid rect"), this);
00333 editGridRect->setStatusTip(tr("Change treshold by setting grid rectangle"));
00334 connect(editGridRect, SIGNAL(triggered()), editor, SLOT(showGridRectDialog()));
00335
00336 editStateParams = new QAction(QIcon(":/images/state.xpm"), tr("Set state style"), this);
00337 editStateParams->setStatusTip(tr("Change state style parameters"));
00338 connect(editStateParams, SIGNAL(triggered()), editor, SLOT(editStateStyleParams()));
00339
00340 editTransitionParams = new QAction(QIcon(":/images/transition.xpm"), tr("Set transition style"), this);
00341 editTransitionParams->setStatusTip(tr("Change transition style parameters"));
00342 connect(editTransitionParams, SIGNAL(triggered()), editor, SLOT(editTransitionStyleParams()));
00343
00344
00345
00346 itemsSelection = new QAction(QIcon(":/images/pointer.png"), tr("&Selection"), this);
00347 itemsSelection->setShortcut(tr("Ctrl+M"));
00348 itemsSelection->setStatusTip(tr("Universal operations: double click - insert state, middle click - insert transition"));
00349 connect(itemsSelection, SIGNAL(triggered()), this, SLOT(setSelection()));
00350 itemsSelection->setCheckable(true);
00351
00352 itemsState = new QAction(QIcon(":/images/state.xpm"), tr("Insert &state"), this);
00353 itemsState->setShortcut(tr("Ctrl+I"));
00354 itemsState->setStatusTip(tr("Insert new state"));
00355 connect(itemsState, SIGNAL(triggered()), this, SLOT(setState()));
00356 itemsState->setCheckable(true);
00357
00358 itemsTransition = new QAction(QIcon(":/images/transition.xpm"), tr("Insert &transition"), this);
00359 itemsTransition->setShortcut(tr("Ctrl+T"));
00360 itemsTransition->setStatusTip(tr("Insert new transition"));
00361 connect(itemsTransition, SIGNAL(triggered()), this, SLOT(setTransition()));
00362 itemsTransition->setCheckable(true);
00363
00364
00365 toolsSnapToGrid = new QAction(QIcon(":/images/snaptogrid.xpm"), tr("&Snap to grid"), this);
00366 toolsSnapToGrid->setShortcut(tr("Ctrl+G"));
00367 toolsSnapToGrid->setStatusTip(tr("Snap state to grid"));
00368 connect(toolsSnapToGrid, SIGNAL(triggered()), this, SLOT(snapToGrid()));
00369 toolsSnapToGrid->setCheckable(true);
00370 toolsSnapToGrid->setChecked(SNAP_TO_GRID);
00371
00372 toolsAlignStatesToGrid = new QAction(QIcon(":/images/aligntogrid.xpm"), tr("&Align states"), this);
00373 toolsAlignStatesToGrid->setShortcut(tr("Ctrl+A"));
00374 toolsAlignStatesToGrid->setStatusTip(tr("Align all states to grid"));
00375 connect(toolsAlignStatesToGrid, SIGNAL(triggered()), this, SLOT(alignToGrid()));
00376
00377 toolsExpandGrid = new QAction(QIcon(":/images/grid_expand.xpm"), tr("&Expand/Shrink grid"), this);
00378 toolsExpandGrid->setStatusTip("Expands/shrinks grid automatically according to items on scene.");
00379 connect(toolsExpandGrid, SIGNAL(triggered()), editor, SLOT(expandGrid()));
00380
00381
00382 showGrid = new QAction(QIcon(":/images/grid.xpm"), tr("Show &grid"), this);
00383 showGrid->setShortcut(tr("Ctrl+Shift+G"));
00384 showGrid->setStatusTip(tr("Show grid"));
00385 connect(showGrid, SIGNAL(triggered(bool)), editor, SLOT(slotShowGrid(bool)));
00386 showGrid->setCheckable(true);
00387 showGrid->setChecked(SHOW_GRID);
00388
00389 showFrame = new QAction(QIcon(":/images/frame.xpm"), tr("Show &frame"), this);
00390 showFrame->setShortcut(tr("Ctrl+Shift+F"));
00391 showFrame->setStatusTip(tr("Show frame"));
00392 connect(showFrame, SIGNAL(triggered(bool)), editor, SLOT(slotShowFrame(bool)));
00393 showFrame->setCheckable(true);
00394 showFrame->setChecked(SHOW_FRAME);
00395
00396 showAntialias = new QAction(QIcon(":/images/antialiasing.png"), tr("Antialiasing On/Off"), this);
00397 showAntialias->setStatusTip(tr("Turn On/Off antialiasing render method"));
00398 showAntialias->setCheckable(true);
00399 showAntialias->setChecked(INIT_ANTIALIASING);
00400 connect(showAntialias, SIGNAL(triggered()), editor, SLOT(switchAntialiasing()));
00401
00402
00403 helpAbout = new QAction(tr("&About"), this);
00404 helpAbout->setStatusTip(tr("About ..."));
00405 connect(helpAbout, SIGNAL(triggered()), this, SLOT(about()));
00406
00407 helpAboutQt = new QAction(tr("About &Qt"),this);
00408 helpAboutQt->setStatusTip(tr("About Qt ..."));
00409 connect(helpAboutQt, SIGNAL(triggered()), this, SLOT(aboutQt()));
00410
00411 QActionGroup *ag = new QActionGroup(this);
00412 ag->addAction(itemsSelection);
00413 ag->addAction(itemsState);
00414 ag->addAction(itemsTransition);
00415 ag->setExclusive(true);
00416
00417
00418 extraLaTeXTable = new QAction(QIcon(":/images/table.png"), tr("&LaTeX table"), this);
00419 extraLaTeXTable->setStatusTip(tr("Get LaTeX table"));
00420 connect(extraLaTeXTable, SIGNAL(triggered()), editor, SLOT(createLaTeXTable()));
00421
00422 extraGeneration = new QAction(QIcon(":/images/generating.png"), tr("Show &geration dialog"), this);
00423 extraGeneration->setStatusTip(tr("Generate graph of searching by selected algorithm"));
00424 connect(extraGeneration, SIGNAL(triggered()), editor, SLOT(generateGraph()));
00425
00426 extraSimulation = new QAction(QIcon(":/images/simulating.png"), tr("DKA/NKA work &simulation"), this);
00427 extraSimulation->setStatusTip(tr("Simulation of finite automaton's work"));
00428 connect(extraSimulation, SIGNAL(triggered()), editor, SLOT(simulateAutomatonWork()));
00429 }
00430
00431 void MainWindow::createMenus()
00432 {
00433 fileMenu = menuBar()->addMenu(tr("&File"));
00434 fileMenu->addAction(fileNew);
00435 fileMenu->addAction(fileOpen);
00436 fileMenu->addAction(fileSave);
00437 fileMenu->addAction(fileSaveAs);
00438 fileMenu->addAction(fileExport);
00439 fileMenu->addSeparator();
00440 fileMenu->addAction(fileQuit);
00441
00442 editMenu = menuBar()->addMenu(tr("&Edit"));
00443 editMenu->addAction(editUndo);
00444 editMenu->addAction(editRedo);
00445 editMenu->addAction(editShowUndoStack);
00446 editMenu->addSeparator();
00447 editMenu->addAction(editCut);
00448 editMenu->addAction(editCopy);
00449 editMenu->addAction(editPaste);
00450 editMenu->addAction(editRemove);
00451 editMenu->addSeparator();
00452 editMenu->addAction(zoomIn);
00453 editMenu->addAction(zoomOut);
00454 editMenu->addAction(resetZoom);
00455 editMenu->addSeparator();
00456 editMenu->addAction(editGridRect);
00457 editMenu->addAction(editStateParams);
00458 editMenu->addAction(editTransitionParams);
00459
00460 connect(editMenu, SIGNAL(aboutToShow()), this, SLOT(updateEditMenu()));
00461 connect(editMenu, SIGNAL(aboutToHide()), this, SLOT(enableEditMenu()));
00462
00463 itemsMenu = menuBar()->addMenu(tr("&Items"));
00464 itemsMenu->addAction(itemsSelection);
00465 itemsMenu->addAction(itemsState);
00466 itemsMenu->addAction(itemsTransition);
00467
00468 toolsMenu = menuBar()->addMenu(tr("&Tools"));
00469 toolsMenu->addAction(toolsSnapToGrid);
00470 toolsMenu->addAction(toolsAlignStatesToGrid);
00471 toolsMenu->addAction(toolsExpandGrid);
00472
00473 showMenu = menuBar()->addMenu(tr("&Show"));
00474 showMenu->addAction(showGrid);
00475 showMenu->addAction(showFrame);
00476 showMenu->addSeparator();
00477 showMenu->addAction(showAntialias);
00478
00479 extraMenu = menuBar()->addMenu(tr("&Utility"));
00480 extraMenu->addAction(extraGeneration);
00481 extraMenu->addAction(extraLaTeXTable);
00482 extraMenu->addAction(extraSimulation);
00483 extraMenu->addSeparator();
00484 algorithmMenu = extraMenu->addMenu(tr("&Algorithms..."));
00485
00486 menuBar()->addSeparator();
00487
00488 helpMenu = menuBar()->addMenu(tr("&Help"));
00489 helpMenu->addAction(helpAbout);
00490 helpMenu->addAction(helpAboutQt);
00491 }
00492
00493 void MainWindow::createToolBars(){
00494 fileToolBar = addToolBar(tr("File"));
00495 fileToolBar->addAction(fileNew);
00496 fileToolBar->addAction(fileOpen);
00497 fileToolBar->addAction(fileSave);
00498
00499 fileToolBar->addAction(fileExport);
00500
00501 editToolBar = addToolBar(tr("Edit"));
00502 editToolBar->addAction(editUndo);
00503 editToolBar->addAction(editRedo);
00504
00505 zoomToolBar = addToolBar(tr("Zoom"));
00506 zoomToolBar->addAction(zoomIn);
00507 zoomToolBar->addAction(zoomOut);
00508 zoomToolBar->addAction(resetZoom);
00509
00510 itemsToolBar = addToolBar(tr("Items"));
00511 itemsToolBar->addAction(itemsSelection);
00512 itemsToolBar->addAction(itemsState);
00513 itemsToolBar->addAction(itemsTransition);
00514
00515 toolsToolBar = addToolBar(tr("Tools"));
00516 toolsToolBar->addAction(toolsSnapToGrid);
00517 toolsToolBar->addAction(toolsAlignStatesToGrid);
00518 toolsToolBar->addAction(toolsExpandGrid);
00519
00520 showToolBar = addToolBar(tr("Show"));
00521 showToolBar->addAction(showGrid);
00522 showToolBar->addAction(showFrame);
00523 showToolBar->addSeparator();
00524 showToolBar->addAction(showAntialias);
00525
00526 extraToolBar = addToolBar(tr("Extra"));
00527 extraToolBar->addAction(extraGeneration);
00528 extraToolBar->addAction(extraLaTeXTable);
00529 extraToolBar->addAction(extraSimulation);
00530 }
00531
00532
00533
00534 void MainWindow::newFile()
00535 {
00536 if (editor->isChanged())
00537 {
00538 int ret = QMessageBox::question(this,
00539 tr("New file"),
00540 tr("File was modified?\nDo you want to save your changes?"),
00541 tr("&Save"), tr("&Discard"), tr("&Cancel"), 0);
00542 if (ret == 0)
00543 {
00544 if (!save()) return;
00545 }
00546 else if (ret == 2)
00547 {
00548 return;
00549 }
00550 }
00551
00552 editor->newFile();
00553 }
00554
00555 void MainWindow::openFile()
00556 {
00557 if (editor->isChanged())
00558 {
00559 int ret = QMessageBox::question(this,
00560 tr("Open file"),
00561 tr("File was modified?\nDo you want to save your changes?"),
00562 tr("&Save"), tr("&Discard"), tr("&Cancel"), 0);
00563
00564 if (ret == 0)
00565 {
00566 if (!save()) return;
00567 }
00568 else if (ret == 2)
00569 {
00570 return;
00571 }
00572 }
00573
00574 QString dir = editor->getFileName();
00575 int idx = dir.lastIndexOf(QRegExp("[/\\\\]"));
00576 if (idx != -1)
00577 dir = dir.left(idx);
00578 else
00579 dir = ".";
00580 #if defined(TESTING) && defined(_WINDOWS)
00581 if (editor->getFileName() == NEW_FILENAME)
00582 {
00583 QDir curDir(dir);
00584 curDir.cdUp();
00585 DBGLOG(curDir.dirName());
00586 if (curDir.cd("tests"))
00587 {
00588 dir = curDir.path();
00589 }
00590 }
00591 #endif
00592 DBGLOG(DBGPAR(dir));
00593 QString fn = QFileDialog::getOpenFileName(0,"Open file",dir,
00594 "VauCanSon-G and LaTeX (*.vcg *.tex);;All files (*.*)");
00595
00596 if (fn != QString::null)
00597 {
00598 editor->openFile(fn);
00599 }
00600 }
00601
00602 bool MainWindow::save()
00603 {
00604 QString fn = editor->getFileName();
00605 if (editor->isSaved() && fn != "")
00606 {
00607 if (!editor->isChanged())
00608 {
00609 DBGLOG("saving isn't necessary");
00610 return true;
00611 }
00612 editor->exportToVaucanson(fn, editor->isAddition());
00613 return true;
00614 }
00615 else return saveAs();
00616 }
00617
00618 void MainWindow::addSuffix(QString &fn, Editor::Format f)
00619 {
00620 if (fn.lastIndexOf(".") != -1) {
00621 return;
00622 }
00623
00624 switch (f) {
00625 case Editor::vcg : fn.append(".vcg"); break;
00626 case Editor::tex : fn.append(".tex"); break;
00627 case Editor::gml : fn.append(".gml"); break;
00628 case Editor::eps : fn.append(".eps"); break;
00629 case Editor::svg : fn.append(".svg"); break;
00630 case Editor::bmp : fn.append(".bmp"); break;
00631 case Editor::png : fn.append(".png"); break;
00632 case Editor::xpm : fn.append(".xpm"); break;
00633 default : break;
00634 }
00635 }
00636
00637 bool MainWindow::saveAs(){
00638 QString fn;
00639 QString filter;
00640
00641 QStringList formats;
00642 if (DEFAULT_SUFFIX_VCG)
00643 {
00644 filter = tr("VauCanSon-G file (*.vcg)");
00645 formats << filter
00646 << tr("LaTeX file (*.tex)");
00647 }
00648 else
00649 {
00650 filter = tr("LaTeX file (*.tex)");
00651 formats << filter
00652 << tr("VauCanSon-G file (*.vcg)");
00653 }
00654 formats << tr("LaTeX file w/o head and tail (*.tex)")
00655 << tr("Other (*.*)");
00656
00657 fn = editor->getFileName();
00658
00659 #if defined(WIN32) || QT_VERSION > 0x040501 // due to bug on Ubuntu system - filter wasn't functional there
00660 fn = QFileDialog::getSaveFileName(this, "Save file", fn,
00661 formats.join(";;"), &filter);
00662 #else
00663 QFileDialog dialog(this, tr("Save as ..."), fn);
00664 dialog.setAcceptMode(QFileDialog::AcceptSave);
00665 dialog.setNameFilters(formats);
00666
00667 if (dialog.exec() != QDialog::Accepted) return false;
00668
00669 filter = dialog.selectedNameFilter();
00670 fn = dialog.selectedFiles()[0];
00671 #endif
00672
00673 DBGLOG(DBGPAR(fn) << DBGPAR(filter));
00674
00675 if (fn != "")
00676 {
00677 QDir dir(fn.left(fn.lastIndexOf(QRegExp("[/\\\\]"))));
00678 if (!dir.exists())
00679 {
00680
00681 QMessageBox::critical(this, PROGRAM_NAME,
00682 "Selected directory doesn't exist!\n"
00683 "Please select existing directory.", "OK");
00684 return false;
00685 }
00686
00687 if (filter == "LaTeX file (*.tex)")
00688 {
00689 addSuffix(fn, Editor::tex);
00690 editor->exportToVaucanson(fn, true);
00691 }
00692 else
00693 {
00694 if (filter == "LaTeX file w/o head and tail (*.tex)")
00695 addSuffix(fn, Editor::tex);
00696 else if (filter == "VauCanSon-G file (*.vcg)")
00697 addSuffix(fn, Editor::vcg);
00698
00699 editor->exportToVaucanson(fn, false);
00700 }
00701 editor->setFileName(fn);
00702 return true;
00703 }
00704 return false;
00705 }
00706
00707 void MainWindow::exportTo()
00708 {
00709 QString fn;
00710 QString filter = tr("Encapsulated PostScript (*.eps)");
00711 Editor::Format f;
00712 QStringList formats;
00713
00714 formats << filter
00715 #ifndef DONT_USE_SVG_MODULE
00716 << tr("SVG+XML (*.svg)")
00717 #endif
00718 << tr("GraphML files (*.graphml *.gml)")
00719 << tr("Images PNG(*.png)")
00720 << tr("Images BMP(*.bmp)")
00721 << tr("Images XPM(*.xpm)");
00722
00723 #if defined(WIN32) || QT_VERSION > 0x040501 // due to bug on Ubuntu system
00724 fn = QFileDialog::getSaveFileName(this, "Export to ...", editor->getFileName(),
00725 formats.join(";;"),
00726 &filter);
00727 #else
00728 QFileDialog dialog(this, tr("Export to ..."),editor->getFileName());
00729 dialog.setAcceptMode(QFileDialog::AcceptSave);
00730 dialog.setNameFilters(formats);
00731
00732 if (dialog.exec() != QDialog::Accepted) return;
00733
00734 filter = dialog.selectedNameFilter();
00735 fn = dialog.selectedFiles()[0];
00736 #endif
00737
00738 DBGLOG(fn << filter);
00739
00740 if (fn != ""){
00741 QDir dir(fn.left(fn.lastIndexOf('/')));
00742 if (!dir.exists()){
00743
00744 QMessageBox::critical(this, PROGRAM_NAME,
00745 "Selected directory doesn't exist!\n"
00746 "Please select existing directory.", "OK");
00747 return;
00748 }
00749
00750
00751 if (filter == "Encapsulated PostScript (*.eps)"){
00752 addSuffix(fn, Editor::eps);
00753 editor->exportToEPS(fn);
00754 }
00755 #ifndef DONT_USE_SVG_MODULE
00756 else if(filter == "SVG+XML (*.svg)"){
00757 addSuffix(fn, Editor::svg);
00758 editor->exportToSVG(fn);
00759 }
00760 #endif
00761 else if (filter == "GraphML files (*.graphml *.gml)"){
00762 addSuffix(fn, Editor::gml);
00763 editor->exportToGraphML(fn);
00764 }
00765 else if (filter == "Images PNG(*.png)"){
00766 f = Editor::png;
00767 addSuffix(fn,f);
00768 editor->exportToPixmap(fn, f);
00769 }
00770 else if (filter == "Images BMP(*.bmp)"){
00771 f = Editor::bmp;
00772 addSuffix(fn,f);
00773 editor->exportToPixmap(fn, f);
00774 }
00775 else if (filter == "Images XPM(*.xpm)"){
00776 f = Editor::xpm;
00777 addSuffix(fn,f);
00778 editor->exportToPixmap(fn,f);
00779 }
00780 else{
00781 RELLOG("No filter selected, file was not saved!");
00782 }
00783 }
00784 }
00785
00786 void MainWindow::closeEvent(QCloseEvent *event){
00787 if (!editor->isChanged()) {
00788 event->accept();
00789 return;
00790 }
00791 int ret = QMessageBox::question(this,
00792 tr("Quit"),
00793 tr("File was modified?\nDo you want to save your changes?"),
00794 tr("&Save"), tr("&Discard"), tr("&Cancel"), 0);
00795
00796 DBGLOG(DBGPAR(ret));
00797 if (ret == 2) {
00798 event->ignore();
00799 }
00800 else if (ret == 1){
00801 event->accept();
00802 }
00803 else {
00804 if (save())
00805 event->accept();
00806 else
00807 event->ignore();
00808 }
00809 }
00810
00811 void MainWindow::undoViewClosed()
00812 {
00813 editShowUndoStack->setChecked(false);
00814 }
00815
00816 void MainWindow::updateEditMenu()
00817 {
00818 editCopy->setEnabled(editor->isSomethingSelected());
00819 editPaste->setEnabled(editor->isPastePossible());
00820 editCut->setEnabled(editor->isSomethingSelected());
00821 editRemove->setEnabled(editor->isSomethingSelected());
00822 }
00823
00824 void MainWindow::enableEditMenu()
00825 {
00826 editCopy->setEnabled(true);
00827 editPaste->setEnabled(true);
00828 editCut->setEnabled(true);
00829 editRemove->setEnabled(true);
00830 }
00831
00832 void MainWindow::copy()
00833 {
00834 if (editor->isSomethingSelected())
00835 {
00836 editor->copySelection();
00837 }
00838 }
00839
00840 void MainWindow::paste()
00841 {
00842 if (editor->isPastePossible())
00843 {
00844 editor->paste();
00845 }
00846 }
00847
00848 void MainWindow::cut()
00849 {
00850 if (editor->isSomethingSelected())
00851 {
00852 editor->cutSelection();
00853 }
00854 }
00855
00856 void MainWindow::remove()
00857 {
00858 if (editor->isSomethingSelected())
00859 {
00860 editor->removeSelection();
00861 }
00862 }
00863
00864 void MainWindow::setSelection()
00865 {
00866 statusBar()->showMessage("Selection tool");
00867 editor->setAction(Editor::eSelection);
00868 }
00869
00870 void MainWindow::setState()
00871 {
00872 statusBar()->showMessage("Insert state selected");
00873 editor->setAction(Editor::eInsertState);
00874 }
00875
00876 void MainWindow::setTransition()
00877 {
00878 statusBar()->showMessage("Insert transition selected, 2000");
00879 editor->setAction(Editor::eInsertTransition);
00880 statusBar()->showMessage("Select first state");
00881 }
00882
00883 void MainWindow::snapToGrid()
00884 {
00885 editor->slotSnapToGrid();
00886 }
00887
00888 void MainWindow::alignToGrid()
00889 {
00890 editor->slotAlignToGrid();
00891 }
00892
00893 void MainWindow::about()
00894 {
00895 QMessageBox::about(this, PROGRAM_NAME,
00896 "Automata editor version 2, Copyright (C) 2008 Milan Kriz<br>" \
00897 "(ported to Qt4 and expanded from version 1 by Lukas Stanek)<br>"\
00898 "This editor comes with ABSOLUTELY NO WARRANTY; for details<br>" \
00899 "see GPLv2. This is free software, and you are welcome<br>" \
00900 "to redistribute it under certain conditions; see GPLv2<br>" \
00901 "for details.<br><br>" \
00902 "<b>For more information about Vaucanson-G visit</b><br>" \
00903 "<a href='http://www-igm.univ-mlv.fr/~lombardy/Vaucanson-G/'>http://www-igm.univ-mlv.fr/~lombardy/Vaucanson-G/</a><br><br>" \
00904 "For GNU General Public License see<br>" \
00905 "<a href='http://www.gnu.org/licenses/gpl.html'>http://www.gnu.org/licenses/gpl.html</a><br><br>" \
00906 "For GraphViz (used in drawing plugin) Common Public License see<br>" \
00907 "<a href='http://www.graphviz.org/License.php'>http://www.graphviz.org/License.php</a>"
00908 );
00909 }
00910
00911 void MainWindow::aboutQt()
00912 {
00913 QMessageBox::aboutQt(this, PROGRAM_NAME);
00914 }
00915
00916 void MainWindow::actualizeChecking(bool sg, bool sf)
00917 {
00918 showGrid->setChecked(sg);
00919 showFrame->setChecked(sf);
00920 }
00921
00922 void MainWindow::actionChanged(int action)
00923 {
00924 switch (action)
00925 {
00926 case Editor::eSelection:
00927 itemsSelection->setChecked(true);
00928 break;
00929 case Editor::eInsertState:
00930 itemsSelection->setChecked(true);
00931 break;
00932 case Editor::eInsertTransition:
00933 itemsSelection->setChecked(true);
00934 break;
00935 default:;
00936 }
00937 }
00938
00939 void MainWindow::setItemsAvailable(bool available)
00940 {
00941 itemsMenu->setEnabled(available);
00942
00943
00944 itemsSelection->setEnabled(available);
00945 itemsState->setEnabled(available);
00946 itemsTransition->setEnabled(available);
00947 }
00948
00949 void MainWindow::setToolsAvailable(bool available)
00950 {
00951 toolsMenu->setEnabled(available);
00952
00953 toolsAlignStatesToGrid->setEnabled(available);
00954 toolsSnapToGrid->setEnabled(available);
00955 }
00956
00957 void MainWindow::setUtilsAvailable(bool available)
00958 {
00959 extraGeneration->setEnabled(available);
00960 extraSimulation->setEnabled(available);
00961
00962 algorithmMenu->setEnabled(available);
00963 }
00964
00965
00966
00967
00968
00969
00970
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085
01086
01087
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137