]> Shamusworld >> Repos - architektonas/blobdiff - src/applicationwindow.cpp
Added Parallel tool + command processing.
[architektonas] / src / applicationwindow.cpp
index b80130e8989cf77740f5e66ad97dcc9ba801c092..d3f014ff05a2ab51060838b5a0be4f665b800b4f 100644 (file)
@@ -31,6 +31,8 @@
 #include <QPrintPreviewDialog>
 #include "about.h"
 #include "blockwidget.h"
+#include "commandprocessor.h"
+#include "consolewidget.h"
 #include "drawingview.h"
 #include "fileio.h"
 #include "generaltab.h"
@@ -58,10 +60,8 @@ ApplicationWindow::ApplicationWindow():
 
        aboutWin = new AboutWindow(this);
 
-//     ((TTEdit *)qApp)->charWnd = new CharWindow(this);
-
        setWindowIcon(QIcon(":/res/atns-icon.png"));
-       setWindowTitle("Architektonas");
+//     setWindowTitle("Architektonas");
 
        CreateActions();
        CreateMenus();
@@ -80,10 +80,16 @@ ApplicationWindow::ApplicationWindow():
        ObjectWidget * ow = new ObjectWidget;
        dock3->setWidget(ow);
        addDockWidget(Qt::RightDockWidgetArea, dock3);
+       QDockWidget * dock4 = new QDockWidget(tr("Command"), this);
+       cw = new ConsoleWidget;
+       dock4->setWidget(cw);
+       addDockWidget(Qt::BottomDockWidgetArea, dock4);
+
        // Needed for saveState()
        dock1->setObjectName("Layers");
        dock2->setObjectName("Blocks");
        dock3->setObjectName("Object");
+       dock4->setObjectName("Commands");
 
        // Create status bar
        zoomIndicator = new QLabel("Zoom: 100% Grid: 12.0\" BU: Inch");
@@ -91,6 +97,8 @@ ApplicationWindow::ApplicationWindow():
        statusBar()->showMessage(tr("Ready"));
 
        ReadSettings();
+       // Make sure the bottom left corner gets owned by the right side:
+       setCorner(Qt::BottomRightCorner, Qt::RightDockWidgetArea);
        setUnifiedTitleAndToolBarOnMac(true);
        Global::font =  new QFont("Verdana", 15, QFont::Bold);
 
@@ -101,6 +109,8 @@ ApplicationWindow::ApplicationWindow():
 
        connect(drawing, SIGNAL(ObjectHovered(Object *)), ow, SLOT(ShowInfo(Object *)));
        connect(drawing, SIGNAL(NeedZoomUpdate()), this, SLOT(UpdateZoom()));
+
+       connect(cw->cmdProc, SIGNAL(UpdateNeeded()), this, SLOT(UpdateFromCommand()));
 }
 
 void ApplicationWindow::closeEvent(QCloseEvent * event)
@@ -146,7 +156,8 @@ void ApplicationWindow::FileNew(void)
        drawing->dirty = false;
        drawing->update();
        documentName.clear();
-       setWindowTitle("Architektonas - Untitled");
+//     setWindowTitle("Architektonas - Untitled");
+       setWindowFilePath(documentName);
        statusBar()->showMessage(tr("New drawing is ready."));
 }
 
@@ -159,6 +170,21 @@ void ApplicationWindow::FileOpen(void)
        if (filename.isEmpty())
                return;
 
+       LoadFile(filename);
+}
+
+void ApplicationWindow::FileOpenRecent(void)
+{
+       QAction * action = qobject_cast<QAction *>(sender());
+
+       if (!action)
+               return;
+
+       LoadFile(action->data().toString());
+}
+
+void ApplicationWindow::LoadFile(QString filename)
+{
        FILE * file = fopen(filename.toUtf8().data(), "r");
 
        if (file == 0)
@@ -185,7 +211,6 @@ void ApplicationWindow::FileOpen(void)
                return;
        }
 
