]> Shamusworld >> Repos - architektonas/blob - src/applicationwindow.cpp
246e0bcb874570dc76d507c8bbf03098933fff3b
[architektonas] / src / applicationwindow.cpp
1 //
2 // applicationwindow.cpp: Architektonas
3 //
4 // Part of the Architektonas Project
5 // (C) 2011 Underground Software
6 // See the README and GPLv3 files for licensing and warranty information
7 //
8 // JLH = James Hammons <jlhamm@acm.org>
9 //
10 // Who  When        What
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
15 //
16
17 // FIXED:
18 //
19 //
20 // STILL TO BE DONE:
21 //
22 //
23
24 // Uncomment this for debugging...
25 //#define DEBUG
26 //#define DEBUGFOO                      // Various tool debugging...
27 //#define DEBUGTP                               // Toolpalette debugging...
28
29 #include "applicationwindow.h"
30
31 #include "about.h"
32 #include "blockwidget.h"
33 #include "drawingview.h"
34 #include "fileio.h"
35 #include "generaltab.h"
36 #include "layerwidget.h"
37 #include "painter.h"
38 #include "settingsdialog.h"
39
40
41 ApplicationWindow::ApplicationWindow(): settings("Underground Software", "Architektonas")
42 {
43         drawing = new DrawingView(this);
44         drawing->setMouseTracking(true);                // We want *all* mouse events...!
45         setCentralWidget(drawing);
46
47         aboutWin = new AboutWindow(this);
48
49 //      ((TTEdit *)qApp)->charWnd = new CharWindow(this);
50
51         setWindowIcon(QIcon(":/res/atns-icon.png"));
52         setWindowTitle("Architektonas");
53
54         CreateActions();
55         CreateMenus();
56         CreateToolbars();
57
58         // Create Dock widgets
59         QDockWidget * dock1 = new QDockWidget(tr("Layers"), this);
60         LayerWidget * lw = new LayerWidget;
61         dock1->setWidget(lw);
62         addDockWidget(Qt::RightDockWidgetArea, dock1);
63         QDockWidget * dock2 = new QDockWidget(tr("Blocks"), this);
64         BlockWidget * bw = new BlockWidget;
65         dock2->setWidget(bw);
66         addDockWidget(Qt::RightDockWidgetArea, dock2);
67         // Needed for saveState()
68         dock1->setObjectName("Layers");
69         dock2->setObjectName("Blocks");
70
71         //      Create status bar
72         zoomIndicator = new QLabel("Grid: 12.0\" Zoom: 12.5%");
73         statusBar()->addPermanentWidget(zoomIndicator);
74         statusBar()->showMessage(tr("Ready"));
75
76         ReadSettings();
77         setUnifiedTitleAndToolBarOnMac(true);
78         Object::SetFont(new QFont("Verdana", 15, QFont::Bold));
79 }
80
81
82 void ApplicationWindow::closeEvent(QCloseEvent * event)
83 {
84         WriteSettings();
85         event->accept();                                                        // Use ignore() if can't close for some reason
86         //Do we have a memory leak here if we don't delete the font in the Object???
87 }
88
89
90 void ApplicationWindow::FileNew(void)
91 {
92         // Should warn the user if drawing hasn't been saved...
93         drawing->document.Clear();
94         drawing->update();
95         documentName.clear();
96         setWindowTitle("Architektonas - Untitled");
97         statusBar()->showMessage(tr("New drawing is ready."));
98 }
99
100
101 void ApplicationWindow::FileOpen(void)
102 {
103         QString filename = QFileDialog::getOpenFileName(this, tr("Open Drawing"),
104                 "", tr("Architektonas files (*.drawing)"));
105         FILE * file = fopen(filename.toAscii().data(), "r");
106
107         if (file == 0)
108         {
109                 QMessageBox msg;
110                 msg.setText(QString(tr("Could not open file \"%1\" for loading!")).arg(filename));
111                 msg.setIcon(QMessageBox::Critical);
112                 msg.exec();
113                 return;
114         }
115
116         Container container(Vector(0, 0));
117         bool successful = FileIO::LoadAtnsFile(file, &container);
118         fclose(file);
119
120         if (!successful)
121         {
122                 QMessageBox msg;
123                 msg.setText(QString(tr("Could not load file \"%1\"!")).arg(filename));
124                 msg.setIcon(QMessageBox::Critical);
125                 msg.exec();
126                 return;
127         }
128
129 printf("FileOpen: container size = %li\n", container.objects.size());
130         drawing->document = container;
131         drawing->update();
132         documentName = filename;
133         setWindowTitle(QString("Architektonas - %1").arg(documentName));
134         statusBar()->showMessage(tr("Drawing loaded."));
135 }
136
137
138 void ApplicationWindow::FileSave(void)
139 {
140         if (documentName.isEmpty())
141                 documentName = QFileDialog::getSaveFileName(this, tr("Save Drawing"),
142                         "", tr("Architektonas drawings (*.drawing)"));
143
144         FILE * file = fopen(documentName.toAscii().data(), "w");
145
146         if (file == 0)
147         {
148                 QMessageBox msg;
149                 msg.setText(QString(tr("Could not open file \"%1\" for saving!")).arg(documentName));
150                 msg.setIcon(QMessageBox::Critical);
151                 msg.exec();
152                 return;
153         }
154
155         bool successful = FileIO::SaveAtnsFile(file, &drawing->document);
156         fclose(file);
157
158         if (!successful)
159         {
160                 QMessageBox msg;
161                 msg.setText(QString(tr("Could not save file \"%1\"!")).arg(documentName));
162                 msg.setIcon(QMessageBox::Critical);
163                 msg.exec();
164                 // In this case, we should unlink the created file, since it's not right...
165                 unlink(documentName.toAscii().data());
166                 return;
167         }
168
169         setWindowTitle(QString("Architektonas - %1").arg(documentName));
170         statusBar()->showMessage(tr("Drawing saved."));
171 }
172
173
174 void ApplicationWindow::FileSaveAs(void)
175 {
176         QString filename = QFileDialog::getSaveFileName(this, tr("Save Drawing As"),
177                 documentName, tr("Architektonas drawings (*.drawing)"));
178
179         if (!filename.isEmpty())
180         {
181                 documentName = filename;
182                 FileSave();
183         }
184 }
185
186
187 void ApplicationWindow::SnapToGridTool(void)
188 {
189         Object::SetSnapMode(snapToGridAct->isChecked());
190 }
191
192
193 void ApplicationWindow::FixAngle(void)
194 {
195         Object::SetFixedAngle(fixAngleAct->isChecked());
196 }
197
198
199 void ApplicationWindow::FixLength(void)
200 {
201         Object::SetFixedLength(fixLengthAct->isChecked());
202 }
203
204
205 // We want certain tools to be exclusive, and this approach isn't working correctly...
206 void ApplicationWindow::DeleteTool(void)
207 {
208         // For this tool, we check first to see if anything is selected. If so, we
209         // delete those and *don't* select the delete tool.
210         if (drawing->document.ItemsSelected() > 0)
211         {
212                 drawing->document.DeleteSelectedItems();
213                 drawing->update();
214                 deleteAct->setChecked(false);
215                 return;
216         }
217
218         // Otherwise, toggle the state of the tool
219         ClearUIToolStatesExcept(deleteAct);
220         SetInternalToolStates();
221 }
222
223
224 void ApplicationWindow::DimensionTool(void)
225 {
226         ClearUIToolStatesExcept(addDimensionAct);
227         SetInternalToolStates();
228 }
229
230
231 void ApplicationWindow::RotateTool(void)
232 {
233         ClearUIToolStatesExcept(rotateAct);
234         SetInternalToolStates();
235 }
236
237
238 void ApplicationWindow::AddLineTool(void)
239 {
240         ClearUIToolStatesExcept(addLineAct);
241         SetInternalToolStates();
242 }
243
244
245 void ApplicationWindow::AddCircleTool(void)
246 {
247         ClearUIToolStatesExcept(addCircleAct);
248         SetInternalToolStates();
249 }
250
251
252 void ApplicationWindow::AddArcTool(void)
253 {
254         ClearUIToolStatesExcept(addArcAct);
255         SetInternalToolStates();
256 }
257
258
259 void ApplicationWindow::AddPolygonTool(void)
260 {
261         ClearUIToolStatesExcept(addPolygonAct);
262         SetInternalToolStates();
263 }
264
265
266 void ApplicationWindow::ZoomInTool(void)
267 {
268         double zoomFactor = 2.0;
269 /*
270 We need to find the center of the screen, then figure out where the new corner
271 will be in the zoomed in window.
272
273 So we know in Qt coords, the center is found via:
274 size.width()  / 2 --> xCenter
275 size.height() / 2 --> yCenter
276
277 transform x/yCenter to Cartesian coordinates. So far, so good.
278
279 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
280 (after subtracting from center, that is...)
281 */
282         QSize size = drawing->size();
283         Vector center(size.width() / 2.0, size.height() / 2.0);
284 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
285         center = Painter::QtToCartesianCoords(center);
286 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
287         Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
288 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
289         Painter::origin = newOrigin;
290
291 //printf("Zoom in... level going from %02f to ", Painter::zoom);
292         // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
293         Painter::zoom *= zoomFactor;
294         drawing->gridSpacing = 12.0 / Painter::zoom;
295 //      zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
296         zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
297         drawing->UpdateGridBackground();
298         drawing->update();
299 }
300
301
302 void ApplicationWindow::ZoomOutTool(void)
303 {
304 /*
305 Ok, real example.
306 center = (436, 311)
307 origin = (223, 160.5)
308 newOrigin should be (-10, -10)
309 Why isn't it?
310
311 center - origin = (213, 150.5)
312 origin - center = (-213, -150.5)
313 x 2 = (-426, -301)
314 + center = (-10, -10)
315
316 */
317         double zoomFactor = 2.0;
318         QSize size = drawing->size();
319         Vector center(size.width() / 2.0, size.height() / 2.0);
320 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
321         center = Painter::QtToCartesianCoords(center);
322 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
323 //      Vector newOrigin = (center - Painter::origin) * zoomFactor;
324 //      Vector newOrigin = center - (Painter::origin * zoomFactor);
325         Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
326 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
327         Painter::origin = newOrigin;
328 //printf("Zoom out...\n");
329         // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
330         Painter::zoom /= zoomFactor;
331         drawing->gridSpacing = 12.0 / Painter::zoom;
332 //      zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
333         zoomIndicator->setText(QString("Grid: %1\", BU: Inch").arg(drawing->gridSpacing));
334         drawing->UpdateGridBackground();
335         drawing->update();
336 }
337
338
339 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
340 {
341         if (exception != addArcAct)
342                 addArcAct->setChecked(false);
343
344         if (exception != addCircleAct)
345                 addCircleAct->setChecked(false);
346
347         if (exception != addDimensionAct)
348                 addDimensionAct->setChecked(false);
349
350         if (exception != addLineAct)
351                 addLineAct->setChecked(false);
352
353         if (exception != addPolygonAct)
354                 addPolygonAct->setChecked(false);
355
356         if (exception != deleteAct)
357                 deleteAct->setChecked(false);
358
359         if (exception != rotateAct)
360                 rotateAct->setChecked(false);
361 }
362
363
364 void ApplicationWindow::SetInternalToolStates(void)
365 {
366         Object::SetDeleteActive(deleteAct->isChecked());
367         Object::SetDimensionActive(addDimensionAct->isChecked());
368         drawing->SetRotateToolActive(rotateAct->isChecked());
369
370         // We can be sure that if we've come here, then either an active tool is
371         // being deactivated, or a new tool is being created. In either case, the
372         // old tool needs to be deleted.
373         if (drawing->toolAction)
374         {
375                 delete drawing->toolAction;
376                 drawing->toolAction = NULL;
377         }
378
379         drawing->SetAddLineToolActive(addLineAct->isChecked());
380         drawing->SetAddCircleToolActive(addCircleAct->isChecked());
381         drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
382 }
383
384
385 void ApplicationWindow::HelpAbout(void)
386 {
387         aboutWin->show();
388 }
389
390
391 void ApplicationWindow::Settings(void)
392 {
393         SettingsDialog dlg(this);
394         dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
395
396         if (dlg.exec() == false)
397                 return;
398
399         // Deal with stuff here (since user hit "OK" button...)
400         drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
401         WriteSettings();
402 }
403
404
405 //
406 // Group a bunch of selected objects (which can include other groups) together
407 // or ungroup a selected group.
408 //
409 void ApplicationWindow::HandleGrouping(void)
410 {
411         int itemsSelected = drawing->document.ItemsSelected();
412
413         // If nothing selected, do nothing
414         if (itemsSelected == 0)
415         {
416                 statusBar()->showMessage(tr("No objects selected to make a group from."));
417                 return;
418         }
419
420         // If it's a group that's selected, ungroup it and leave the objects in a
421         // selected state
422         if (itemsSelected == 1)
423         {
424                 Object * object = drawing->document.SelectedItem(0);
425
426 #if 0
427 if (object == NULL)
428         printf("SelectedItem = NULL!\n");
429 else
430         printf("SelectedItem = %08X, type = %i\n", object, object->type);
431 #endif
432
433                 if (object == NULL || object->type != OTContainer)
434                 {
435                         statusBar()->showMessage(tr("A group requires two or more selected objects."));
436                         return;
437                 }
438
439                 // Need the parent of the group, we're assuming here that the parent is
440                 // the drawing's document. Does it matter? Maybe...
441                 // Could just stipulate that grouping like this only takes place where the
442                 // parent of the group is the drawing's document. Makes life much simpler.
443                 ((Container *)object)->SelectAll();
444                 ((Container *)object)->MoveContentsTo(&(drawing->document));
445                 drawing->document.Delete(object);
446                 statusBar()->showMessage(tr("Objects ungrouped."));
447         }
448         // Otherwise, if it's a group of 2 or more objects (which can be groups too)
449         // group them and select the group
450         else if (itemsSelected > 1)
451         {
452                 Container * container = new Container(Vector(), &(drawing->document));
453                 drawing->document.MoveSelectedContentsTo(container);
454                 drawing->document.Add(container);
455                 container->DeselectAll();
456                 container->state = OSSelected;
457                 statusBar()->showMessage(QString(tr("Grouped %1 objects.")).arg(itemsSelected));
458         }
459
460         drawing->update();
461 }
462
463
464 void ApplicationWindow::CreateActions(void)
465 {
466         exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
467                 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
468         connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
469
470         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);
471         connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
472
473         fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
474                 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
475         connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
476
477         fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
478                 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
479         connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
480
481         deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(tr("Delete")), true);
482         connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
483
484         addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
485         connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
486
487         addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
488         connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
489
490         addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
491         connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
492
493         addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
494         connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
495
496         addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
497         connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
498
499         aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
500         connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
501
502         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);
503         connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
504
505         zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
506         connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
507
508         zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
509         connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
510
511         fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+n")));
512         connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
513
514         fileOpenAct = CreateAction(tr("&Open Drawing"), tr("Open Drawing"), tr("Opens an existing drawing from a file."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+o")));
515         connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
516
517         fileSaveAct = CreateAction(tr("&Save Drawing"), tr("Save Drawing"), tr("Saves the current drawing to a file."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+s")));
518         connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
519
520         fileSaveAsAct = CreateAction(tr("Save Drawing &As"), tr("Save As"), tr("Saves the current drawing to a file with a different name."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+Shift+s")));
521         connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
522
523         fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+w")));
524
525         settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/generic-tool.png"), QKeySequence());
526         connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
527
528         groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/group-tool.png"), QKeySequence("g"));
529         connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
530
531 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
532 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
533 /*      QActionGroup * group = new QActionGroup(this);
534         group->addAction(deleteAct);
535         group->addAction(addDimensionAct);
536         group->addAction(addLineAct);
537         group->addAction(addCircleAct);
538         group->addAction(addArcAct);//*/
539 }
540
541
542 //
543 // Consolidates action creation from a multi-step process to a single-step one.
544 //
545 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
546         QIcon icon, QKeySequence key, bool checkable/*= false*/)
547 {
548         QAction * action = new QAction(icon, name, this);
549         action->setToolTip(tooltip);
550         action->setStatusTip(statustip);
551         action->setShortcut(key);
552         action->setCheckable(checkable);
553
554         return action;
555 }
556
557
558 //
559 // This is essentially the same as the previous function, but this allows more
560 // than one key sequence to be added as key shortcuts.
561 //
562 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
563         QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
564 {
565         QAction * action = new QAction(icon, name, this);
566         action->setToolTip(tooltip);
567         action->setStatusTip(statustip);
568         QList<QKeySequence> keyList;
569         keyList.append(key1);
570         keyList.append(key2);
571         action->setShortcuts(keyList);
572         action->setCheckable(checkable);
573
574         return action;
575 }
576
577
578 void ApplicationWindow::CreateMenus(void)
579 {
580         QMenu * menu = menuBar()->addMenu(tr("&File"));
581         menu->addAction(fileNewAct);
582         menu->addAction(fileOpenAct);
583         menu->addAction(fileSaveAct);
584         menu->addAction(fileSaveAsAct);
585         menu->addAction(fileCloseAct);
586         menu->addSeparator();
587         menu->addAction(exitAct);
588
589         menu = menuBar()->addMenu(tr("&View"));
590         menu->addAction(zoomInAct);
591         menu->addAction(zoomOutAct);
592
593         menu = menuBar()->addMenu(tr("&Edit"));
594         menu->addAction(snapToGridAct);
595         menu->addAction(groupAct);
596         menu->addAction(fixAngleAct);
597         menu->addAction(fixLengthAct);
598         menu->addAction(rotateAct);
599         menu->addSeparator();
600         menu->addAction(deleteAct);
601         menu->addSeparator();
602         menu->addAction(addLineAct);
603         menu->addAction(addCircleAct);
604         menu->addAction(addArcAct);
605         menu->addAction(addPolygonAct);
606         menu->addAction(addDimensionAct);
607         menu->addSeparator();
608         menu->addAction(settingsAct);
609
610         menu = menuBar()->addMenu(tr("&Help"));
611         menu->addAction(aboutAct);
612 }
613
614
615 void ApplicationWindow::CreateToolbars(void)
616 {
617         QToolBar * toolbar = addToolBar(tr("File"));
618         toolbar->setObjectName("File"); // Needed for saveState()
619         toolbar->addAction(exitAct);
620
621         toolbar = addToolBar(tr("View"));
622         toolbar->setObjectName("View");
623         toolbar->addAction(zoomInAct);
624         toolbar->addAction(zoomOutAct);
625
626         toolbar = addToolBar(tr("Edit"));
627         toolbar->setObjectName("Edit");
628         toolbar->addAction(snapToGridAct);
629         toolbar->addAction(groupAct);
630         toolbar->addAction(fixAngleAct);
631         toolbar->addAction(fixLengthAct);
632         toolbar->addAction(rotateAct);
633         toolbar->addAction(deleteAct);
634         toolbar->addSeparator();
635         toolbar->addAction(addLineAct);
636         toolbar->addAction(addCircleAct);
637         toolbar->addAction(addArcAct);
638         toolbar->addAction(addPolygonAct);
639         toolbar->addAction(addDimensionAct);
640 }
641
642
643 void ApplicationWindow::ReadSettings(void)
644 {
645         QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
646         QSize size = settings.value("size", QSize(400, 400)).toSize();
647         drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
648         snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
649         resize(size);
650         move(pos);
651         restoreState(settings.value("windowState").toByteArray());
652 //      pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
653 //      size = settings.value("charWndSize", QSize(200, 200)).toSize();
654 //      ((TTEdit *)qApp)->charWnd->resize(size);
655 //      ((TTEdit *)qApp)->charWnd->move(pos);
656 }
657
658
659 void ApplicationWindow::WriteSettings(void)
660 {
661         settings.setValue("pos", pos());
662         settings.setValue("size", size());
663         settings.setValue("windowState", saveState());
664         settings.setValue("useAntialiasing", drawing->useAntialiasing);
665         settings.setValue("snapToGrid", snapToGridAct->isChecked());
666 //      settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos());
667 //      settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size());
668 }
669