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"
47 DrawingView * ApplicationWindow::drawing;
50 ApplicationWindow::ApplicationWindow():
51 baseUnitInput(new QLineEdit),
52 dimensionSizeInput(new QLineEdit),
53 settings("Underground Software", "Architektonas")
55 drawing = new DrawingView(this);
56 drawing->setMouseTracking(true); // We want *all* mouse events...!
57 drawing->setFocusPolicy(Qt::StrongFocus);
58 setCentralWidget(drawing);
60 aboutWin = new AboutWindow(this);
62 // ((TTEdit *)qApp)->charWnd = new CharWindow(this);
64 setWindowIcon(QIcon(":/res/atns-icon.png"));
65 setWindowTitle("Architektonas");
71 // Create Dock widgets
72 QDockWidget * dock1 = new QDockWidget(tr("Layers"), this);
73 LayerWidget * lw = new LayerWidget;
75 addDockWidget(Qt::RightDockWidgetArea, dock1);
76 QDockWidget * dock2 = new QDockWidget(tr("Blocks"), this);
77 BlockWidget * bw = new BlockWidget;
79 addDockWidget(Qt::RightDockWidgetArea, dock2);
80 // Needed for saveState()
81 dock1->setObjectName("Layers");
82 dock2->setObjectName("Blocks");
85 zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
86 statusBar()->addPermanentWidget(zoomIndicator);
87 statusBar()->showMessage(tr("Ready"));
90 setUnifiedTitleAndToolBarOnMac(true);
91 Object::SetFont(new QFont("Verdana", 15, QFont::Bold));
93 connect(lw, SIGNAL(LayerSelected(int)), drawing, SLOT(SetCurrentLayer(int)));
97 void ApplicationWindow::closeEvent(QCloseEvent * event)
100 event->accept(); // Use ignore() if can't close for some reason
101 //Do we have a memory leak here if we don't delete the font in the Object???
105 void ApplicationWindow::FileNew(void)
107 // Should warn the user if drawing hasn't been saved...
108 drawing->document.Clear();
110 documentName.clear();
111 setWindowTitle("Architektonas - Untitled");
112 statusBar()->showMessage(tr("New drawing is ready."));
116 void ApplicationWindow::FileOpen(void)
118 QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
119 "", tr("Architektonas files (*.drawing)"));
120 FILE * file = fopen(filename.toAscii().data(), "r");
125 msg.setText(QString(tr("Could not open file \"%1\" for loading!")).arg(filename));
126 msg.setIcon(QMessageBox::Critical);
131 Container container(Vector(0, 0));
132 bool successful = FileIO::LoadAtnsFile(file, &container);
138 msg.setText(QString(tr("Could not load file \"%1\"!")).arg(filename));
139 msg.setIcon(QMessageBox::Critical);
144 printf("FileOpen: container size = %li\n", container.objects.size());
145 drawing->document = container;
147 documentName = filename;
148 setWindowTitle(QString("Architektonas - %1").arg(documentName));
149 statusBar()->showMessage(tr("Drawing loaded."));
153 void ApplicationWindow::FileSave(void)
155 if (documentName.isEmpty())
156 documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"),
157 "", tr("Architektonas drawings (*.drawing)"));
159 FILE * file = fopen(documentName.toAscii().data(), "w");
164 msg.setText(QString(tr("Could not open file \"%1\" for saving!")).arg(documentName));
165 msg.setIcon(QMessageBox::Critical);
170 bool successful = FileIO::SaveAtnsFile(file, &drawing->document);
176 msg.setText(QString(tr("Could not save file \"%1\"!")).arg(documentName));
177 msg.setIcon(QMessageBox::Critical);
179 // In this case, we should unlink the created file, since it's not right...
180 unlink(documentName.toAscii().data());
184 setWindowTitle(QString("Architektonas - %1").arg(documentName));
185 statusBar()->showMessage(tr("Drawing saved."));
189 void ApplicationWindow::FileSaveAs(void)
191 QString filename = QFileDialog::getSaveFileName(this, tr("Save Drawing As"),
192 documentName, tr("Architektonas drawings (*.drawing)"));
194 if (!filename.isEmpty())
196 documentName = filename;
202 void ApplicationWindow::SnapToGridTool(void)
204 Object::SetSnapMode(snapToGridAct->isChecked());
208 void ApplicationWindow::FixAngle(void)
210 Object::SetFixedAngle(fixAngleAct->isChecked());
214 void ApplicationWindow::FixLength(void)
216 Object::SetFixedLength(fixLengthAct->isChecked());
220 // We want certain tools to be exclusive, and this approach isn't working correctly...
221 void ApplicationWindow::DeleteTool(void)
223 // For this tool, we check first to see if anything is selected. If so, we
224 // delete those and *don't* select the delete tool.
225 if (drawing->document.ItemsSelected() > 0)
227 drawing->document.DeleteSelectedItems();
229 deleteAct->setChecked(false);
233 // Otherwise, toggle the state of the tool
234 ClearUIToolStatesExcept(deleteAct);
235 SetInternalToolStates();
239 void ApplicationWindow::DimensionTool(void)
241 ClearUIToolStatesExcept(addDimensionAct);
242 SetInternalToolStates();
246 void ApplicationWindow::RotateTool(void)
248 ClearUIToolStatesExcept(rotateAct);
249 SetInternalToolStates();
253 void ApplicationWindow::MirrorTool(void)
255 ClearUIToolStatesExcept(mirrorAct);
256 SetInternalToolStates();
260 void ApplicationWindow::AddLineTool(void)
262 ClearUIToolStatesExcept(addLineAct);
263 SetInternalToolStates();
267 void ApplicationWindow::AddCircleTool(void)
269 ClearUIToolStatesExcept(addCircleAct);
270 SetInternalToolStates();
274 void ApplicationWindow::AddArcTool(void)
276 ClearUIToolStatesExcept(addArcAct);
277 SetInternalToolStates();
281 void ApplicationWindow::AddPolygonTool(void)
283 ClearUIToolStatesExcept(addPolygonAct);
284 SetInternalToolStates();
288 void ApplicationWindow::ZoomInTool(void)
290 double zoomFactor = 2.0;
292 We need to find the center of the screen, then figure out where the new corner
293 will be in the zoomed in window.
295 So we know in Qt coords, the center is found via:
296 size.width() / 2 --> xCenter
297 size.height() / 2 --> yCenter
299 transform x/yCenter to Cartesian coordinates. So far, so good.
301 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
302 (after subtracting from center, that is...)
304 QSize size = drawing->size();
305 Vector center(size.width() / 2.0, size.height() / 2.0);
306 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
307 center = Painter::QtToCartesianCoords(center);
308 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
309 Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
310 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
311 Painter::origin = newOrigin;
313 //printf("Zoom in... level going from %02f to ", Painter::zoom);
314 // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
315 // This should actually be calculated by drawing->gridPixels / grid size.
316 Painter::zoom *= zoomFactor;
317 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
318 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
319 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
320 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
321 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
322 drawing->UpdateGridBackground();
325 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
326 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
330 void ApplicationWindow::ZoomOutTool(void)
335 origin = (223, 160.5)
336 newOrigin should be (-10, -10)
339 center - origin = (213, 150.5)
340 origin - center = (-213, -150.5)
342 + center = (-10, -10)
345 double zoomFactor = 2.0;
346 QSize size = drawing->size();
347 Vector center(size.width() / 2.0, size.height() / 2.0);
348 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
349 center = Painter::QtToCartesianCoords(center);
350 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
351 // Vector newOrigin = (center - Painter::origin) * zoomFactor;
352 // Vector newOrigin = center - (Painter::origin * zoomFactor);
353 Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
354 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
355 Painter::origin = newOrigin;
356 //printf("Zoom out...\n");
357 // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
358 Painter::zoom /= zoomFactor;
359 // drawing->gridSpacing = drawing->gridPixels / Painter::zoom;
360 Object::gridSpacing = drawing->gridPixels / Painter::zoom;
361 // zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
362 // zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
363 zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(Object::gridSpacing));
364 drawing->UpdateGridBackground();
367 // baseUnitInput->setText(QString("%1").arg(drawing->gridSpacing));
368 baseUnitInput->setText(QString("%1").arg(Object::gridSpacing));
372 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
374 if (exception != addArcAct)
375 addArcAct->setChecked(false);
377 if (exception != addCircleAct)
378 addCircleAct->setChecked(false);
380 if (exception != addDimensionAct)
381 addDimensionAct->setChecked(false);
383 if (exception != addLineAct)
384 addLineAct->setChecked(false);
386 if (exception != addPolygonAct)
387 addPolygonAct->setChecked(false);
389 if (exception != deleteAct)
390 deleteAct->setChecked(false);
392 if (exception != rotateAct)
393 rotateAct->setChecked(false);
395 if (exception != mirrorAct)
396 mirrorAct->setChecked(false);
400 void ApplicationWindow::SetInternalToolStates(void)
402 Object::SetDeleteActive(deleteAct->isChecked());
403 Object::SetDimensionActive(addDimensionAct->isChecked());
404 drawing->SetRotateToolActive(rotateAct->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;
416 drawing->SetAddLineToolActive(addLineAct->isChecked());
417 drawing->SetAddCircleToolActive(addCircleAct->isChecked());
418 drawing->SetAddArcToolActive(addArcAct->isChecked());
419 drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
421 drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL);
422 drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL);
423 drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL);
424 drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
425 drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL);
432 void ApplicationWindow::HelpAbout(void)
438 void ApplicationWindow::Settings(void)
440 SettingsDialog dlg(this);
441 dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
443 if (dlg.exec() == false)
446 // Deal with stuff here (since user hit "OK" button...)
447 drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
453 // Group a bunch of selected objects (which can include other groups) together
454 // or ungroup a selected group.
456 void ApplicationWindow::HandleGrouping(void)
458 int itemsSelected = drawing->document.ItemsSelected();
460 // If nothing selected, do nothing
461 if (itemsSelected == 0)
463 statusBar()->showMessage(tr("No objects selected to make a group from."));
467 // If it's a group that's selected, ungroup it and leave the objects in a
469 if (itemsSelected == 1)
471 Object * object = drawing->document.SelectedItem(0);
475 printf("SelectedItem = NULL!\n");
477 printf("SelectedItem = %08X, type = %i\n", object, object->type);
480 if (object == NULL || object->type != OTContainer)
482 statusBar()->showMessage(tr("A group requires two or more selected objects."));
486 // Need the parent of the group, we're assuming here that the parent is
487 // the drawing's document. Does it matter? Maybe...
488 // Could just stipulate that grouping like this only takes place where the
489 // parent of the group is the drawing's document. Makes life much simpler.
490 ((Container *)object)->SelectAll();
491 ((Container *)object)->MoveContentsTo(&(drawing->document));
492 drawing->document.Delete(object);
493 statusBar()->showMessage(tr("Objects ungrouped."));
495 // Otherwise, if it's a group of 2 or more objects (which can be groups too)
496 // group them and select the group
497 else if (itemsSelected > 1)
499 Container * container = new Container(Vector(), &(drawing->document));
500 drawing->document.MoveSelectedContentsTo(container);
501 drawing->document.Add(container);
502 container->DeselectAll();
503 container->state = OSSelected;
504 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
511 void ApplicationWindow::HandleGridSizeInPixels(int size)
513 drawing->SetGridSize(size);
518 void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
522 double value = text.toDouble(&ok);
524 // Nothing parsable to a double, so quit...
525 if (!ok || value == 0)
528 // drawing->gridSpacing = value;
529 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
530 Object::gridSpacing = value;
531 Painter::zoom = drawing->gridPixels / Object::gridSpacing;
532 drawing->UpdateGridBackground();
537 void ApplicationWindow::HandleDimensionSize(QString text)
541 double value = text.toDouble(&ok);
543 // Nothing parsable to a double, so quit...
544 if (!ok || value == 0)
547 drawing->document.ResizeAllDimensions(value);
548 // drawing->gridSpacing = value;
549 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
550 // drawing->UpdateGridBackground();
555 void ApplicationWindow::CreateActions(void)
557 exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
558 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
559 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
561 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);
562 connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
564 fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
565 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
566 connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
568 fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
569 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
570 connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
572 deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
573 connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
575 addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
576 connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
578 addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
579 connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
581 addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
582 connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
584 addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
585 connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
587 addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
588 connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
590 aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
591 connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
593 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);
594 connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
596 zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
597 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
599 zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
600 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
602 fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/file-new.png"), QKeySequence(tr("Ctrl+n")));
603 connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
605 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")));
606 connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
608 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")));
609 connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
611 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")));
612 connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
614 fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/file-close.png"), QKeySequence(tr("Ctrl+w")));
616 settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/settings.png"), QKeySequence());
617 connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
619 groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
620 connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
622 connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c"));
624 disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d"));
626 mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true);
627 connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool()));
630 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
631 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
632 /* QActionGroup * group = new QActionGroup(this);
633 group->addAction(deleteAct);
634 group->addAction(addDimensionAct);
635 group->addAction(addLineAct);
636 group->addAction(addCircleAct);
637 group->addAction(addArcAct);//*/
642 // Consolidates action creation from a multi-step process to a single-step one.
644 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
645 QIcon icon, QKeySequence key, bool checkable/*= false*/)
647 QAction * action = new QAction(icon, name, this);
648 action->setToolTip(tooltip);
649 action->setStatusTip(statustip);
650 action->setShortcut(key);
651 action->setCheckable(checkable);
658 // This is essentially the same as the previous function, but this allows more
659 // than one key sequence to be added as key shortcuts.
661 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
662 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
664 QAction * action = new QAction(icon, name, this);
665 action->setToolTip(tooltip);
666 action->setStatusTip(statustip);
667 QList<QKeySequence> keyList;
668 keyList.append(key1);
669 keyList.append(key2);
670 action->setShortcuts(keyList);
671 action->setCheckable(checkable);
677 void ApplicationWindow::CreateMenus(void)
679 QMenu * menu = menuBar()->addMenu(tr("&File"));
680 menu->addAction(fileNewAct);
681 menu->addAction(fileOpenAct);
682 menu->addAction(fileSaveAct);
683 menu->addAction(fileSaveAsAct);
684 menu->addAction(fileCloseAct);
685 menu->addSeparator();
686 menu->addAction(exitAct);
688 menu = menuBar()->addMenu(tr("&View"));
689 menu->addAction(zoomInAct);
690 menu->addAction(zoomOutAct);
692 menu = menuBar()->addMenu(tr("&Edit"));
693 menu->addAction(snapToGridAct);
694 menu->addAction(groupAct);
695 menu->addAction(fixAngleAct);
696 menu->addAction(fixLengthAct);
697 menu->addAction(rotateAct);
698 menu->addAction(mirrorAct);
699 menu->addAction(connectAct);
700 menu->addAction(disconnectAct);
701 menu->addSeparator();
702 menu->addAction(deleteAct);
703 menu->addSeparator();
704 menu->addAction(addLineAct);
705 menu->addAction(addCircleAct);
706 menu->addAction(addArcAct);
707 menu->addAction(addPolygonAct);
708 menu->addAction(addDimensionAct);
709 menu->addSeparator();
710 menu->addAction(settingsAct);
712 menu = menuBar()->addMenu(tr("&Help"));
713 menu->addAction(aboutAct);
717 void ApplicationWindow::CreateToolbars(void)
719 QToolBar * toolbar = addToolBar(tr("File"));
720 toolbar->setObjectName("File"); // Needed for saveState()
721 toolbar->addAction(fileNewAct);
722 toolbar->addAction(fileOpenAct);
723 toolbar->addAction(fileSaveAct);
724 toolbar->addAction(fileSaveAsAct);
725 toolbar->addAction(fileCloseAct);
726 // toolbar->addAction(exitAct);
728 toolbar = addToolBar(tr("View"));
729 toolbar->setObjectName("View");
730 toolbar->addAction(zoomInAct);
731 toolbar->addAction(zoomOutAct);
733 QSpinBox * spinbox = new QSpinBox;
734 toolbar->addWidget(spinbox);
735 // QLineEdit * lineedit = new QLineEdit;
736 toolbar->addWidget(baseUnitInput);
737 toolbar->addWidget(dimensionSizeInput);
739 toolbar = addToolBar(tr("Edit"));
740 toolbar->setObjectName("Edit");
741 toolbar->addAction(snapToGridAct);
742 toolbar->addAction(groupAct);
743 toolbar->addAction(fixAngleAct);
744 toolbar->addAction(fixLengthAct);
745 toolbar->addAction(rotateAct);
746 toolbar->addAction(mirrorAct);
747 toolbar->addAction(deleteAct);
748 toolbar->addAction(connectAct);
749 toolbar->addAction(disconnectAct);
750 toolbar->addSeparator();
751 toolbar->addAction(addLineAct);
752 toolbar->addAction(addCircleAct);
753 toolbar->addAction(addArcAct);
754 toolbar->addAction(addPolygonAct);
755 toolbar->addAction(addDimensionAct);
757 spinbox->setRange(4, 256);
758 spinbox->setValue(12);
759 baseUnitInput->setText("12");
760 connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(HandleGridSizeInPixels(int)));
761 connect(baseUnitInput, SIGNAL(textChanged(QString)), this, SLOT(HandleGridSizeInBaseUnits(QString)));
762 connect(dimensionSizeInput, SIGNAL(textChanged(QString)), this, SLOT(HandleDimensionSize(QString)));
766 void ApplicationWindow::ReadSettings(void)
768 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
769 QSize size = settings.value("size", QSize(400, 400)).toSize();
770 drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
771 snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
774 restoreState(settings.value("windowState").toByteArray());
778 void ApplicationWindow::WriteSettings(void)
780 settings.setValue("pos", pos());
781 settings.setValue("size", size());
782 settings.setValue("windowState", saveState());
783 settings.setValue("useAntialiasing", drawing->useAntialiasing);
784 settings.setValue("snapToGrid", snapToGridAct->isChecked());