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 "settingsdialog.h"
46 ApplicationWindow::ApplicationWindow():
47 baseUnitInput(new QLineEdit),
48 dimensionSizeInput(new QLineEdit),
49 settings("Underground Software", "Architektonas")
51 drawing = new DrawingView(this);
52 drawing->setMouseTracking(true); // We want *all* mouse events...!
53 drawing->setFocusPolicy(Qt::StrongFocus);
54 setCentralWidget(drawing);
56 aboutWin = new AboutWindow(this);
58 // ((TTEdit *)qApp)->charWnd = new CharWindow(this);
60 setWindowIcon(QIcon(":/res/atns-icon.png"));
61 setWindowTitle("Architektonas");
67 // Create Dock widgets
68 QDockWidget * dock1 = new QDockWidget(tr("Layers"), this);
69 LayerWidget * lw = new LayerWidget;
71 addDockWidget(Qt::RightDockWidgetArea, dock1);
72 QDockWidget * dock2 = new QDockWidget(tr("Blocks"), this);
73 BlockWidget * bw = new BlockWidget;
75 addDockWidget(Qt::RightDockWidgetArea, dock2);
76 // Needed for saveState()
77 dock1->setObjectName("Layers");
78 dock2->setObjectName("Blocks");
81 zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
82 statusBar()->addPermanentWidget(zoomIndicator);
83 statusBar()->showMessage(tr("Ready"));
86 setUnifiedTitleAndToolBarOnMac(true);
87 Object::SetFont(new QFont("Verdana", 15, QFont::Bold));
91 void ApplicationWindow::closeEvent(QCloseEvent * event)
94 event->accept(); // Use ignore() if can't close for some reason
95 //Do we have a memory leak here if we don't delete the font in the Object???
99 void ApplicationWindow::FileNew(void)
101 // Should warn the user if drawing hasn't been saved...
102 drawing->document.Clear();
104 documentName.clear();
105 setWindowTitle("Architektonas - Untitled");
106 statusBar()->showMessage(tr("New drawing is ready."));
110 void ApplicationWindow::FileOpen(void)
112 QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
113 "", tr("Architektonas files (*.drawing)"));
114 FILE * file = fopen(filename.toAscii().data(), "r");
119 msg.setText(QString(tr("Could not open file \"%1\" for loading!")).arg(filename));
120 msg.setIcon(QMessageBox::Critical);
125 Container container(Vector(0, 0));
126 bool successful = FileIO::LoadAtnsFile(file, &container);
132 msg.setText(QString(tr("Could not load file \"%1\"!")).arg(filename));
133 msg.setIcon(QMessageBox::Critical);
138 printf("FileOpen: container size = %li\n", container.objects.size());
139 drawing->document = container;
141 documentName = filename;
142 setWindowTitle(QString("Architektonas - %1").arg(documentName));
143 statusBar()->showMessage(tr("Drawing loaded."));
147 void ApplicationWindow::FileSave(void)
149 if (documentName.isEmpty())
150 documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"),
151 "", tr("Architektonas drawings (*.drawing)"));
153 FILE * file = fopen(documentName.toAscii().data(), "w");
158 msg.setText(QString(tr("Could not open file \"%1\" for saving!")).arg(documentName));
159 msg.setIcon(QMessageBox::Critical);
164 bool successful = FileIO::SaveAtnsFile(file, &drawing->document);
170 msg.setText(QString(tr("Could not save file \"%1\"!")).arg(documentName));
171 msg.setIcon(QMessageBox::Critical);
173 // In this case, we should unlink the created file, since it's not right...
174 unlink(documentName.toAscii().data());
178 setWindowTitle(QString("Architektonas - %1").arg(documentName));
179 statusBar()->showMessage(tr("Drawing saved."));
183 void ApplicationWindow::FileSaveAs(void)
185 QString filename = QFileDialog::getSaveFileName(this, tr("Save Drawing As"),
186 documentName, tr("Architektonas drawings (*.drawing)"));
188 if (!filename.isEmpty())
190 documentName = filename;
196 void ApplicationWindow::SnapToGridTool(void)
198 Object::SetSnapMode(snapToGridAct->isChecked());
202 void ApplicationWindow::FixAngle(void)
204 Object::SetFixedAngle(fixAngleAct->isChecked());
208 void ApplicationWindow::FixLength(void)
210 Object::SetFixedLength(fixLengthAct->isChecked());
214 // We want certain tools to be exclusive, and this approach isn't working correctly...
215 void ApplicationWindow::DeleteTool(void)
217 // For this tool, we check first to see if anything is selected. If so, we
218 // delete those and *don't* select the delete tool.
219 if (drawing->document.ItemsSelected() > 0)
221 drawing->document.DeleteSelectedItems();
223 deleteAct->setChecked(false);
227 // Otherwise, toggle the state of the tool
228 ClearUIToolStatesExcept(deleteAct);
229 SetInternalToolStates();
233 void ApplicationWindow::DimensionTool(void)
235 ClearUIToolStatesExcept(addDimensionAct);
236 SetInternalToolStates();
240 void ApplicationWindow::RotateTool(void)
242 ClearUIToolStatesExcept(rotateAct);
243 SetInternalToolStates();
247 void ApplicationWindow::MirrorTool(void)
249 ClearUIToolStatesExcept(mirrorAct);
250 SetInternalToolStates();
254 void ApplicationWindow::AddLineTool(void)
256 ClearUIToolStatesExcept(addLineAct);
257 SetInternalToolStates();
261 void ApplicationWindow::AddCircleTool(void)
263 ClearUIToolStatesExcept(addCircleAct);
264 SetInternalToolStates();
268 void ApplicationWindow::AddArcTool(void)
270 ClearUIToolStatesExcept(addArcAct);
271 SetInternalToolStates();
275 void ApplicationWindow::AddPolygonTool(void)
277 ClearUIToolStatesExcept(addPolygonAct);
278 SetInternalToolStates();
282 void ApplicationWindow::ZoomInTool(void)
284 double zoomFactor = 2.0;
286 We need to find the center of the screen, then figure out where the new corner
287 will be in the zoomed in window.
289 So we know in Qt coords, the center is found via:
290 size.width() / 2 --> xCenter
291 size.height() / 2 --> yCenter
293 transform x/yCenter to Cartesian coordinates. So far, so good.
295 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
296 (after subtracting from center, that is...)
298 QSize size = drawing->size();
299 Vector center(size.width() / 2.0, size.height() / 2.0);
300 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
301 center = Painter::QtToCartesianCoords(center);
302 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
303 Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
304 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
305 Painter::origin = newOrigin;
307 //printf("Zoom in... level going from %02f to ", Painter::zoom);
308 // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
309 // This should actually be calculated by drawing->gridPixels / grid size.
310 Painter::zoom *= zoomFactor;
311 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
312 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
313 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
314 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
315 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
316 drawing->UpdateGridBackground();
319 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
320 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
324 void ApplicationWindow::ZoomOutTool(void)
329 origin = (223, 160.5)
330 newOrigin should be (-10, -10)
333 center - origin = (213, 150.5)
334 origin - center = (-213, -150.5)
336 + center = (-10, -10)
339 double zoomFactor = 2.0;
340 QSize size = drawing->size();
341 Vector center(size.width() / 2.0, size.height() / 2.0);
342 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
343 center = Painter::QtToCartesianCoords(center);
344 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
345 // Vector newOrigin = (center - Painter::origin) * zoomFactor;
346 // Vector newOrigin = center - (Painter::origin * zoomFactor);
347 Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
348 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
349 Painter::origin = newOrigin;
350 //printf("Zoom out...\n");
351 // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
352 Painter::zoom /= zoomFactor;
353 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
354 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
355 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
356 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
357 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
358 drawing->UpdateGridBackground();
361 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
362 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
366 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
368 if (exception != addArcAct)
369 addArcAct->setChecked(false);
371 if (exception != addCircleAct)
372 addCircleAct->setChecked(false);
374 if (exception != addDimensionAct)
375 addDimensionAct->setChecked(false);
377 if (exception != addLineAct)
378 addLineAct->setChecked(false);
380 if (exception != addPolygonAct)
381 addPolygonAct->setChecked(false);
383 if (exception != deleteAct)
384 deleteAct->setChecked(false);
386 if (exception != rotateAct)
387 rotateAct->setChecked(false);
389 if (exception != mirrorAct)
390 mirrorAct->setChecked(false);
394 void ApplicationWindow::SetInternalToolStates(void)
396 Object::SetDeleteActive(deleteAct->isChecked());
397 Object::SetDimensionActive(addDimensionAct->isChecked());
398 drawing->SetRotateToolActive(rotateAct->isChecked());
400 // We can be sure that if we've come here, then either an active tool is
401 // being deactivated, or a new tool is being created. In either case, the
402 // old tool needs to be deleted.
403 if (drawing->toolAction)
405 delete drawing->toolAction;
406 drawing->toolAction = NULL;
410 drawing->SetAddLineToolActive(addLineAct->isChecked());
411 drawing->SetAddCircleToolActive(addCircleAct->isChecked());
412 drawing->SetAddArcToolActive(addArcAct->isChecked());
413 drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
415 drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL);
416 drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL);
417 drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL);
418 drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
419 drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL);
426 void ApplicationWindow::HelpAbout(void)
432 void ApplicationWindow::Settings(void)
434 SettingsDialog dlg(this);
435 dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
437 if (dlg.exec() == false)
440 // Deal with stuff here (since user hit "OK" button...)
441 drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
447 // Group a bunch of selected objects (which can include other groups) together
448 // or ungroup a selected group.
450 void ApplicationWindow::HandleGrouping(void)
452 int itemsSelected = drawing->document.ItemsSelected();
454 // If nothing selected, do nothing
455 if (itemsSelected == 0)
457 statusBar()->showMessage(tr("No objects selected to make a group from."));
461 // If it's a group that's selected, ungroup it and leave the objects in a
463 if (itemsSelected == 1)
465 Object * object = drawing->document.SelectedItem(0);
469 printf("SelectedItem = NULL!\n");
471 printf("SelectedItem = %08X, type = %i\n", object, object->type);
474 if (object == NULL || object->type != OTContainer)
476 statusBar()->showMessage(tr("A group requires two or more selected objects."));
480 // Need the parent of the group, we're assuming here that the parent is
481 // the drawing's document. Does it matter? Maybe...
482 // Could just stipulate that grouping like this only takes place where the
483 // parent of the group is the drawing's document. Makes life much simpler.
484 ((Container *)object)->SelectAll();
485 ((Container *)object)->MoveContentsTo(&(drawing->document));
486 drawing->document.Delete(object);
487 statusBar()->showMessage(tr("Objects ungrouped."));
489 // Otherwise, if it's a group of 2 or more objects (which can be groups too)
490 // group them and select the group
491 else if (itemsSelected > 1)
493 Container * container = new Container(Vector(), &(drawing->document));
494 drawing->document.MoveSelectedContentsTo(container);
495 drawing->document.Add(container);
496 container->DeselectAll();
497 container->state = OSSelected;
498 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
505 void ApplicationWindow::HandleGridSizeInPixels(int size)
507 drawing->SetGridSize(size);
512 void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
516 double value = text.toDouble(&ok);
518 // Nothing parsable to a double, so quit...
519 if (!ok || value == 0)
522 // drawing->gridSpacing = value;
523 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
524 Object::gridSpacing = value;
525 Painter::zoom = drawing->gridPixels / Object::gridSpacing;
526 drawing->UpdateGridBackground();
531 void ApplicationWindow::HandleDimensionSize(QString text)
535 double value = text.toDouble(&ok);
537 // Nothing parsable to a double, so quit...
538 if (!ok || value == 0)
541 drawing->document.ResizeAllDimensions(value);
542 // drawing->gridSpacing = value;
543 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
544 // drawing->UpdateGridBackground();
549 void ApplicationWindow::CreateActions(void)
551 exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
552 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
553 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
555 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);
556 connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
558 fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
559 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
560 connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
562 fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
563 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
564 connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
566 deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
567 connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
569 addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
570 connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
572 addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
573 connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
575 addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
576 connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
578 addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
579 connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
581 addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
582 connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
584 aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
585 connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
587 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);
588 connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
590 zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
591 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
593 zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
594 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
596 fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/file-new.png"), QKeySequence(tr("Ctrl+n")));
597 connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
599 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")));
600 connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
602 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")));
603 connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
605 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")));
606 connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
608 fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/file-close.png"), QKeySequence(tr("Ctrl+w")));
610 settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/settings.png"), QKeySequence());
611 connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
613 groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
614 connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
616 connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c"));
618 disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d"));
620 mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true);
621 connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool()));
624 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
625 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
626 /* QActionGroup * group = new QActionGroup(this);
627 group->addAction(deleteAct);
628 group->addAction(addDimensionAct);
629 group->addAction(addLineAct);
630 group->addAction(addCircleAct);
631 group->addAction(addArcAct);//*/
636 // Consolidates action creation from a multi-step process to a single-step one.
638 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
639 QIcon icon, QKeySequence key, bool checkable/*= false*/)
641 QAction * action = new QAction(icon, name, this);
642 action->setToolTip(tooltip);
643 action->setStatusTip(statustip);
644 action->setShortcut(key);
645 action->setCheckable(checkable);
652 // This is essentially the same as the previous function, but this allows more
653 // than one key sequence to be added as key shortcuts.
655 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
656 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
658 QAction * action = new QAction(icon, name, this);
659 action->setToolTip(tooltip);
660 action->setStatusTip(statustip);
661 QList<QKeySequence> keyList;
662 keyList.append(key1);
663 keyList.append(key2);
664 action->setShortcuts(keyList);
665 action->setCheckable(checkable);
671 void ApplicationWindow::CreateMenus(void)
673 QMenu * menu = menuBar()->addMenu(tr("&File"));
674 menu->addAction(fileNewAct);
675 menu->addAction(fileOpenAct);
676 menu->addAction(fileSaveAct);
677 menu->addAction(fileSaveAsAct);
678 menu->addAction(fileCloseAct);
679 menu->addSeparator();
680 menu->addAction(exitAct);
682 menu = menuBar()->addMenu(tr("&View"));
683 menu->addAction(zoomInAct);
684 menu->addAction(zoomOutAct);
686 menu = menuBar()->addMenu(tr("&Edit"));
687 menu->addAction(snapToGridAct);
688 menu->addAction(groupAct);
689 menu->addAction(fixAngleAct);
690 menu->addAction(fixLengthAct);
691 menu->addAction(rotateAct);
692 menu->addAction(mirrorAct);
693 menu->addAction(connectAct);
694 menu->addAction(disconnectAct);
695 menu->addSeparator();
696 menu->addAction(deleteAct);
697 menu->addSeparator();
698 menu->addAction(addLineAct);
699 menu->addAction(addCircleAct);
700 menu->addAction(addArcAct);
701 menu->addAction(addPolygonAct);
702 menu->addAction(addDimensionAct);
703 menu->addSeparator();
704 menu->addAction(settingsAct);
706 menu = menuBar()->addMenu(tr("&Help"));
707 menu->addAction(aboutAct);
711 void ApplicationWindow::CreateToolbars(void)
713 QToolBar * toolbar = addToolBar(tr("File"));
714 toolbar->setObjectName("File"); // Needed for saveState()
715 toolbar->addAction(fileNewAct);
716 toolbar->addAction(fileOpenAct);
717 toolbar->addAction(fileSaveAct);
718 toolbar->addAction(fileSaveAsAct);
719 toolbar->addAction(fileCloseAct);
720 // toolbar->addAction(exitAct);
722 toolbar = addToolBar(tr("View"));
723 toolbar->setObjectName("View");
724 toolbar->addAction(zoomInAct);
725 toolbar->addAction(zoomOutAct);
727 QSpinBox * spinbox = new QSpinBox;
728 toolbar->addWidget(spinbox);
729 // QLineEdit * lineedit = new QLineEdit;
730 toolbar->addWidget(baseUnitInput);
731 toolbar->addWidget(dimensionSizeInput);
733 toolbar = addToolBar(tr("Edit"));
734 toolbar->setObjectName("Edit");
735 toolbar->addAction(snapToGridAct);
736 toolbar->addAction(groupAct);
737 toolbar->addAction(fixAngleAct);
738 toolbar->addAction(fixLengthAct);
739 toolbar->addAction(rotateAct);
740 toolbar->addAction(mirrorAct);
741 toolbar->addAction(deleteAct);
742 toolbar->addAction(connectAct);
743 toolbar->addAction(disconnectAct);
744 toolbar->addSeparator();
745 toolbar->addAction(addLineAct);
746 toolbar->addAction(addCircleAct);
747 toolbar->addAction(addArcAct);
748 toolbar->addAction(addPolygonAct);
749 toolbar->addAction(addDimensionAct);
751 spinbox->setRange(4, 256);
752 spinbox->setValue(12);
753 baseUnitInput->setText("12");
754 connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(HandleGridSizeInPixels(int)));
755 connect(baseUnitInput, SIGNAL(textChanged(QString)), this, SLOT(HandleGridSizeInBaseUnits(QString)));
756 connect(dimensionSizeInput, SIGNAL(textChanged(QString)), this, SLOT(HandleDimensionSize(QString)));
760 void ApplicationWindow::ReadSettings(void)
762 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
763 QSize size = settings.value("size", QSize(400, 400)).toSize();
764 drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
765 snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
768 restoreState(settings.value("windowState").toByteArray());
772 void ApplicationWindow::WriteSettings(void)
774 settings.setValue("pos", pos());
775 settings.setValue("size", size());
776 settings.setValue("windowState", saveState());
777 settings.setValue("useAntialiasing", drawing->useAntialiasing);
778 settings.setValue("snapToGrid", snapToGridAct->isChecked());