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