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