-//printf("FileOpen: container size = %li\n", container.objects.size());
        // Keep memory leaks from happening by getting rid of the old document
        DeleteContents(drawing->document.objects);
        emit ReloadLayers();
@@ -196,7 +221,8 @@ void ApplicationWindow::FileOpen(void)
        drawing->dirty = false;
        drawing->update();
        documentName = filename;
-       setWindowTitle(QString("Architektonas - %1").arg(documentName));
+//     setWindowTitle(QString("Architektonas - %1").arg(documentName));
+       AdjustMRU(filename);
        statusBar()->showMessage(tr("Drawing loaded."));
 }
 
@@ -234,7 +260,8 @@ void ApplicationWindow::FileSave(void)
        }
 
        drawing->dirty = false;
-       setWindowTitle(QString("Architektonas - %1").arg(documentName));
+//     setWindowTitle(QString("Architektonas - %1").arg(documentName));
+       AdjustMRU(documentName);
        statusBar()->showMessage(tr("Drawing saved."));
 }
 
@@ -298,15 +325,52 @@ void ApplicationWindow::HandlePrintRequest(QPrinter * printer)
        Global::screenSize = screenSizeSave;
 }
 
+//
+// Right-click menu
+//
 void ApplicationWindow::contextMenuEvent(QContextMenuEvent * event)
 {
+       // Proof of concept, still need to code up the real thing
        QMenu menu(this);
+
+       VPVector hovered = drawing->GetHovered();
+
+       if ((drawing->select.size() > 0) || (hovered.size() > 0))
+       {
+               QMenu * layerMenu = menu.addMenu("To layer");
+
+               layerAct.clear();
+
+               for(int i=0; i<Global::numLayers; i++)
+               {
+                       QAction * act = new QAction(QIcon(), Global::layerName[i].c_str(), this);
+                       act->setData(i);
+                       layerMenu->addAction(act);
+                       layerAct.append(act);
+                       connect(act, SIGNAL(triggered()), this, SLOT(MoveToLayer()));
+               }
+       }
+
        menu.addAction(mirrorAct);
        menu.addAction(rotateAct);
        menu.addAction(trimAct);
        menu.exec(event->globalPos());
 }
 
