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"
41 #include "mirroraction.h"
43 #include "rotateaction.h"
44 #include "settingsdialog.h"
48 DrawingView * ApplicationWindow::drawing;
51 ApplicationWindow::ApplicationWindow():
52 baseUnitInput(new QLineEdit),
53 dimensionSizeInput(new QLineEdit),
54 settings("Underground Software", "Architektonas")
56 drawing = new DrawingView(this);
57 drawing->setMouseTracking(true); // We want *all* mouse events...!
58 drawing->setFocusPolicy(Qt::StrongFocus);
59 setCentralWidget(drawing);
61 aboutWin = new AboutWindow(this);
63 // ((TTEdit *)qApp)->charWnd = new CharWindow(this);
65 setWindowIcon(QIcon(":/res/atns-icon.png"));
66 setWindowTitle("Architektonas");
72 // Create Dock widgets
73 QDockWidget * dock1 = new QDockWidget(tr("Layers"), this);
74 LayerWidget * lw = new LayerWidget;
76 addDockWidget(Qt::RightDockWidgetArea, dock1);
77 QDockWidget * dock2 = new QDockWidget(tr("Blocks"), this);
78 BlockWidget * bw = new BlockWidget;
80 addDockWidget(Qt::RightDockWidgetArea, dock2);
81 // Needed for saveState()
82 dock1->setObjectName("Layers");
83 dock2->setObjectName("Blocks");
86 zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
87 statusBar()->addPermanentWidget(zoomIndicator);
88 statusBar()->showMessage(tr("Ready"));
91 setUnifiedTitleAndToolBarOnMac(true);
92 Object::SetFont(new QFont("Verdana", 15, QFont::Bold));
94 connect(lw, SIGNAL(LayerSelected(int)), drawing, SLOT(SetCurrentLayer(int)));
98 void ApplicationWindow::closeEvent(QCloseEvent * event)
101 event->accept(); // Use ignore() if can't close for some reason
102 //Do we have a memory leak here if we don't delete the font in the Object???
106 void ApplicationWindow::FileNew(void)
108 // Should warn the user if drawing hasn't been saved...
109 drawing->document.Clear();
111 documentName.clear();
112 setWindowTitle("Architektonas - Untitled");
113 statusBar()->showMessage(tr("New drawing is ready."));
117 void ApplicationWindow::FileOpen(void)
119 QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
120 "", tr("Architektonas files (*.drawing)"));
121 FILE * file = fopen(filename.toAscii().data(), "r");
126 msg.setText(QString(tr("Could not open file \"%1\" for loading!")).arg(filename));
127 msg.setIcon(QMessageBox::Critical);
132 Container container(Vector(0, 0));
133 bool successful = FileIO::LoadAtnsFile(file, &container);
139 msg.setText(QString(tr("Could not load file \"%1\"!")).arg(filename));
140 msg.setIcon(QMessageBox::Critical);
145 printf("FileOpen: container size = %li\n", container.objects.size());
146 drawing->document = container;
148 documentName = filename;
149 setWindowTitle(QString("Architektonas - %1").arg(documentName));
150 statusBar()->showMessage(tr("Drawing loaded."));
154 void ApplicationWindow::FileSave(void)
156 if (documentName.isEmpty())
157 documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"),
158 "", tr("Architektonas drawings (*.drawing)"));
160 FILE * file = fopen(documentName.toAscii().data(), "w");
165 msg.setText(QString(tr("Could not open file \"%1\" for saving!")).arg(documentName));
166 msg.setIcon(QMessageBox::Critical);
171 bool successful = FileIO::SaveAtnsFile(file, &drawing->document);
177 msg.setText(QString(tr("Could not save file \"%1\"!")).arg(documentName));
178 msg.setIcon(QMessageBox::Critical);
180 // In this case, we should unlink the created file, since it's not right...
181 unlink(documentName.toAscii().data());
185 setWindowTitle(QString("Architektonas - %1").arg(documentName));
186 statusBar()->showMessage(tr("Drawing saved."));
190 void ApplicationWindow::FileSaveAs(void)
192 QString filename = QFileDialog::getSaveFileName(this, tr("Save Drawing As"),
193 documentName, tr("Architektonas drawings (*.drawing)"));
195 if (!filename.isEmpty())
197 documentName = filename;
203 void ApplicationWindow::SnapToGridTool(void)
205 Object::SetSnapMode(snapToGridAct->isChecked());
209 void ApplicationWindow::FixAngle(void)
211 Object::SetFixedAngle(fixAngleAct->isChecked());
215 void ApplicationWindow::FixLength(void)
217 Object::SetFixedLength(fixLengthAct->isChecked());
221 // We want certain tools to be exclusive, and this approach isn't working correctly...
222 void ApplicationWindow::DeleteTool(void)
224 // For this tool, we check first to see if anything is selected. If so, we
225 // delete those and *don't* select the delete tool.
226 if (drawing->document.ItemsSelected() > 0)
228 drawing->document.DeleteSelectedItems();
230 deleteAct->setChecked(false);
234 // Otherwise, toggle the state of the tool
235 ClearUIToolStatesExcept(deleteAct);
236 SetInternalToolStates();
240 void ApplicationWindow::DimensionTool(void)
242 ClearUIToolStatesExcept(addDimensionAct);
243 SetInternalToolStates();
247 void ApplicationWindow::RotateTool(void)
249 ClearUIToolStatesExcept(rotateAct);
250 SetInternalToolStates();
254 void ApplicationWindow::MirrorTool(void)
256 ClearUIToolStatesExcept(mirrorAct);
257 SetInternalToolStates();
261 void ApplicationWindow::AddLineTool(void)
263 ClearUIToolStatesExcept(addLineAct);
264 SetInternalToolStates();
268 void ApplicationWindow::AddCircleTool(void)
270 ClearUIToolStatesExcept(addCircleAct);
271 SetInternalToolStates();
275 void ApplicationWindow::AddArcTool(void)
277 ClearUIToolStatesExcept(addArcAct);
278 SetInternalToolStates();
282 void ApplicationWindow::AddPolygonTool(void)
284 ClearUIToolStatesExcept(addPolygonAct);
285 SetInternalToolStates();
289 void ApplicationWindow::ZoomInTool(void)
291 double zoomFactor = 2.0;
293 We need to find the center of the screen, then figure out where the new corner
294 will be in the zoomed in window.
296 So we know in Qt coords, the center is found via:
297 size.width() / 2 --> xCenter
298 size.height() / 2 --> yCenter
300 transform x/yCenter to Cartesian coordinates. So far, so good.
302 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
303 (after subtracting from center, that is...)
305 QSize size = drawing->size();
306 Vector center(size.width() / 2.0, size.height() / 2.0);
307 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
308 center = Painter::QtToCartesianCoords(center);
309 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
310 Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
311 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
312 Painter::origin = newOrigin;
314 //printf("Zoom in... level going from %02f to ", Painter::zoom);
315 // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
316 // This should actually be calculated by drawing->gridPixels / grid size.
317 Painter::zoom *= zoomFactor;
318 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
319 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
320 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
321 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
322 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
323 drawing->UpdateGridBackground();
326 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
327 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
331 void ApplicationWindow::ZoomOutTool(void)
336 origin = (223, 160.5)
337 newOrigin should be (-10, -10)
340 center - origin = (213, 150.5)
341 origin - center = (-213, -150.5)
343 + center = (-10, -10)
346 double zoomFactor = 2.0;
347 QSize size = drawing->size();
348 Vector center(size.width() / 2.0, size.height() / 2.0);
349 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
350 center = Painter::QtToCartesianCoords(center);
351 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
352 // Vector newOrigin = (center - Painter::origin) * zoomFactor;
353 // Vector newOrigin = center - (Painter::origin * zoomFactor);
354 Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
355 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
356 Painter::origin = newOrigin;
357 //printf("Zoom out...\n");
358 // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
359 Painter::zoom /= zoomFactor;
360 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
361 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
362 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
363 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
364 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
365 drawing->UpdateGridBackground();
368 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
369 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
373 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
375 if (exception != addArcAct)
376 addArcAct->setChecked(false);
378 if (exception != addCircleAct)
379 addCircleAct->setChecked(false);
381 if (exception != addDimensionAct)
382 addDimensionAct->setChecked(false);
384 if (exception != addLineAct)
385 addLineAct->setChecked(false);
387 if (exception != addPolygonAct)
388 addPolygonAct->setChecked(false);
390 if (exception != deleteAct)
391 deleteAct->setChecked(false);
393 if (exception != rotateAct)
394 rotateAct->setChecked(false);
396 if (exception != mirrorAct)
397 mirrorAct->setChecked(false);
401 void ApplicationWindow::SetInternalToolStates(void)
403 Object::SetDeleteActive(deleteAct->isChecked());
404 Object::SetDimensionActive(addDimensionAct->isChecked());
406 // We can be sure that if we've come here, then either an active tool is
407 // being deactivated, or a new tool is being created. In either case, the
408 // old tool needs to be deleted.
409 if (drawing->toolAction)
411 delete drawing->toolAction;
412 drawing->toolAction = NULL;
413 Object::ignoreClicks = false;
416 drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL);
417 drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL);
418 drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL);
419 drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
420 drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL);
421 drawing->SetToolActive(rotateAct->isChecked() ? new RotateAction() : NULL);
423 if (drawing->toolAction)
424 Object::ignoreClicks = true;
430 void ApplicationWindow::HelpAbout(void)
436 void ApplicationWindow::Settings(void)
438 SettingsDialog dlg(this);
439 dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
441 if (dlg.exec() == false)
444 // Deal with stuff here (since user hit "OK" button...)
445 drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
451 // Group a bunch of selected objects (which can include other groups) together
452 // or ungroup a selected group.
454 void ApplicationWindow::HandleGrouping(void)
456 int itemsSelected = drawing->document.ItemsSelected();
458 // If nothing selected, do nothing
459 if (itemsSelected == 0)
461 statusBar()->showMessage(tr("No objects selected to make a group from."));
465 // If it's a group that's selected, ungroup it and leave the objects in a
467 if (itemsSelected == 1)
469 Object * object = drawing->document.SelectedItem(0);
473 printf("SelectedItem = NULL!\n");
475 printf("SelectedItem = %08X, type = %i\n", object, object->type);
478 if (object == NULL || object->type != OTContainer)
480 statusBar()->showMessage(tr("A group requires two or more selected objects."));
484 // Need the parent of the group, we're assuming here that the parent is
485 // the drawing's document. Does it matter? Maybe...
486 // Could just stipulate that grouping like this only takes place where the
487 // parent of the group is the drawing's document. Makes life much simpler.
488 ((Container *)object)->SelectAll();
489 ((Container *)object)->MoveContentsTo(&(drawing->document));
490 drawing->document.Delete(object);
491 statusBar()->showMessage(tr("Objects ungrouped."));
493 // Otherwise, if it's a group of 2 or more objects (which can be groups too)
494 // group them and select the group
495 else if (itemsSelected > 1)
497 Container * container = new Container(Vector(), &(drawing->document));
498 drawing->document.MoveSelectedContentsTo(container);
499 drawing->document.Add(container);
500 container->DeselectAll();
501 container->state = OSSelected;
502 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
509 void ApplicationWindow::HandleGridSizeInPixels(int size)
511 drawing->SetGridSize(size);
516 void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
520 double value = text.toDouble(&ok);
522 // Nothing parsable to a double, so quit...
523 if (!ok || value == 0)
526 // drawing->gridSpacing = value;
527 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
528 Object::gridSpacing = value;
529 Painter::zoom = drawing->gridPixels / Object::gridSpacing;
530 drawing->UpdateGridBackground();
535 void ApplicationWindow::HandleDimensionSize(QString text)
539 double value = text.toDouble(&ok);
541 // Nothing parsable to a double, so quit...
542 if (!ok || value == 0)
545 drawing->document.ResizeAllDimensions(value);
546 // drawing->gridSpacing = value;
547 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
548 // drawing->UpdateGridBackground();
553 void ApplicationWindow::CreateActions(void)
555 exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
556 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
557 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
559 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);
560 connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
562 fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
563 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
564 connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
566 fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
567 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
568 connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
570 deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
571 connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
573 addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
574 connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
576 addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
577 connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
579 addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
580 connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
582 addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
583 connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
585 addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
586 connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
588 aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
589 connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
591 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);
592 connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
594 zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
595 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
597 zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
598 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
600 fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/file-new.png"), QKeySequence(tr("Ctrl+n")));
601 connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
603 fileOpenAct = CreateAction(tr("&Open Drawing"), tr("Open Drawing"), tr("Opens an existing drawing from a file."), QIcon(":/res/file-open.png"), QKeySequence(tr("Ctrl+o")));
604 connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
606 fileSaveAct = CreateAction(tr("&Save Drawing"), tr("Save Drawing"), tr("Saves the current drawing to a file."), QIcon(":/res/file-save.png"), QKeySequence(tr("Ctrl+s")));
607 connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
609 fileSaveAsAct = CreateAction(tr("Save Drawing &As"), tr("Save As"), tr("Saves the current drawing to a file with a different name."), QIcon(":/res/file-save-as.png"), QKeySequence(tr("Ctrl+Shift+s")));
610 connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
612 fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/file-close.png"), QKeySequence(tr("Ctrl+w")));
614 settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/settings.png"), QKeySequence());
615 connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
617 groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
618 connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
620 connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c"));
622 disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d"));
624 mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true);
625 connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool()));
628 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
629 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
630 /* QActionGroup * group = new QActionGroup(this);
631 group->addAction(deleteAct);
632 group->addAction(addDimensionAct);
633 group->addAction(addLineAct);
634 group->addAction(addCircleAct);
635 group->addAction(addArcAct);//*/
640 // Consolidates action creation from a multi-step process to a single-step one.
642 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
643 QIcon icon, QKeySequence key, bool checkable/*= false*/)
645 QAction * action = new QAction(icon, name, this);
646 action->setToolTip(tooltip);
647 action->setStatusTip(statustip);
648 action->setShortcut(key);
649 action->setCheckable(checkable);
656 // This is essentially the same as the previous function, but this allows more
657 // than one key sequence to be added as key shortcuts.
659 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
660 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
662 QAction * action = new QAction(icon, name, this);
663 action->setToolTip(tooltip);
664 action->setStatusTip(statustip);
665 QList<QKeySequence> keyList;
666 keyList.append(key1);
667 keyList.append(key2);
668 action->setShortcuts(keyList);
669 action->setCheckable(checkable);
675 void ApplicationWindow::CreateMenus(void)
677 QMenu * menu = menuBar()->addMenu(tr("&File"));
678 menu->addAction(fileNewAct);
679 menu->addAction(fileOpenAct);
680 menu->addAction(fileSaveAct);
681 menu->addAction(fileSaveAsAct);
682 menu->addAction(fileCloseAct);
683 menu->addSeparator();
684 menu->addAction(exitAct);
686 menu = menuBar()->addMenu(tr("&View"));
687 menu->addAction(zoomInAct);
688 menu->addAction(zoomOutAct);
690 menu = menuBar()->addMenu(tr("&Edit"));
691 menu->addAction(snapToGridAct);
692 menu->addAction(groupAct);
693 menu->addAction(fixAngleAct);
694 menu->addAction(fixLengthAct);
695 menu->addAction(rotateAct);
696 menu->addAction(mirrorAct);
697 menu->addAction(connectAct);
698 menu->addAction(disconnectAct);
699 menu->addSeparator();
700 menu->addAction(deleteAct);
701 menu->addSeparator();
702 menu->addAction(addLineAct);
703 menu->addAction(addCircleAct);
704 menu->addAction(addArcAct);
705 menu->addAction(addPolygonAct);
706 menu->addAction(addDimensionAct);
707 menu->addSeparator();
708 menu->addAction(settingsAct);
710 menu = menuBar()->addMenu(tr("&Help"));
711 menu->addAction(aboutAct);
715 void ApplicationWindow::CreateToolbars(void)
717 QToolBar * toolbar = addToolBar(tr("File"));
718 toolbar->setObjectName("File"); // Needed for saveState()
719 toolbar->addAction(fileNewAct);
720 toolbar->addAction(fileOpenAct);
721 toolbar->addAction(fileSaveAct);
722 toolbar->addAction(fileSaveAsAct);
723 toolbar->addAction(fileCloseAct);
724 // toolbar->addAction(exitAct);
726 toolbar = addToolBar(tr("View"));
727 toolbar->setObjectName("View");
728 toolbar->addAction(zoomInAct);
729 toolbar->addAction(zoomOutAct);
731 QSpinBox * spinbox = new QSpinBox;
732 toolbar->addWidget(spinbox);
733 // QLineEdit * lineedit = new QLineEdit;
734 toolbar->addWidget(baseUnitInput);
735 toolbar->addWidget(dimensionSizeInput);
737 toolbar = addToolBar(tr("Edit"));
738 toolbar->setObjectName("Edit");
739 toolbar->addAction(snapToGridAct);
740 toolbar->addAction(groupAct);
741 toolbar->addAction(fixAngleAct);
742 toolbar->addAction(fixLengthAct);
743 toolbar->addAction(rotateAct);
744 toolbar->addAction(mirrorAct);
745 toolbar->addAction(deleteAct);
746 toolbar->addAction(connectAct);
747 toolbar->addAction(disconnectAct);
748 toolbar->addSeparator();
749 toolbar->addAction(addLineAct);
750 toolbar->addAction(addCircleAct);
751 toolbar->addAction(addArcAct);
752 toolbar->addAction(addPolygonAct);
753 toolbar->addAction(addDimensionAct);
755 spinbox->setRange(4, 256);
756 spinbox->setValue(12);
757 baseUnitInput->setText("12");
758 connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(HandleGridSizeInPixels(int)));
759 connect(baseUnitInput, SIGNAL(textChanged(QString)), this, SLOT(HandleGridSizeInBaseUnits(QString)));
760 connect(dimensionSizeInput, SIGNAL(textChanged(QString)), this, SLOT(HandleDimensionSize(QString)));
764 void ApplicationWindow::ReadSettings(void)
766 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
767 QSize size = settings.value("size", QSize(400, 400)).toSize();
768 drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
769 snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
772 restoreState(settings.value("windowState").toByteArray());
776 void ApplicationWindow::WriteSettings(void)
778 settings.setValue("pos", pos());
779 settings.setValue("size", size());
780 settings.setValue("windowState", saveState());
781 settings.setValue("useAntialiasing", drawing->useAntialiasing);
782 settings.setValue("snapToGrid", snapToGridAct->isChecked());