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;
413 Object::ignoreClicks = false;
417 drawing->SetAddLineToolActive(addLineAct->isChecked());
418 drawing->SetAddCircleToolActive(addCircleAct->isChecked());
419 drawing->SetAddArcToolActive(addArcAct->isChecked());
420 drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
422 drawing->SetToolActive(addLineAct->isChecked() ? new DrawLineAction() : NULL);
423 drawing->SetToolActive(addCircleAct->isChecked() ? new DrawCircleAction() : NULL);
424 drawing->SetToolActive(addArcAct->isChecked() ? new DrawArcAction() : NULL);
425 drawing->SetToolActive(addDimensionAct->isChecked() ? new DrawDimensionAction() : NULL);
426 drawing->SetToolActive(mirrorAct->isChecked() ? new MirrorAction() : NULL);
429 if (drawing->toolAction)
430 Object::ignoreClicks = true;
436 void ApplicationWindow::HelpAbout(void)
442 void ApplicationWindow::Settings(void)
444 SettingsDialog dlg(this);
445 dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
447 if (dlg.exec() == false)
450 // Deal with stuff here (since user hit "OK" button...)
451 drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
457 // Group a bunch of selected objects (which can include other groups) together
458 // or ungroup a selected group.
460 void ApplicationWindow::HandleGrouping(void)
462 int itemsSelected = drawing->document.ItemsSelected();
464 // If nothing selected, do nothing
465 if (itemsSelected == 0)
467 statusBar()->showMessage(tr("No objects selected to make a group from."));
471 // If it's a group that's selected, ungroup it and leave the objects in a
473 if (itemsSelected == 1)
475 Object * object = drawing->document.SelectedItem(0);
479 printf("SelectedItem = NULL!\n");
481 printf("SelectedItem = %08X, type = %i\n", object, object->type);
484 if (object == NULL || object->type != OTContainer)
486 statusBar()->showMessage(tr("A group requires two or more selected objects."));
490 // Need the parent of the group, we're assuming here that the parent is
491 // the drawing's document. Does it matter? Maybe...
492 // Could just stipulate that grouping like this only takes place where the
493 // parent of the group is the drawing's document. Makes life much simpler.
494 ((Container *)object)->SelectAll();
495 ((Container *)object)->MoveContentsTo(&(drawing->document));
496 drawing->document.Delete(object);
497 statusBar()->showMessage(tr("Objects ungrouped."));
499 // Otherwise, if it's a group of 2 or more objects (which can be groups too)
500 // group them and select the group
501 else if (itemsSelected > 1)
503 Container * container = new Container(Vector(), &(drawing->document));
504 drawing->document.MoveSelectedContentsTo(container);
505 drawing->document.Add(container);
506 container->DeselectAll();
507 container->state = OSSelected;
508 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
515 void ApplicationWindow::HandleGridSizeInPixels(int size)
517 drawing->SetGridSize(size);
522 void ApplicationWindow::HandleGridSizeInBaseUnits(QString text)
526 double value = text.toDouble(&ok);
528 // Nothing parsable to a double, so quit...
529 if (!ok || value == 0)
532 // drawing->gridSpacing = value;
533 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
534 Object::gridSpacing = value;
535 Painter::zoom = drawing->gridPixels / Object::gridSpacing;
536 drawing->UpdateGridBackground();
541 void ApplicationWindow::HandleDimensionSize(QString text)
545 double value = text.toDouble(&ok);
547 // Nothing parsable to a double, so quit...
548 if (!ok || value == 0)
551 drawing->document.ResizeAllDimensions(value);
552 // drawing->gridSpacing = value;
553 // Painter::zoom = drawing->gridPixels / drawing->gridSpacing;
554 // drawing->UpdateGridBackground();
559 void ApplicationWindow::CreateActions(void)
561 exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
562 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
563 connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
565 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);
566 connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
568 fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
569 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
570 connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
572 fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
573 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
574 connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
576 deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
577 connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
579 addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
580 connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
582 addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
583 connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
585 addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
586 connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
588 addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
589 connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
591 addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
592 connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
594 aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
595 connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
597 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);
598 connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
600 zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
601 connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
603 zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
604 connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
606 fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/file-new.png"), QKeySequence(tr("Ctrl+n")));
607 connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
609 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")));
610 connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
612 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")));
613 connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
615 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")));
616 connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
618 fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/file-close.png"), QKeySequence(tr("Ctrl+w")));
620 settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/settings.png"), QKeySequence());
621 connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
623 groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
624 connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
626 connectAct = CreateAction(tr("&Connect"), tr("Connect"), tr("Connect objects at point."), QIcon(":/res/connect-tool.png"), QKeySequence("c,c"));
628 disconnectAct = CreateAction(tr("&Disconnect"), tr("Disconnect"), tr("Disconnect objects joined at point."), QIcon(":/res/disconnect-tool.png"), QKeySequence("d,d"));
630 mirrorAct = CreateAction(tr("&Mirror"), tr("Mirror"), tr("Mirror selected objects around a line."), QIcon(":/res/mirror-tool.png"), QKeySequence("m,i"), true);
631 connect(mirrorAct, SIGNAL(triggered()), this, SLOT(MirrorTool()));
634 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
635 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
636 /* QActionGroup * group = new QActionGroup(this);
637 group->addAction(deleteAct);
638 group->addAction(addDimensionAct);
639 group->addAction(addLineAct);
640 group->addAction(addCircleAct);
641 group->addAction(addArcAct);//*/
646 // Consolidates action creation from a multi-step process to a single-step one.
648 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
649 QIcon icon, QKeySequence key, bool checkable/*= false*/)
651 QAction * action = new QAction(icon, name, this);
652 action->setToolTip(tooltip);
653 action->setStatusTip(statustip);
654 action->setShortcut(key);
655 action->setCheckable(checkable);
662 // This is essentially the same as the previous function, but this allows more
663 // than one key sequence to be added as key shortcuts.
665 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
666 QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
668 QAction * action = new QAction(icon, name, this);
669 action->setToolTip(tooltip);
670 action->setStatusTip(statustip);
671 QList<QKeySequence> keyList;
672 keyList.append(key1);
673 keyList.append(key2);
674 action->setShortcuts(keyList);
675 action->setCheckable(checkable);
681 void ApplicationWindow::CreateMenus(void)
683 QMenu * menu = menuBar()->addMenu(tr("&File"));
684 menu->addAction(fileNewAct);
685 menu->addAction(fileOpenAct);
686 menu->addAction(fileSaveAct);
687 menu->addAction(fileSaveAsAct);
688 menu->addAction(fileCloseAct);
689 menu->addSeparator();
690 menu->addAction(exitAct);
692 menu = menuBar()->addMenu(tr("&View"));
693 menu->addAction(zoomInAct);
694 menu->addAction(zoomOutAct);
696 menu = menuBar()->addMenu(tr("&Edit"));
697 menu->addAction(snapToGridAct);
698 menu->addAction(groupAct);
699 menu->addAction(fixAngleAct);
700 menu->addAction(fixLengthAct);
701 menu->addAction(rotateAct);
702 menu->addAction(mirrorAct);
703 menu->addAction(connectAct);
704 menu->addAction(disconnectAct);
705 menu->addSeparator();
706 menu->addAction(deleteAct);
707 menu->addSeparator();
708 menu->addAction(addLineAct);
709 menu->addAction(addCircleAct);
710 menu->addAction(addArcAct);
711 menu->addAction(addPolygonAct);
712 menu->addAction(addDimensionAct);
713 menu->addSeparator();
714 menu->addAction(settingsAct);
716 menu = menuBar()->addMenu(tr("&Help"));
717 menu->addAction(aboutAct);
721 void ApplicationWindow::CreateToolbars(void)
723 QToolBar * toolbar = addToolBar(tr("File"));
724 toolbar->setObjectName("File"); // Needed for saveState()
725 toolbar->addAction(fileNewAct);
726 toolbar->addAction(fileOpenAct);
727 toolbar->addAction(fileSaveAct);
728 toolbar->addAction(fileSaveAsAct);
729 toolbar->addAction(fileCloseAct);
730 // toolbar->addAction(exitAct);
732 toolbar = addToolBar(tr("View"));
733 toolbar->setObjectName("View");
734 toolbar->addAction(zoomInAct);
735 toolbar->addAction(zoomOutAct);
737 QSpinBox * spinbox = new QSpinBox;
738 toolbar->addWidget(spinbox);
739 // QLineEdit * lineedit = new QLineEdit;
740 toolbar->addWidget(baseUnitInput);
741 toolbar->addWidget(dimensionSizeInput);
743 toolbar = addToolBar(tr("Edit"));
744 toolbar->setObjectName("Edit");
745 toolbar->addAction(snapToGridAct);
746 toolbar->addAction(groupAct);
747 toolbar->addAction(fixAngleAct);
748 toolbar->addAction(fixLengthAct);
749 toolbar->addAction(rotateAct);
750 toolbar->addAction(mirrorAct);
751 toolbar->addAction(deleteAct);
752 toolbar->addAction(connectAct);
753 toolbar->addAction(disconnectAct);
754 toolbar->addSeparator();
755 toolbar->addAction(addLineAct);
756 toolbar->addAction(addCircleAct);
757 toolbar->addAction(addArcAct);
758 toolbar->addAction(addPolygonAct);
759 toolbar->addAction(addDimensionAct);
761 spinbox->setRange(4, 256);
762 spinbox->setValue(12);
763 baseUnitInput->setText("12");
764 connect(spinbox, SIGNAL(valueChanged(int)), this, SLOT(HandleGridSizeInPixels(int)));
765 connect(baseUnitInput, SIGNAL(textChanged(QString)), this, SLOT(HandleGridSizeInBaseUnits(QString)));
766 connect(dimensionSizeInput, SIGNAL(textChanged(QString)), this, SLOT(HandleDimensionSize(QString)));
770 void ApplicationWindow::ReadSettings(void)
772 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
773 QSize size = settings.value("size", QSize(400, 400)).toSize();
774 drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
775 snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
778 restoreState(settings.value("windowState").toByteArray());
782 void ApplicationWindow::WriteSettings(void)
784 settings.setValue("pos", pos());
785 settings.setValue("size", size());
786 settings.setValue("windowState", saveState());
787 settings.setValue("useAntialiasing", drawing->useAntialiasing);
788 settings.setValue("snapToGrid", snapToGridAct->isChecked());