+void ApplicationWindow::MoveToLayer(void)
+{
+       QAction * act = qobject_cast<QAction *>(sender());
+
+       drawing->MoveSelectedToLayer(act->data().toInt());
+       drawing->update();
+}
+
+void ApplicationWindow::UpdateFromCommand(void)
+{
+       cw->SetToolPrompt();
+       drawing->update();
+}
+
 void ApplicationWindow::SnapToGridTool(void)
 {
        Global::snapToGrid = snapToGridAct->isChecked();
@@ -326,7 +390,6 @@ void ApplicationWindow::DeleteTool(void)
 {
        // For this tool, we check first to see if anything is selected. If so, we
        // delete those and *don't* select the delete tool.
-//     if (drawing->numSelected > 0)
        if (drawing->select.size() > 0)
        {
                DeleteSelectedObjects(drawing->document.objects);
@@ -338,6 +401,7 @@ void ApplicationWindow::DeleteTool(void)
        // Otherwise, toggle the state of the tool
        ClearUIToolStatesExcept(deleteAct);
        SetInternalToolStates();
+       Global::toolSuppressCrosshair = true;
 }
 
 void ApplicationWindow::DimensionTool(void)
@@ -372,6 +436,14 @@ void ApplicationWindow::TrimTool(void)
 {
        ClearUIToolStatesExcept(trimAct);
        SetInternalToolStates();
+       Global::toolSuppressCrosshair = true;
+}
+
+void ApplicationWindow::ParallelTool(void)
+{
+       ClearUIToolStatesExcept(parallelAct);
+       SetInternalToolStates();
+       Global::toolSuppressCrosshair = true;
 }
 
 void ApplicationWindow::TriangulateTool(void)
@@ -465,7 +537,6 @@ void ApplicationWindow::UpdateZoom(void)
        else
                Global::gridSpacing = 0.015625;
 
-//     drawing->SetGridSize((double)(Global::gridSpacing * Global::zoom));
        drawing->update();
 
        zoomIndicator->setText(QString("Zoom: %1% Grid: %2\" BU: Inch").arg(Global::zoom * 100.0).arg(Global::gridSpacing));
@@ -492,9 +563,11 @@ void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
 void ApplicationWindow::SetInternalToolStates(void)
 {
        // We can be sure that if we've come here, then either an active tool is
-       // being deactivated, or a new tool is being created. In either case, the
-       // old tool needs to be deleted.
+       // being deactivated, or a new tool is being activated.  In either case,
+       // the tool state needs to be reset.  Also, we reset the crosshair
+       // suppression flag.
        Global::toolState = TSNone;
+       Global::toolSuppressCrosshair = false;
 
        if (addLineAct->isChecked())
                Global::tool = TTLine;
@@ -516,11 +589,14 @@ void ApplicationWindow::SetInternalToolStates(void)
                Global::tool = TTRotate;
        else if (trimAct->isChecked())
                Global::tool = TTTrim;
+       else if (parallelAct->isChecked())
+               Global::tool = TTParallel;
        else if (triangulateAct->isChecked())
                Global::tool = TTTriangulate;
        else
                Global::tool = TTNone;
 
+       cw->SetToolPrompt();//cw->cmdline);
        drawing->update();
 }
 
@@ -697,11 +773,8 @@ void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
        if (!ok || value == 0)
                return;
 
-//     drawing->gridSpacing = value;
-//     Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
        Global::gridSpacing = value;
        Global::zoom = drawing->gridPixels / Global::gridSpacing;
-//     drawing->UpdateGridBackground();
        drawing->update();
 }
 
@@ -846,6 +919,9 @@ void ApplicationWindow::CreateActions(void)
        trimAct = CreateAction(tr("&Trim"), tr("Trim"), tr("Trim extraneous lines from selected objects."), QIcon(":/res/trim-tool.png"), QKeySequence("t,r"), true);
        connect(trimAct, SIGNAL(triggered()), this, SLOT(TrimTool()));
 
+       parallelAct = CreateAction(tr("&Parallel"), tr("Parallel"), tr("Create copies of objects parallel to the original."), QIcon(":/res/parallel-tool.png"), QKeySequence("p,l"), true);
+       connect(parallelAct, SIGNAL(triggered()), this, SLOT(ParallelTool()));
+
        triangulateAct = CreateAction(tr("&Triangulate"), tr("Triangulate"), tr("Make triangles from selected lines, preserving their lengths."), QIcon(":/res/triangulate-tool.png"), QKeySequence("t,g"), true);
        connect(triangulateAct, SIGNAL(triggered()), this, SLOT(TriangulateTool()));
 
@@ -872,6 +948,14 @@ void ApplicationWindow::CreateActions(void)
        group->addAction(addLineAct);
        group->addAction(addCircleAct);
        group->addAction(addArcAct);//*/
+
+       for(int i=0; i<MRU_MAX; i++)
+       {
+               QAction * rfa = new QAction(this);
+               rfa->setVisible(false);
+               connect(rfa, SIGNAL(triggered()), this, SLOT(FileOpenRecent()));
+               mruAct.append(rfa);
+       }
 }
 
 //
@@ -914,6 +998,14 @@ void ApplicationWindow::CreateMenus(void)
        QMenu * menu = menuBar()->addMenu(tr("&File"));
        menu->addAction(fileNewAct);
        menu->addAction(fileOpenAct);
+
+       QMenu * recentMenu = menu->addMenu(tr("Open &Recent"));
+
+       for(int i=0; i<MRU_MAX; i++)
+               recentMenu->addAction(mruAct.at(i));
+
+       UpdateMRUActionList();
+
        menu->addAction(fileSaveAct);
        menu->addAction(fileSaveAsAct);
        menu->addAction(fileCloseAct);
@@ -934,6 +1026,7 @@ void ApplicationWindow::CreateMenus(void)
        menu->addAction(rotateAct);
        menu->addAction(mirrorAct);
        menu->addAction(trimAct);
