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