2 // applicationwindow.cpp: Architektonas
4 // Part of the Architektonas Project
5 // (C) 2011 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
8 // JLH = James Hammons <jlhamm@acm.org>
11 // --- ---------- -------------------------------------------------------------
12 // JLH 03/22/2011 Created this file
13 // JLH 09/29/2011 Added simple zoom in/out functionality
14 // JLH 10/03/2011 Fixed zoom tool to zoom in/out from center of screen
24 // Uncomment this for debugging...
26 //#define DEBUGFOO // Various tool debugging...
27 //#define DEBUGTP // Toolpalette debugging...
29 #include "applicationwindow.h"
32 #include "blockwidget.h"
33 #include "drawingview.h"
34 #include "drawarcaction.h"
35 #include "drawcircleaction.h"
36 #include "drawdimensionaction.h"
37 #include "drawlineaction.h"
39 #include "generaltab.h"
40 #include "layerwidget.h"
42 #include "settingsdialog.h"
45 ApplicationWindow::ApplicationWindow():
46 baseUnitInput(new QLineEdit),
47 dimensionSizeInput(new QLineEdit),
48 settings("Underground Software", "Architektonas")
50 drawing = new DrawingView(this);
51 drawing->setMouseTracking(true); // We want *all* mouse events...!
52 setCentralWidget(drawing);
54 aboutWin = new AboutWindow(this);
56 // ((TTEdit *)qApp)->charWnd = new CharWindow(this);
58 setWindowIcon(QIcon(":/res/atns-icon.png"));
59 setWindowTitle("Architektonas");
65 // Create Dock widgets
66 QDockWidget * dock1 = new QDockWidget(tr("Layers"), this);
67 LayerWidget * lw = new LayerWidget;
69 addDockWidget(Qt::RightDockWidgetArea, dock1);
70 QDockWidget * dock2 = new QDockWidget(tr("Blocks"), this);
71 BlockWidget * bw = new BlockWidget;
73 addDockWidget(Qt::RightDockWidgetArea, dock2);
74 // Needed for saveState()
75 dock1->setObjectName("Layers");
76 dock2->setObjectName("Blocks");
79 zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
80 statusBar()->addPermanentWidget(zoomIndicator);
81 statusBar()->showMessage(tr("Ready"));
84 setUnifiedTitleAndToolBarOnMac(true);
85 Object::SetFont(new QFont("Verdana", 15, QFont::Bold));
89 void ApplicationWindow::closeEvent(QCloseEvent * event)
92 event->accept(); // Use ignore() if can't close for some reason
93 //Do we have a memory leak here if we don't delete the font in the Object???
97 void ApplicationWindow::FileNew(void)
99 // Should warn the user if drawing hasn't been saved...
100 drawing->document.Clear();
102 documentName.clear();
103 setWindowTitle("Architektonas - Untitled");
104 statusBar()->showMessage(tr("New drawing is ready."));
108 void ApplicationWindow::FileOpen(void)
110 QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
111 "", tr("Architektonas files (*.drawing)"));
112 FILE * file = fopen(filename.toAscii().data(), "r");
117 msg.setText(QString(tr("Could not open file \"%1\" for loading!")).arg(filename));
118 msg.setIcon(QMessageBox::Critical);
123 Container container(Vector(0, 0));
124 bool successful = FileIO::LoadAtnsFile(file, &container);
130 msg.setText(QString(tr("Could not load file \"%1\"!")).arg(filename));
131 msg.setIcon(QMessageBox::Critical);
136 printf("FileOpen: container size = %li\n", container.objects.size());
137 drawing->document = container;
139 documentName = filename;
140 setWindowTitle(QString("Architektonas - %1").arg(documentName));
141 statusBar()->showMessage(tr("Drawing loaded."));
145 void ApplicationWindow::FileSave(void)
147 if (documentName.isEmpty())
148 documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"),
149 "", tr("Architektonas drawings (*.drawing)"));
151 FILE * file = fopen(documentName.toAscii().data(), "w");
156 msg.setText(QString(tr("Could not open file \"%1\" for saving!")).arg(documentName));
157 msg.setIcon(QMessageBox::Critical);
162 bool successful = FileIO::SaveAtnsFile(file, &drawing->document);
168 msg.setText(QString(tr("Could not save file \"%1\"!")).arg(documentName));
169 msg.setIcon(QMessageBox::Critical);
171 // In this case, we should unlink the created file, since it's not right...
172 unlink(documentName.toAscii().data());
176 setWindowTitle(QString("Architektonas - %1").arg(documentName));
177 statusBar()->showMessage(tr("Drawing saved."));
181 void ApplicationWindow::FileSaveAs(void)
183 QString filename = QFileDialog::getSaveFileName(this, tr("Save Drawing As"),
184 documentName, tr("Architektonas drawings (*.drawing)"));
186 if (!filename.isEmpty())
188 documentName = filename;
194 void ApplicationWindow::SnapToGridTool(void)
196 Object::SetSnapMode(snapToGridAct->isChecked());
200 void ApplicationWindow::FixAngle(void)
202 Object::SetFixedAngle(fixAngleAct->isChecked());
206 void ApplicationWindow::FixLength(void)
208 Object::SetFixedLength(fixLengthAct->isChecked());
212 // We want certain tools to be exclusive, and this approach isn't working correctly...
213 void ApplicationWindow::DeleteTool(void)
215 // For this tool, we check first to see if anything is selected. If so, we
216 // delete those and *don't* select the delete tool.
217 if (drawing->document.ItemsSelected() > 0)
219 drawing->document.DeleteSelectedItems();
221 deleteAct->setChecked(false);
225 // Otherwise, toggle the state of the tool
226 ClearUIToolStatesExcept(deleteAct);
227 SetInternalToolStates();
231 void ApplicationWindow::DimensionTool(void)
233 ClearUIToolStatesExcept(addDimensionAct);
234 SetInternalToolStates();
238 void ApplicationWindow::RotateTool(void)
240 ClearUIToolStatesExcept(rotateAct);
241 SetInternalToolStates();
245 void ApplicationWindow::AddLineTool(void)
247 ClearUIToolStatesExcept(addLineAct);
248 SetInternalToolStates();
252 void ApplicationWindow::AddCircleTool(void)
254 ClearUIToolStatesExcept(addCircleAct);
255 SetInternalToolStates();
259 void ApplicationWindow::AddArcTool(void)
261 ClearUIToolStatesExcept(addArcAct);
262 SetInternalToolStates();
266 void ApplicationWindow::AddPolygonTool(void)
268 ClearUIToolStatesExcept(addPolygonAct);
269 SetInternalToolStates();
273 void ApplicationWindow::ZoomInTool(void)
275 double zoomFactor = 2.0;
277 We need to find the center of the screen, then figure out where the new corner
278 will be in the zoomed in window.
280 So we know in Qt coords, the center is found via:
281 size.width() / 2 --> xCenter
282 size.height() / 2 --> yCenter
284 transform x/yCenter to Cartesian coordinates. So far, so good.
286 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
287 (after subtracting from center, that is...)
289 QSize size = drawing->size();
290 Vector center(size.width() / 2.0, size.height() / 2.0);
291 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
292 center = Painter::QtToCartesianCoords(center);
293 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
294 Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
295 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
296 Painter::origin = newOrigin;
298 //printf("Zoom in... level going from %02f to ", Painter::zoom);
299 // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
300 // This should actually be calculated by drawing->gridPixels / grid size.
301 Painter::zoom *= zoomFactor;
302 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
303 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
304 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
305 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
306 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
307 drawing->UpdateGridBackground();
310 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
311 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
315 void ApplicationWindow::ZoomOutTool(void)
320 origin = (223, 160.5)
321 newOrigin should be (-10, -10)
324 center - origin = (213, 150.5)
325 origin - center = (-213, -150.5)
327 + center = (-10, -10)
330 double zoomFactor = 2.0;
331 QSize size = drawing->size();
332 Vector center(size.width() / 2.0, size.height() / 2.0);
333 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
334 center = Painter::QtToCartesianCoords(center);
335 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
336 // Vector newOrigin = (center - Painter::origin) * zoomFactor;
337 // Vector newOrigin = center - (Painter::origin * zoomFactor);
338 Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
339 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
340 Painter::origin = newOrigin;
341 //printf("Zoom out...\n");
342 // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
343 Painter::zoom /= zoomFactor;
344 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
345 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
346 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
347 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
348 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
349 drawing->UpdateGridBackground();
352 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
353 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
357 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
359 if (exception != addArcAct)
360 addArcAct->setChecked(false);
362 if (exception != addCircleAct)
363 addCircleAct->setChecked(false);
365 if (exception != addDimensionAct)
366 addDimensionAct->setChecked(false);
368 if (exception != addLineAct)
369 addLineAct->setChecked(false);
371 if (exception != addPolygonAct)
372 addPolygonAct->setChecked(false);
374 if (exception != deleteAct)
375 deleteAct->setChecked(false);
377 if (exception != rotateAct)
378 rotateAct->setChecked(false);
382 void ApplicationWindow::SetInternalToolStates(void)
384 Object::SetDeleteActive(deleteAct->isChecked());
385 Object::SetDimensionActive(addDimensionAct->isChecked());
386 drawing->SetRotateToolActive(rotateAct->isChecked());
388 // We can be sure that if we've come here, then either an active tool is
389 // being deactivated, or a new tool is being created. In either case, the
390 // old tool needs to be deleted.
391 if (drawing->toolAction)
393 delete drawing->toolAction;
394 drawing->toolAction = NULL;
398 drawing->SetAddLineToolActive(addLineAct->isChecked());
399 drawing->SetAddCircleToolActive(addCircleAct->isChecked());
400 drawing->SetAddArcToolActive(addArcAct->isChecked());
401 drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
403 drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL);
404 drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL);
405 drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL);
406 drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
413 void ApplicationWindow::HelpAbout(void)
419 void ApplicationWindow::Settings(void)
421 SettingsDialog dlg(this);
422 dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
424 if (dlg.exec() == false)
427 // Deal with stuff here (since user hit "OK" button...)
428 drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
434 // Group a bunch of selected objects (which can include other groups) together
435 // or ungroup a selected group.
437 void ApplicationWindow::HandleGrouping(void)
439 int itemsSelected = drawing->document.ItemsSelected();
441 // If nothing selected, do nothing
442 if (itemsSelected == 0)
444 statusBar()->showMessage(tr("No objects selected to make a group from."));
448 // If it's a group that's selected, ungroup it and leave the objects in a
450 if (itemsSelected == 1)
452 Object * object = drawing->document.SelectedItem(0);
456 printf("SelectedItem = NULL!\n");
458 printf("SelectedItem = %08X, type = %i\n", object, object->type);
461 if (object == NULL || object->type != OTContainer)
463 statusBar()->showMessage(tr("A group requires two or more selected objects."));
467 // Need the parent of the group, we're assuming here that the parent is
468 // the drawing's document. Does it matter? Maybe...
469 // Could just stipulate that grouping like this only takes place where the
470 // parent of the group is the drawing's document. Makes life much simpler.
471 ((Container *)object)->SelectAll();
472 ((Container *)object)->MoveContentsTo(&(drawing->document));
473 drawing->document.Delete(object);
474 statusBar()->showMessage(tr("Objects ungrouped."));
476 // Otherwise, if it's a group of 2 or more objects (which can be groups too)
477 // group them and select the group
478 else if (itemsSelected > 1)
480 Container * container = new Container(Vector(), &(drawing->document));
481 drawing->document.MoveSelectedContentsTo(container);
482 drawing->document.Add(container);
483 container->DeselectAll();
484 container->state = OSSelected;
485 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
492 void ApplicationWindow::HandleGridSizeInPixels(int size)
494 drawing->SetGridSize(size);
499 void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
503 double value = text.toDouble(&ok);
505 // Nothing parsable to a double, so quit...
506 if (!ok || value == 0)
509 // drawing->gridSpacing = value;
510 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
511 Object::gridSpacing = value;
512 Painter::zoom = drawing->gridPixels / Object::gridSpacing;
513 drawing->UpdateGridBackground();
518 void ApplicationWindow::HandleDimensionSize(QString text)
522 double value = text.toDouble(&ok);
524 // Nothing parsable to a double, so quit...
525 if (!ok || value == 0)
528 drawing->document.ResizeAllDimensions(value);
529 // drawing->gridSpacing = value;
530 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
531 // drawing->UpdateGridBackground();
536 void ApplicationWindow::CreateActions(void)
538 exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
539 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
540 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
542 snapToGridAct = CreateAction(tr("Snap To &Grid"), tr("Snap To Grid"), tr("Snaps mouse cursor to the visible grid when moving/creating objects."), QIcon(":/res/snap-to-grid-tool.png"), QKeySequence(tr("S")), true);
543 connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
545 fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
546 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
547 connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
549 fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
550 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
551 connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
553 deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
554 connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
556 addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
557 connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
559 addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
560 connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
562 addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
563 connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
565 addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
566 connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
568 addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
569 connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
571 aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
572 connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
574 rotateAct = CreateAction(tr("&Rotate Objects"), tr("Rotate"), tr("Rotate object(s) around an arbitrary center."), QIcon(":/res/rotate-tool.png"), QKeySequence(tr("R,O")), true);
575 connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
577 zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
578 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
580 zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
581 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
583 fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+n")));
584 connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
586 fileOpenAct = CreateAction(tr("&Open Drawing"), tr("Open Drawing"), tr("Opens an existing drawing from a file."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+o")));
587 connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
589 fileSaveAct = CreateAction(tr("&Save Drawing"), tr("Save Drawing"), tr("Saves the current drawing to a file."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+s")));
590 connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
592 fileSaveAsAct = CreateAction(tr("Save Drawing &As"), tr("Save As"), tr("Saves the current drawing to a file with a different name."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+Shift+s")));
593 connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
595 fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+w")));
597 settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/generic-tool.png"), QKeySequence());
598 connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
600 groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
601 connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
603 connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c"));
605 disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d"));
607 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
608 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
609 /* QActionGroup * group = new QActionGroup(this);
610 group->addAction(deleteAct);
611 group->addAction(addDimensionAct);
612 group->addAction(addLineAct);
613 group->addAction(addCircleAct);
614 group->addAction(addArcAct);//*/
619 // Consolidates action creation from a multi-step process to a single-step one.
621 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
622 QIcon icon, QKeySequence key, bool checkable/*= false*/)
624 QAction * action = new QAction(icon, name, this);
625 action->setToolTip(tooltip);
626 action->setStatusTip(statustip);
627 action->setShortcut(key);
628 action->setCheckable(checkable);
635 // This is essentially the same as the previous function, but this allows more
636 // than one key sequence to be added as key shortcuts.
638 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
639 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
641 QAction * action = new QAction(icon, name, this);
642 action->setToolTip(tooltip);
643 action->setStatusTip(statustip);
644 QList<QKeySequence> keyList;
645 keyList.append(key1);
646 keyList.append(key2);
647 action->setShortcuts(keyList);
648 action->setCheckable(checkable);
654 void ApplicationWindow::CreateMenus(void)
656 QMenu * menu = menuBar()->addMenu(tr("&File"));
657 menu->addAction(fileNewAct);
658 menu->addAction(fileOpenAct);
659 menu->addAction(fileSaveAct);
660 menu->addAction(fileSaveAsAct);
661 menu->addAction(fileCloseAct);
662 menu->addSeparator();
663 menu->addAction(exitAct);
665 menu = menuBar()->addMenu(tr("&View"));
666 menu->addAction(zoomInAct);
667 menu->addAction(zoomOutAct);
669 menu = menuBar()->addMenu(tr("&Edit"));
670 menu->addAction(snapToGridAct);
671 menu->addAction(groupAct);
672 menu->addAction(fixAngleAct);
673 menu->addAction(fixLengthAct);
674 menu->addAction(rotateAct);
675 menu->addAction(connectAct);
676 menu->addAction(disconnectAct);
677 menu->addSeparator();
678 menu->addAction(deleteAct);
679 menu->addSeparator();
680 menu->addAction(addLineAct);
681 menu->addAction(addCircleAct);
682 menu->addAction(addArcAct);
683 menu->addAction(addPolygonAct);
684 menu->addAction(addDimensionAct);
685 menu->addSeparator();
686 menu->addAction(settingsAct);
688 menu = menuBar()->addMenu(tr("&Help"));
689 menu->addAction(aboutAct);
693 void ApplicationWindow::CreateToolbars(void)
695 QToolBar * toolbar = addToolBar(tr("File"));
696 toolbar->setObjectName("File"); // Needed for saveState()
697 toolbar->addAction(exitAct);
699 toolbar = addToolBar(tr("View"));
700 toolbar->setObjectName("View");
701 toolbar->addAction(zoomInAct);
702 toolbar->addAction(zoomOutAct);
704 QSpinBox * spinbox = new QSpinBox;
705 toolbar->addWidget(spinbox);
706 // QLineEdit * lineedit = new QLineEdit;
707 toolbar->addWidget(baseUnitInput);
708 toolbar->addWidget(dimensionSizeInput);
710 toolbar = addToolBar(tr("Edit"));
711 toolbar->setObjectName("Edit");
712 toolbar->addAction(snapToGridAct);
713 toolbar->addAction(groupAct);
714 toolbar->addAction(fixAngleAct);
715 toolbar->addAction(fixLengthAct);
716 toolbar->addAction(rotateAct);
717 toolbar->addAction(deleteAct);
718 toolbar->addAction(connectAct);
719 toolbar->addAction(disconnectAct);
720 toolbar->addSeparator();
721 toolbar->addAction(addLineAct);
722 toolbar->addAction(addCircleAct);
723 toolbar->addAction(addArcAct);
724 toolbar->addAction(addPolygonAct);
725 toolbar->addAction(addDimensionAct);
727 spinbox->setRange(4, 256);
728 spinbox->setValue(12);
729 baseUnitInput->setText("12");
730 connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(HandleGridSizeInPixels(int)));
731 connect(baseUnitInput, SIGNAL(textChanged(QString)), this, SLOT(HandleGridSizeInBaseUnits(QString)));
732 connect(dimensionSizeInput, SIGNAL(textChanged(QString)), this, SLOT(HandleDimensionSize(QString)));
736 void ApplicationWindow::ReadSettings(void)
738 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
739 QSize size = settings.value("size", QSize(400, 400)).toSize();
740 drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
741 snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
744 restoreState(settings.value("windowState").toByteArray());
748 void ApplicationWindow::WriteSettings(void)
750 settings.setValue("pos", pos());
751 settings.setValue("size", size());
752 settings.setValue("windowState", saveState());
753 settings.setValue("useAntialiasing", drawing->useAntialiasing);
754 settings.setValue("snapToGrid", snapToGridAct->isChecked());