+       menu->addAction(parallelAct);
        menu->addAction(triangulateAct);
        menu->addAction(connectAct);
        menu->addAction(disconnectAct);
@@ -966,7 +1059,6 @@ void ApplicationWindow::CreateToolbars(void)
        toolbar->addAction(fileSaveAct);
        toolbar->addAction(fileSaveAsAct);
        toolbar->addAction(fileCloseAct);
-//     toolbar->addAction(exitAct);
 
        toolbar = addToolBar(tr("View"));
        toolbar->setObjectName("View");
@@ -975,7 +1067,6 @@ void ApplicationWindow::CreateToolbars(void)
 
        QSpinBox * spinbox = new QSpinBox;
        toolbar->addWidget(spinbox);
-//     QLineEdit * lineedit = new QLineEdit;
        toolbar->addWidget(baseUnitInput);
        toolbar->addWidget(dimensionSizeInput);
 
@@ -988,6 +1079,7 @@ void ApplicationWindow::CreateToolbars(void)
        toolbar->addAction(rotateAct);
        toolbar->addAction(mirrorAct);
        toolbar->addAction(trimAct);
+       toolbar->addAction(parallelAct);
        toolbar->addAction(triangulateAct);
        toolbar->addAction(editCutAct);
        toolbar->addAction(editCopyAct);
@@ -1015,10 +1107,6 @@ void ApplicationWindow::CreateToolbars(void)
        toolbar->setObjectName(tr("Pen"));
        toolbar->addWidget(pw);
        connect(drawing, SIGNAL(ObjectSelected(Object *)), pw, SLOT(SetFields(Object *)));
-       connect(pw, SIGNAL(WidthSelected(float)), drawing, SLOT(HandlePenWidth(float)));
-       connect(pw, SIGNAL(StyleSelected(int)), drawing, SLOT(HandlePenStyle(int)));
-       connect(pw, SIGNAL(ColorSelected(uint32_t)), drawing, SLOT(HandlePenColor(uint32_t)));
-//     connect(pw, SIGNAL(StampSelected(void)), drawing, SLOT(HandlePenStamp(QAction *)));
        connect(pw->tbStamp, SIGNAL(triggered(QAction *)), drawing, SLOT(HandlePenStamp(QAction *)));
        connect(pw->tbDropper, SIGNAL(triggered(QAction *)), drawing, SLOT(HandlePenDropper(QAction *)));
 }
@@ -1042,3 +1130,38 @@ void ApplicationWindow::WriteSettings(void)
        settings.setValue("useAntialiasing", drawing->useAntialiasing);
        settings.setValue("snapToGrid", snapToGridAct->isChecked());
 }
+
+void ApplicationWindow::UpdateMRUActionList(void)
+{
+       QStringList mruFilePaths = settings.value("recentFiles").toStringList();
+
+       int mruSize = (mruFilePaths.size() <= MRU_MAX ? mruFilePaths.size() : MRU_MAX);
+
+       for(int i=0; i<mruSize; i++)
+       {
+               QString filename = QFileInfo(mruFilePaths.at(i)).fileName();
+               mruAct.at(i)->setText(filename);
+               mruAct.at(i)->setData(mruFilePaths.at(i));
+               mruAct.at(i)->setVisible(true);
+       }
+
+       for(int i=mruSize; i<MRU_MAX; i++)
+               mruAct.at(i)->setVisible(false);
+}
+
+void ApplicationWindow::AdjustMRU(const QString & filePath)
+{
+       documentName = filePath;
+       setWindowFilePath(documentName);
+
+       QStringList mruFilePaths = settings.value("recentFiles").toStringList();
+       mruFilePaths.removeAll(filePath);
+       mruFilePaths.prepend(filePath);
+
+       while (mruFilePaths.size() > MRU_MAX)
+               mruFilePaths.removeLast();
+
+       settings.setValue("recentFiles", mruFilePaths);
+
+       UpdateMRUActionList();
+}