]> Shamusworld >> Repos - architektonas/blob - src/applicationwindow.cpp
Fix tool handling and circle highlighting.
[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         
201         ClearUIToolStatesExcept(deleteAct);
202         SetInternalToolStates();
203 }
204
205
206 void ApplicationWindow::DimensionTool(void)
207 {
208         ClearUIToolStatesExcept(addDimensionAct);
209         SetInternalToolStates();
210 }
211
212
213 void ApplicationWindow::RotateTool(void)
214 {
215         ClearUIToolStatesExcept(rotateAct);
216         SetInternalToolStates();
217 }
218
219
220 void ApplicationWindow::AddLineTool(void)
221 {
222         ClearUIToolStatesExcept(addLineAct);
223         SetInternalToolStates();
224 }
225
226
227 void ApplicationWindow::AddCircleTool(void)
228 {
229         ClearUIToolStatesExcept(addCircleAct);
230         SetInternalToolStates();
231 }
232
233
234 void ApplicationWindow::AddArcTool(void)
235 {
236         ClearUIToolStatesExcept(addArcAct);
237         SetInternalToolStates();
238 }
239
240
241 void ApplicationWindow::AddPolygonTool(void)
242 {
243         ClearUIToolStatesExcept(addPolygonAct);
244         SetInternalToolStates();
245 }
246
247
248 void ApplicationWindow::ZoomInTool(void)
249 {
250         double zoomFactor = 2.0;
251 /*
252 We need to find the center of the screen, then figure out where the new corner
253 will be in the zoomed in window.
254
255 So we know in Qt coords, the center is found via:
256 size.width()  / 2 --> xCenter
257 size.height() / 2 --> yCenter
258
259 transform x/yCenter to Cartesian coordinates. So far, so good.
260
261 when zooming in, new origin will be (xCenter - origin.x) / 2, (yCenter - origin.y) / 2
262 (after subtracting from center, that is...)
263 */
264         QSize size = drawing->size();
265         Vector center(size.width() / 2.0, size.height() / 2.0);
266 //printf("Zoom in... Center=%.2f,%.2f; ", center.x, center.y);
267         center = Painter::QtToCartesianCoords(center);
268 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
269         Vector newOrigin = center - ((center - Painter::origin) / zoomFactor);
270 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
271         Painter::origin = newOrigin;
272
273 //printf("Zoom in... level going from %02f to ", Painter::zoom);
274         // This just zooms leaving origin intact... should zoom in at the current center! [DONE]
275         Painter::zoom *= zoomFactor;
276         drawing->gridSpacing = 12.0 / Painter::zoom;
277         zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
278         drawing->UpdateGridBackground();
279         drawing->update();
280 }
281
282
283 void ApplicationWindow::ZoomOutTool(void)
284 {
285 /*
286 Ok, real example.
287 center = (436, 311)
288 origin = (223, 160.5)
289 newOrigin should be (-10, -10)
290 Why isn't it?
291
292 center - origin = (213, 150.5)
293 origin - center = (-213, -150.5)
294 x 2 = (-426, -301)
295 + center = (-10, -10)
296
297 */
298         double zoomFactor = 2.0;
299         QSize size = drawing->size();
300         Vector center(size.width() / 2.0, size.height() / 2.0);
301 //printf("Zoom out... Center=%.2f,%.2f; ", center.x, center.y);
302         center = Painter::QtToCartesianCoords(center);
303 //printf("(%.2f,%.2f); origin=%.2f,%.2f; ", center.x, center.y, Painter::origin.x, Painter::origin.y);
304 //      Vector newOrigin = (center - Painter::origin) * zoomFactor;
305 //      Vector newOrigin = center - (Painter::origin * zoomFactor);
306         Vector newOrigin = center + ((Painter::origin - center) * zoomFactor);
307 //printf("newOrigin=%.2f,%.2f;\n", newOrigin.x, newOrigin.y);
308         Painter::origin = newOrigin;
309 //printf("Zoom out...\n");
310         // This just zooms leaving origin intact... should zoom out at the current center! [DONE]
311         Painter::zoom /= zoomFactor;
312         drawing->gridSpacing = 12.0 / Painter::zoom;
313         zoomIndicator->setText(QString("Grid: %2\" Zoom: %1%").arg(Painter::zoom * 100.0 * SCREEN_ZOOM).arg(drawing->gridSpacing));
314         drawing->UpdateGridBackground();
315         drawing->update();
316 }
317
318
319 void ApplicationWindow::ClearUIToolStatesExcept(QAction * exception)
320 {
321         if (exception != addArcAct)
322                 addArcAct->setChecked(false);
323
324         if (exception != addCircleAct)
325                 addCircleAct->setChecked(false);
326
327         if (exception != addDimensionAct)
328                 addDimensionAct->setChecked(false);
329
330         if (exception != addLineAct)
331                 addLineAct->setChecked(false);
332
333         if (exception != addPolygonAct)
334                 addPolygonAct->setChecked(false);
335
336         if (exception != deleteAct)
337                 deleteAct->setChecked(false);
338
339         if (exception != rotateAct)
340                 rotateAct->setChecked(false);
341 }
342
343
344 void ApplicationWindow::SetInternalToolStates(void)
345 {
346         Object::SetDeleteActive(deleteAct->isChecked());
347         Object::SetDimensionActive(addDimensionAct->isChecked());
348         drawing->SetRotateToolActive(rotateAct->isChecked());
349
350         // We can be sure that if we've come here, then either an active tool is
351         // being deactivated, or a new tool is being created. In either case, the
352         // old tool needs to be deleted.
353         if (drawing->toolAction)
354         {
355                 delete drawing->toolAction;
356                 drawing->toolAction = NULL;
357         }
358
359         drawing->SetAddLineToolActive(addLineAct->isChecked());
360         drawing->SetAddCircleToolActive(addCircleAct->isChecked());
361         drawing->SetAddDimensionToolActive(addDimensionAct->isChecked());
362 }
363
364
365 void ApplicationWindow::HelpAbout(void)
366 {
367         aboutWin->show();
368 }
369
370
371 void ApplicationWindow::Settings(void)
372 {
373         SettingsDialog dlg(this);
374         dlg.generalTab->antialiasChk->setChecked(drawing->useAntialiasing);
375
376         if (dlg.exec() == false)
377                 return;
378
379         // Deal with stuff here (since user hit "OK" button...)
380         drawing->useAntialiasing = dlg.generalTab->antialiasChk->isChecked();
381         WriteSettings();
382 }
383
384
385 void ApplicationWindow::HandleGrouping(void)
386 {
387         // Group a bunch of selected objects together or ungroup a selected group.
388 }
389
390
391 void ApplicationWindow::CreateActions(void)
392 {
393         exitAct = CreateAction(tr("&Quit"), tr("Quit"), tr("Exits the application."),
394                 QIcon(":/res/quit.png"), QKeySequence(tr("Ctrl+q")));
395         connect(exitAct, SIGNAL(triggered()), this, SLOT(close()));
396
397         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);
398         connect(snapToGridAct, SIGNAL(triggered()), this, SLOT(SnapToGridTool()));
399
400         fixAngleAct = CreateAction(tr("Fix &Angle"), tr("Fix Angle"), tr("Fixes the angle of an object."),
401                 QIcon(":/res/fix-angle.png"), QKeySequence(tr("F,A")), true);
402         connect(fixAngleAct, SIGNAL(triggered()), this, SLOT(FixAngle()));
403
404         fixLengthAct = CreateAction(tr("Fix &Length"), tr("Fix Length"), tr("Fixes the length of an object."),
405                 QIcon(":/res/fix-length.png"), QKeySequence(tr("F,L")), true);
406         connect(fixLengthAct, SIGNAL(triggered()), this, SLOT(FixLength()));
407
408         deleteAct = CreateAction(tr("&Delete"), tr("Delete Object"), tr("Deletes selected objects."), QIcon(":/res/delete-tool.png"), QKeySequence(), true);
409         connect(deleteAct, SIGNAL(triggered()), this, SLOT(DeleteTool()));
410
411         addDimensionAct = CreateAction(tr("Add &Dimension"), tr("Add Dimension"), tr("Adds a dimension to the drawing."), QIcon(":/res/dimension-tool.png"), QKeySequence("D,I"), true);
412         connect(addDimensionAct, SIGNAL(triggered()), this, SLOT(DimensionTool()));
413
414         addLineAct = CreateAction(tr("Add &Line"), tr("Add Line"), tr("Adds lines to the drawing."), QIcon(":/res/add-line-tool.png"), QKeySequence("A,L"), true);
415         connect(addLineAct, SIGNAL(triggered()), this, SLOT(AddLineTool()));
416
417         addCircleAct = CreateAction(tr("Add &Circle"), tr("Add Circle"), tr("Adds circles to the drawing."), QIcon(":/res/add-circle-tool.png"), QKeySequence("A,C"), true);
418         connect(addCircleAct, SIGNAL(triggered()), this, SLOT(AddCircleTool()));
419
420         addArcAct = CreateAction(tr("Add &Arc"), tr("Add Arc"), tr("Adds arcs to the drawing."), QIcon(":/res/add-arc-tool.png"), QKeySequence("A,A"), true);
421         connect(addArcAct, SIGNAL(triggered()), this, SLOT(AddArcTool()));
422
423         addPolygonAct = CreateAction(tr("Add &Polygon"), tr("Add Polygon"), tr("Add polygons to the drawing."), QIcon(":/res/add-polygon-tool.png"), QKeySequence("A,P"), true);
424         connect(addPolygonAct, SIGNAL(triggered()), this, SLOT(AddPolygonTool()));
425
426         aboutAct = CreateAction(tr("About &Architektonas"), tr("About Architektonas"), tr("Gives information about this program."), QIcon(":/res/generic-tool.png"), QKeySequence());
427         connect(aboutAct, SIGNAL(triggered()), this, SLOT(HelpAbout()));
428
429         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);
430         connect(rotateAct, SIGNAL(triggered()), this, SLOT(RotateTool()));
431
432         zoomInAct = CreateAction(tr("Zoom &In"), tr("Zoom In"), tr("Zoom in on the document."), QIcon(":/res/zoom-in.png"), QKeySequence(tr("+")), QKeySequence(tr("=")));
433         connect(zoomInAct, SIGNAL(triggered()), this, SLOT(ZoomInTool()));
434
435         zoomOutAct = CreateAction(tr("Zoom &Out"), tr("Zoom Out"), tr("Zoom out of the document."), QIcon(":/res/zoom-out.png"), QKeySequence(tr("-")));
436         connect(zoomOutAct, SIGNAL(triggered()), this, SLOT(ZoomOutTool()));
437
438         fileNewAct = CreateAction(tr("&New Drawing"), tr("New Drawing"), tr("Creates a new drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+n")));
439         connect(fileNewAct, SIGNAL(triggered()), this, SLOT(FileNew()));
440
441         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")));
442         connect(fileOpenAct, SIGNAL(triggered()), this, SLOT(FileOpen()));
443
444         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")));
445         connect(fileSaveAct, SIGNAL(triggered()), this, SLOT(FileSave()));
446
447         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")));
448         connect(fileSaveAsAct, SIGNAL(triggered()), this, SLOT(FileSaveAs()));
449
450         fileCloseAct = CreateAction(tr("&Close Drawing"), tr("Close Drawing"), tr("Closes the current drawing."), QIcon(":/res/generic-tool.png"), QKeySequence(tr("Ctrl+w")));
451
452         settingsAct = CreateAction(tr("&Settings"), tr("Settings"), tr("Change certain defaults for Architektonas."), QIcon(":/res/generic-tool.png"), QKeySequence());
453         connect(settingsAct, SIGNAL(triggered()), this, SLOT(Settings()));
454
455         groupAct = CreateAction(tr("&Group"), tr("Group"), tr("Group/ungroup selected objects."), QIcon(":/res/generic-tool.png"), QKeySequence("g"));
456         connect(groupAct, SIGNAL(triggered()), this, SLOT(HandleGrouping()));
457
458 //Hm. I think we'll have to have separate logic to do the "Radio Group Toolbar" thing...
459 // Yup, in order to turn them off, we'd have to have an "OFF" toolbar button. Ick.
460 /*      QActionGroup * group = new QActionGroup(this);
461         group->addAction(deleteAct);
462         group->addAction(addDimensionAct);
463         group->addAction(addLineAct);
464         group->addAction(addCircleAct);
465         group->addAction(addArcAct);//*/
466 }
467
468
469 //
470 // Consolidates action creation from a multi-step process to a single-step one.
471 //
472 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
473         QIcon icon, QKeySequence key, bool checkable/*= false*/)
474 {
475         QAction * action = new QAction(icon, name, this);
476         action->setToolTip(tooltip);
477         action->setStatusTip(statustip);
478         action->setShortcut(key);
479         action->setCheckable(checkable);
480
481         return action;
482 }
483
484
485 //
486 // This is essentially the same as the previous function, but this allows more
487 // than one key sequence to be added as key shortcuts.
488 //
489 QAction * ApplicationWindow::CreateAction(QString name, QString tooltip, QString statustip,
490         QIcon icon, QKeySequence key1, QKeySequence key2, bool checkable/*= false*/)
491 {
492         QAction * action = new QAction(icon, name, this);
493         action->setToolTip(tooltip);
494         action->setStatusTip(statustip);
495         QList<QKeySequence> keyList;
496         keyList.append(key1);
497         keyList.append(key2);
498         action->setShortcuts(keyList);
499         action->setCheckable(checkable);
500
501         return action;
502 }
503
504
505 void ApplicationWindow::CreateMenus(void)
506 {
507         QMenu * menu = menuBar()->addMenu(tr("&File"));
508         menu->addAction(fileNewAct);
509         menu->addAction(fileOpenAct);
510         menu->addAction(fileSaveAct);
511         menu->addAction(fileSaveAsAct);
512         menu->addAction(fileCloseAct);
513         menu->addSeparator();
514         menu->addAction(exitAct);
515
516         menu = menuBar()->addMenu(tr("&View"));
517         menu->addAction(zoomInAct);
518         menu->addAction(zoomOutAct);
519
520         menu = menuBar()->addMenu(tr("&Edit"));
521         menu->addAction(snapToGridAct);
522         menu->addAction(groupAct);
523         menu->addAction(fixAngleAct);
524         menu->addAction(fixLengthAct);
525         menu->addAction(rotateAct);
526         menu->addSeparator();
527         menu->addAction(deleteAct);
528         menu->addSeparator();
529         menu->addAction(addLineAct);
530         menu->addAction(addCircleAct);
531         menu->addAction(addArcAct);
532         menu->addAction(addPolygonAct);
533         menu->addAction(addDimensionAct);
534         menu->addSeparator();
535         menu->addAction(settingsAct);
536
537         menu = menuBar()->addMenu(tr("&Help"));
538         menu->addAction(aboutAct);
539 }
540
541
542 void ApplicationWindow::CreateToolbars(void)
543 {
544         QToolBar * toolbar = addToolBar(tr("File"));
545         toolbar->addAction(exitAct);
546
547         toolbar = addToolBar(tr("View"));
548         toolbar->addAction(zoomInAct);
549         toolbar->addAction(zoomOutAct);
550
551         toolbar = addToolBar(tr("Edit"));
552         toolbar->addAction(snapToGridAct);
553         toolbar->addAction(groupAct);
554         toolbar->addAction(fixAngleAct);
555         toolbar->addAction(fixLengthAct);
556         toolbar->addAction(rotateAct);
557         toolbar->addAction(deleteAct);
558         toolbar->addSeparator();
559         toolbar->addAction(addLineAct);
560         toolbar->addAction(addCircleAct);
561         toolbar->addAction(addArcAct);
562         toolbar->addAction(addPolygonAct);
563         toolbar->addAction(addDimensionAct);
564 }
565
566
567 void ApplicationWindow::ReadSettings(void)
568 {
569         QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
570         QSize size = settings.value("size", QSize(400, 400)).toSize();
571         drawing->useAntialiasing = settings.value("useAntialiasing", true).toBool();
572         snapToGridAct->setChecked(settings.value("snapToGrid", true).toBool());
573         resize(size);
574         move(pos);
575 //      pos = settings.value("charWndPos", QPoint(0, 0)).toPoint();
576 //      size = settings.value("charWndSize", QSize(200, 200)).toSize();
577 //      ((TTEdit *)qApp)->charWnd->resize(size);
578 //      ((TTEdit *)qApp)->charWnd->move(pos);
579 }
580
581
582 void ApplicationWindow::WriteSettings(void)
583 {
584         settings.setValue("pos", pos());
585         settings.setValue("size", size());
586         settings.setValue("useAntialiasing", drawing->useAntialiasing);
587         settings.setValue("snapToGrid", snapToGridAct->isChecked());
588 //      settings.setValue("charWndPos", ((TTEdit *)qApp)->charWnd->pos());
589 //      settings.setValue("charWndSize", ((TTEdit *)qApp)->charWnd->size());
590 }
591