]> Shamusworld >> Repos - architektonas/blob - src/mainapp/mdiwindow.cpp
In the middle of chasing down MDI not activating bug, renaming of Graphic to
[architektonas] / src / mainapp / mdiwindow.cpp
1 // mdiwindow.cpp
2 //
3 // Part of the Architektonas Project
4 // Originally part of QCad Community Edition by Andrew Mustun
5 // Extensively rewritten and refactored by James L. Hammons
6 // Portions copyright (C) 2001-2003 RibbonSoft
7 // Copyright (C) 2010 Underground Software
8 // See the README and GPLv2 files for licensing and warranty information
9 //
10 // JLH = James L. Hammons <jlhamm@acm.org>
11 //
12 // Who  When        What
13 // ---  ----------  -----------------------------------------------------------
14 // JLH  05/17/2010  Added this text. :-)
15 //
16
17 #include "mdiwindow.h"
18
19 #include "drawing.h"
20 #include "eventhandler.h"
21 #include "exitdialog.h"
22 #include "filedialog.h"
23 #include "qg_graphicview.h"
24
25 // Class variable
26 int MDIWindow::idCounter = 0;
27
28 /**
29  * Constructor.
30  *
31  * @param doc Pointer to an existing document of NULL if a new
32  *   document shall be created for this window.
33  * @param parent Parent widget. Usually a workspace (QMdiArea).
34  */
35 MDIWindow::MDIWindow(Document * doc, QWidget * parent, const char * name/*= NULL*/,
36         Qt::WindowFlags wflags/*= Qt::WDestructiveClose*/):
37         QMdiSubWindow(parent, Qt::SubWindow), owner(false)//, forceClosing(false)
38 #warning "!!! wflags is ignored !!!"
39 {
40 // This warning not longer occurs...!
41 //This warning is most likely coming from the QMdiSubWindow() constructor above...
42 //#warning "QWidget::setMinimumSize: (/QMdi::ControlLabel) Negative sizes (-1,-1) are not possible"
43         initDoc(doc);
44         initView();
45         id = idCounter++;
46         parentWindow = NULL;
47
48 //not using this anymore
49 #if 0
50         if (document)
51         {
52                 if (document->getLayerList())
53                         // Link the graphic view to the layer widget
54                         document->getLayerList()->addListener(graphicView);
55
56                 if (document->getBlockList())
57                         // Link the graphic view to the block widget
58                         document->getBlockList()->addListener(graphicView);
59         }
60 #endif
61
62 //hm.
63         setFocus(/*Qt::StrongFocus*/);
64 }
65
66 /**
67  * Destructor.
68  *
69  * Deletes the document associated with this window.
70  */
71 MDIWindow::~MDIWindow()
72 {
73 #if 0
74         if (document->getLayerList())
75                 document->getLayerList()->removeListener(graphicView);
76
77         if (document->getBlockList())
78                 document->getBlockList()->removeListener(graphicView);
79 #endif
80
81         if (owner && document)
82                 delete document;
83
84         document = NULL;
85 }
86
87 /**
88  * Adds another MDI window to the list of known windows that
89  * depend on this one. This can be another view or a view for
90  * a particular block.
91  */
92 void MDIWindow::addChildWindow(MDIWindow * w)
93 {
94         DEBUG->print("RS_MDIWindow::addChildWindow()");
95         childWindows.append(w);
96         w->setParentWindow(this);
97         DEBUG->print("children: %d", childWindows.count());
98 }
99
100 /**
101  * Removes a child window.
102  *
103  * @see addChildWindow
104  */
105 void MDIWindow::removeChildWindow(MDIWindow * w)
106 {
107         DEBUG->print("RS_MDIWindow::removeChildWindow()");
108         bool success = childWindows.removeOne(w);
109         DEBUG->print("successfully removed child window: %s.", (success ? "yes" : "NO"));
110         DEBUG->print("# of children: %d", childWindows.count());
111 }
112
113 /**
114  * @return pointer to the print preview of this drawing or NULL.
115  */
116 MDIWindow * MDIWindow::getPrintPreview()
117 {
118         for(int i=0; i<childWindows.count(); i++)
119         {
120                 if (childWindows.at(i)->getGraphicView()->isPrintPreview())
121                         return childWindows.at(i);
122         }
123
124         return NULL;
125 }
126
127 /**
128  * closes this MDI window.
129  *
130  * @param force Disable cancel button (demo versions)
131  * @param ask Ask user before closing.
132  */
133 bool MDIWindow::CloseMDI(void)
134 {
135         // This should never happen:
136         if (!document)
137                 return true;
138
139         bool closed = false;
140         bool isBlock = (parentWindow != NULL);
141
142         // This is a block and we don't need to ask the user for closing
143         // since it's still available in the parent drawing after closing.
144         if (isBlock)
145         {
146                 DEBUG->print("  closing block");
147
148                 // tell parent window we're not here anymore.
149                 if (parentWindow)
150                 {
151                         DEBUG->print("    notifying parent about closing this window");
152                         parentWindow->removeChildWindow(this);
153                 }
154
155                 emit(signalClosing());
156                 closed = true;
157         }
158         // This is a drawing document. Ask user for closing.
159         else if (slotFileClose())
160         {
161                 DEBUG->print("  closing graphic");
162
163                 // Close all child windows:
164                 while (!childWindows.isEmpty())
165                 {
166                         MDIWindow * child = childWindows.takeFirst();
167
168                         if (child)
169                                 child->close();
170                 }
171
172                 emit(signalClosing());
173                 closed = true;
174         }
175
176         return closed;
177 }
178
179 /**
180  * Called by Qt when the user closes this MDI window.
181  */
182 void MDIWindow::closeEvent(QCloseEvent * ce)
183 {
184         DEBUG->print("MDIWindow::closeEvent begin");
185
186         (CloseMDI() ? ce->accept() : ce->ignore());
187
188         DEBUG->print("MDIWindow::closeEvent end");
189 }
190
191 /**
192  * Initialize the document.
193  */
194 void MDIWindow::initDoc(Document * doc)
195 {
196         DEBUG->print("MDIWindow::initDoc()");
197
198         if (!doc)
199         {
200                 document = new Drawing();                               // Drawing is derived from Document
201                 document->newDoc();
202                 owner = true;
203         }
204         else
205         {
206                 document = doc;
207                 owner = false;
208         }
209 }
210
211 /**
212  * Initialize the view.
213  */
214 void MDIWindow::initView()
215 {
216         // This is only called once: In the MDIWindow constructor.
217         DEBUG->print("MDIWindow::initView()");
218
219 //      graphicView = new QC_GraphicView(document, this);
220         graphicView = new QG_GraphicView(document, this);
221         setWidget(graphicView);
222         graphicView->setFocus();
223 }
224
225 /**
226  * Called when the current pen (color, style, width) has changed.
227  * Sets the active pen for the document in this MDI window.
228  */
229 void MDIWindow::slotPenChanged(Pen pen)
230 {
231         DEBUG->print("MDIWindow::slotPenChanged() begin");
232
233         if (document)
234                 document->setActivePen(pen);
235
236         DEBUG->print("MDIWindow::slotPenChanged() end");
237 }
238
239 /**
240  * Creates a new empty document in this MDI window.
241  */
242 void MDIWindow::slotFileNew()
243 {
244         DEBUG->print("MDIWindow::slotFileNew begin");
245
246         if (document && graphicView)
247         {
248                 document->newDoc();
249                 graphicView->redraw();
250         }
251
252         DEBUG->print("MDIWindow::slotFileNew end");
253 }
254
255 /**
256  * Opens the given file in this MDI window.
257  */
258 bool MDIWindow::slotFileOpen(const QString & fileName, RS2::FormatType type)
259 {
260         DEBUG->print("MDIWindow::slotFileOpen");
261         bool ret = false;
262
263         if (document != NULL && !fileName.isEmpty())
264         {
265                 document->newDoc();
266                 ret = document->open(fileName, type);
267
268                 if (ret)
269                 {
270                         //QString message=tr("Loaded document: ")+fileName;
271                         //statusBar()->message(message, 2000);
272
273                         DEBUG->print("MDIWindow::slotFileOpen: autoZoom");
274                         graphicView->zoomAuto(false);
275                         DEBUG->print("MDIWindow::slotFileOpen: autoZoom: OK");
276                 }
277                 else
278                 {
279                         DEBUG->print("MDIWindow::slotFileOpen: failed");
280                 }
281         }
282         else
283         {
284                 DEBUG->print("MDIWindow::slotFileOpen: cancelled");
285                 //statusBar()->message(tr("Opening aborted"), 2000);
286         }
287
288         DEBUG->print("MDIWindow::slotFileOpen: OK");
289
290         return ret;
291 }
292
293 /**
294  * Saves the current file.
295  *
296  * @return true if the file was saved successfully.
297  *         false if the file could not be saved or the document
298  *         is invalid.
299  */
300 bool MDIWindow::slotFileSave(bool & cancelled)
301 {
302         DEBUG->print("MDIWindow::slotFileSave()");
303         bool ret = false;
304         cancelled = false;
305
306         if (document)
307         {
308                 if (document->getFilename().isEmpty())
309                         ret = slotFileSaveAs(cancelled);
310                 else
311                 {
312                         QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
313                         ret = document->save();
314                         QApplication::restoreOverrideCursor();
315                 }
316         }
317
318         return ret;
319 }
320
321 /**
322  * Saves the current file. The user is asked for a new filename
323  * and format.
324  *
325  * @return true if the file was saved successfully or the user cancelled.
326  *         false if the file could not be saved or the document
327  *         is invalid.
328  */
329 bool MDIWindow::slotFileSaveAs(bool & cancelled)
330 {
331         DEBUG->print("MDIWindow::slotFileSaveAs");
332         bool ret = false;
333         cancelled = false;
334         RS2::FormatType t = RS2::FormatDXF;
335
336         QString fn = FileDialog::getSaveFileName(this, &t);
337
338         if (document != NULL && !fn.isEmpty())
339         {
340                 QApplication::setOverrideCursor(QCursor(Qt::WaitCursor));
341                 ret = document->saveAs(fn, t);
342                 QApplication::restoreOverrideCursor();
343         }
344         else
345         {
346                 // cancel is not an error - returns true
347                 ret = true;
348                 cancelled = true;
349         }
350
351         return ret;
352 }
353
354 /**
355  * Requests the closing of this MDI window.
356  */
357 bool MDIWindow::slotFileClose(void)
358 {
359         DEBUG->print("MDIWindow::slotFileClose()");
360         bool succeeded = true;
361
362         if (document == NULL || !document->isModified())
363                 return succeeded;
364
365         ExitDialog dlg(this);
366
367         if (document->getFilename().isEmpty())
368                 dlg.setText(tr("Do you really want to discard this drawing?"));
369         else
370         {
371                 QString fn = document->getFilename();
372
373                 if (fn.length() > 50)
374                         fn = QString("%1...%2").arg(fn.left(24)).arg(fn.right(24));
375
376                 dlg.setText(tr("Do you really want to discard changes to the file\n%1?").arg(fn));
377         }
378
379         dlg.setTitle(tr("Close Drawing"));
380
381         bool again = false;
382
383         do
384         {
385                 bool cancelled;
386                 int exit = dlg.exec();
387
388                 switch (exit)
389                 {
390                 case 0:                                                                 // Cancel
391                         succeeded = false;
392                         again = false;
393                         break;
394                 case 1:                                                                 // OK (Leave)
395                         succeeded = true;
396                         again = false;
397                         break;
398                 case 2:                                                                 // Save
399                         succeeded = slotFileSave(cancelled);
400                         again = !succeeded || cancelled;
401                         break;
402                 case 3:                                                                 // Save As
403                         succeeded = slotFileSaveAs(cancelled);
404                         again = !succeeded || cancelled;
405                         break;
406                 default:
407                         break;
408                 }
409         }
410         while (again);
411
412         return succeeded;
413 }
414
415 void MDIWindow::slotFilePrint()
416 {
417         DEBUG->print("MDIWindow::slotFilePrint");
418
419         //statusBar()->message(tr("Printing..."));
420         QPrinter printer;
421
422 //      if (printer.setup(this))
423         QPrintDialog dialog(&printer, this);
424
425         if (dialog.exec())
426         {
427                 QPainter painter;
428                 painter.begin(&printer);
429
430                 ///////////////////////////////////////////////////////////////////
431                 // TODO: Define printing by using the QPainter methods here
432
433                 painter.end();
434         }
435
436         //statusBar()->message(tr("Ready."));
437 }
438
439 /**
440  * @return Pointer to graphic view
441  */
442 //QC_GraphicView * MDIWindow::getGraphicView()
443 QG_GraphicView * MDIWindow::getGraphicView()
444 {
445         return graphicView;
446 }
447
448 /**
449  * @return Pointer to document
450  */
451 Document * MDIWindow::getDocument()
452 {
453         return document;
454 }
455
456 /**
457  * @return Pointer to Drawing or NULL
458  */
459 Drawing * MDIWindow::GetDrawing()
460 {
461         return document->GetDrawing();
462 }
463
464 /**
465  * @return Pointer to current event handler
466  */
467 EventHandler * MDIWindow::getEventHandler()
468 {
469         return (graphicView ? graphicView->getEventHandler() : NULL);
470 }
471
472 /**
473  * Sets the parent window that will be notified if this
474  */
475 void MDIWindow::setParentWindow(MDIWindow * p)
476 {
477         DEBUG->print("setParentWindow");
478         parentWindow = p;
479 }
480
481 /**
482  * @return The MDI window id.
483  */
484 int MDIWindow::getId()
485 {
486         return id;
487 }
488
489 /**
490  * Streams some info about an MDI window to stdout.
491  */
492 std::ostream & operator<<(std::ostream & os, MDIWindow & w)
493 {
494         os << "MDIWindow[" << w.getId() << "]:\n";
495
496         if (w.parentWindow)
497                 os << "  parentWindow: " << w.parentWindow->getId() << "\n";
498         else
499                 os << "  parentWindow: NULL\n";
500
501         for(int i=0; i<w.childWindows.count(); i++)
502                 os << "  childWindow[" << i << "]: " << w.childWindows.at(i)->getId() << "\n";
503
504         return os;
505 }