|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the examples of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 #include <QtGui> |
|
43 |
|
44 #include "mainwindow.h" |
|
45 #include "mdichild.h" |
|
46 |
|
47 MainWindow::MainWindow() |
|
48 { |
|
49 mdiArea = new QMdiArea; |
|
50 mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
|
51 mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded); |
|
52 setCentralWidget(mdiArea); |
|
53 connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow *)), |
|
54 this, SLOT(updateMenus())); |
|
55 windowMapper = new QSignalMapper(this); |
|
56 connect(windowMapper, SIGNAL(mapped(QWidget *)), |
|
57 this, SLOT(setActiveSubWindow(QWidget *))); |
|
58 |
|
59 createActions(); |
|
60 createMenus(); |
|
61 createToolBars(); |
|
62 createStatusBar(); |
|
63 updateMenus(); |
|
64 |
|
65 readSettings(); |
|
66 |
|
67 setWindowTitle(tr("MDI")); |
|
68 setUnifiedTitleAndToolBarOnMac(true); |
|
69 } |
|
70 |
|
71 void MainWindow::closeEvent(QCloseEvent *event) |
|
72 { |
|
73 mdiArea->closeAllSubWindows(); |
|
74 if (activeMdiChild()) { |
|
75 event->ignore(); |
|
76 } else { |
|
77 writeSettings(); |
|
78 event->accept(); |
|
79 } |
|
80 } |
|
81 |
|
82 void MainWindow::newFile() |
|
83 { |
|
84 MdiChild *child = createMdiChild(); |
|
85 child->newFile(); |
|
86 child->show(); |
|
87 } |
|
88 |
|
89 void MainWindow::open() |
|
90 { |
|
91 QString fileName = QFileDialog::getOpenFileName(this); |
|
92 if (!fileName.isEmpty()) { |
|
93 QMdiSubWindow *existing = findMdiChild(fileName); |
|
94 if (existing) { |
|
95 mdiArea->setActiveSubWindow(existing); |
|
96 return; |
|
97 } |
|
98 |
|
99 MdiChild *child = createMdiChild(); |
|
100 if (child->loadFile(fileName)) { |
|
101 statusBar()->showMessage(tr("File loaded"), 2000); |
|
102 child->show(); |
|
103 } else { |
|
104 child->close(); |
|
105 } |
|
106 } |
|
107 } |
|
108 |
|
109 void MainWindow::save() |
|
110 { |
|
111 if (activeMdiChild() && activeMdiChild()->save()) |
|
112 statusBar()->showMessage(tr("File saved"), 2000); |
|
113 } |
|
114 |
|
115 void MainWindow::saveAs() |
|
116 { |
|
117 if (activeMdiChild() && activeMdiChild()->saveAs()) |
|
118 statusBar()->showMessage(tr("File saved"), 2000); |
|
119 } |
|
120 |
|
121 void MainWindow::cut() |
|
122 { |
|
123 if (activeMdiChild()) |
|
124 activeMdiChild()->cut(); |
|
125 } |
|
126 |
|
127 void MainWindow::copy() |
|
128 { |
|
129 if (activeMdiChild()) |
|
130 activeMdiChild()->copy(); |
|
131 } |
|
132 |
|
133 void MainWindow::paste() |
|
134 { |
|
135 if (activeMdiChild()) |
|
136 activeMdiChild()->paste(); |
|
137 } |
|
138 |
|
139 void MainWindow::about() |
|
140 { |
|
141 QMessageBox::about(this, tr("About MDI"), |
|
142 tr("The <b>MDI</b> example demonstrates how to write multiple " |
|
143 "document interface applications using Qt.")); |
|
144 } |
|
145 |
|
146 void MainWindow::updateMenus() |
|
147 { |
|
148 bool hasMdiChild = (activeMdiChild() != 0); |
|
149 saveAct->setEnabled(hasMdiChild); |
|
150 saveAsAct->setEnabled(hasMdiChild); |
|
151 pasteAct->setEnabled(hasMdiChild); |
|
152 closeAct->setEnabled(hasMdiChild); |
|
153 closeAllAct->setEnabled(hasMdiChild); |
|
154 tileAct->setEnabled(hasMdiChild); |
|
155 cascadeAct->setEnabled(hasMdiChild); |
|
156 nextAct->setEnabled(hasMdiChild); |
|
157 previousAct->setEnabled(hasMdiChild); |
|
158 separatorAct->setVisible(hasMdiChild); |
|
159 |
|
160 bool hasSelection = (activeMdiChild() && |
|
161 activeMdiChild()->textCursor().hasSelection()); |
|
162 cutAct->setEnabled(hasSelection); |
|
163 copyAct->setEnabled(hasSelection); |
|
164 } |
|
165 |
|
166 void MainWindow::updateWindowMenu() |
|
167 { |
|
168 windowMenu->clear(); |
|
169 windowMenu->addAction(closeAct); |
|
170 windowMenu->addAction(closeAllAct); |
|
171 windowMenu->addSeparator(); |
|
172 windowMenu->addAction(tileAct); |
|
173 windowMenu->addAction(cascadeAct); |
|
174 windowMenu->addSeparator(); |
|
175 windowMenu->addAction(nextAct); |
|
176 windowMenu->addAction(previousAct); |
|
177 windowMenu->addAction(separatorAct); |
|
178 |
|
179 QList<QMdiSubWindow *> windows = mdiArea->subWindowList(); |
|
180 separatorAct->setVisible(!windows.isEmpty()); |
|
181 |
|
182 for (int i = 0; i < windows.size(); ++i) { |
|
183 MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget()); |
|
184 |
|
185 QString text; |
|
186 if (i < 9) { |
|
187 text = tr("&%1 %2").arg(i + 1) |
|
188 .arg(child->userFriendlyCurrentFile()); |
|
189 } else { |
|
190 text = tr("%1 %2").arg(i + 1) |
|
191 .arg(child->userFriendlyCurrentFile()); |
|
192 } |
|
193 QAction *action = windowMenu->addAction(text); |
|
194 action->setCheckable(true); |
|
195 action ->setChecked(child == activeMdiChild()); |
|
196 connect(action, SIGNAL(triggered()), windowMapper, SLOT(map())); |
|
197 windowMapper->setMapping(action, windows.at(i)); |
|
198 } |
|
199 } |
|
200 |
|
201 MdiChild *MainWindow::createMdiChild() |
|
202 { |
|
203 MdiChild *child = new MdiChild; |
|
204 mdiArea->addSubWindow(child); |
|
205 |
|
206 connect(child, SIGNAL(copyAvailable(bool)), |
|
207 cutAct, SLOT(setEnabled(bool))); |
|
208 connect(child, SIGNAL(copyAvailable(bool)), |
|
209 copyAct, SLOT(setEnabled(bool))); |
|
210 |
|
211 return child; |
|
212 } |
|
213 |
|
214 void MainWindow::createActions() |
|
215 { |
|
216 newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this); |
|
217 newAct->setShortcuts(QKeySequence::New); |
|
218 newAct->setStatusTip(tr("Create a new file")); |
|
219 connect(newAct, SIGNAL(triggered()), this, SLOT(newFile())); |
|
220 |
|
221 openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this); |
|
222 openAct->setShortcuts(QKeySequence::Open); |
|
223 openAct->setStatusTip(tr("Open an existing file")); |
|
224 connect(openAct, SIGNAL(triggered()), this, SLOT(open())); |
|
225 |
|
226 saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this); |
|
227 saveAct->setShortcuts(QKeySequence::Save); |
|
228 saveAct->setStatusTip(tr("Save the document to disk")); |
|
229 connect(saveAct, SIGNAL(triggered()), this, SLOT(save())); |
|
230 |
|
231 saveAsAct = new QAction(tr("Save &As..."), this); |
|
232 saveAsAct->setShortcuts(QKeySequence::SaveAs); |
|
233 saveAsAct->setStatusTip(tr("Save the document under a new name")); |
|
234 connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs())); |
|
235 |
|
236 //! [0] |
|
237 exitAct = new QAction(tr("E&xit"), this); |
|
238 exitAct->setShortcuts(QKeySequence::Quit); |
|
239 exitAct->setStatusTip(tr("Exit the application")); |
|
240 connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows())); |
|
241 //! [0] |
|
242 |
|
243 cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this); |
|
244 cutAct->setShortcuts(QKeySequence::Cut); |
|
245 cutAct->setStatusTip(tr("Cut the current selection's contents to the " |
|
246 "clipboard")); |
|
247 connect(cutAct, SIGNAL(triggered()), this, SLOT(cut())); |
|
248 |
|
249 copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this); |
|
250 copyAct->setShortcuts(QKeySequence::Copy); |
|
251 copyAct->setStatusTip(tr("Copy the current selection's contents to the " |
|
252 "clipboard")); |
|
253 connect(copyAct, SIGNAL(triggered()), this, SLOT(copy())); |
|
254 |
|
255 pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this); |
|
256 pasteAct->setShortcuts(QKeySequence::Paste); |
|
257 pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current " |
|
258 "selection")); |
|
259 connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste())); |
|
260 |
|
261 closeAct = new QAction(tr("Cl&ose"), this); |
|
262 closeAct->setStatusTip(tr("Close the active window")); |
|
263 connect(closeAct, SIGNAL(triggered()), |
|
264 mdiArea, SLOT(closeActiveSubWindow())); |
|
265 |
|
266 closeAllAct = new QAction(tr("Close &All"), this); |
|
267 closeAllAct->setStatusTip(tr("Close all the windows")); |
|
268 connect(closeAllAct, SIGNAL(triggered()), |
|
269 mdiArea, SLOT(closeAllSubWindows())); |
|
270 |
|
271 tileAct = new QAction(tr("&Tile"), this); |
|
272 tileAct->setStatusTip(tr("Tile the windows")); |
|
273 connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows())); |
|
274 |
|
275 cascadeAct = new QAction(tr("&Cascade"), this); |
|
276 cascadeAct->setStatusTip(tr("Cascade the windows")); |
|
277 connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows())); |
|
278 |
|
279 nextAct = new QAction(tr("Ne&xt"), this); |
|
280 nextAct->setShortcuts(QKeySequence::NextChild); |
|
281 nextAct->setStatusTip(tr("Move the focus to the next window")); |
|
282 connect(nextAct, SIGNAL(triggered()), |
|
283 mdiArea, SLOT(activateNextSubWindow())); |
|
284 |
|
285 previousAct = new QAction(tr("Pre&vious"), this); |
|
286 previousAct->setShortcuts(QKeySequence::PreviousChild); |
|
287 previousAct->setStatusTip(tr("Move the focus to the previous " |
|
288 "window")); |
|
289 connect(previousAct, SIGNAL(triggered()), |
|
290 mdiArea, SLOT(activatePreviousSubWindow())); |
|
291 |
|
292 separatorAct = new QAction(this); |
|
293 separatorAct->setSeparator(true); |
|
294 |
|
295 aboutAct = new QAction(tr("&About"), this); |
|
296 aboutAct->setStatusTip(tr("Show the application's About box")); |
|
297 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about())); |
|
298 |
|
299 aboutQtAct = new QAction(tr("About &Qt"), this); |
|
300 aboutQtAct->setStatusTip(tr("Show the Qt library's About box")); |
|
301 connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt())); |
|
302 } |
|
303 |
|
304 void MainWindow::createMenus() |
|
305 { |
|
306 fileMenu = menuBar()->addMenu(tr("&File")); |
|
307 fileMenu->addAction(newAct); |
|
308 fileMenu->addAction(openAct); |
|
309 fileMenu->addAction(saveAct); |
|
310 fileMenu->addAction(saveAsAct); |
|
311 fileMenu->addSeparator(); |
|
312 QAction *action = fileMenu->addAction(tr("Switch layout direction")); |
|
313 connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection())); |
|
314 fileMenu->addAction(exitAct); |
|
315 |
|
316 editMenu = menuBar()->addMenu(tr("&Edit")); |
|
317 editMenu->addAction(cutAct); |
|
318 editMenu->addAction(copyAct); |
|
319 editMenu->addAction(pasteAct); |
|
320 |
|
321 windowMenu = menuBar()->addMenu(tr("&Window")); |
|
322 updateWindowMenu(); |
|
323 connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu())); |
|
324 |
|
325 menuBar()->addSeparator(); |
|
326 |
|
327 helpMenu = menuBar()->addMenu(tr("&Help")); |
|
328 helpMenu->addAction(aboutAct); |
|
329 helpMenu->addAction(aboutQtAct); |
|
330 } |
|
331 |
|
332 void MainWindow::createToolBars() |
|
333 { |
|
334 fileToolBar = addToolBar(tr("File")); |
|
335 fileToolBar->addAction(newAct); |
|
336 fileToolBar->addAction(openAct); |
|
337 fileToolBar->addAction(saveAct); |
|
338 |
|
339 editToolBar = addToolBar(tr("Edit")); |
|
340 editToolBar->addAction(cutAct); |
|
341 editToolBar->addAction(copyAct); |
|
342 editToolBar->addAction(pasteAct); |
|
343 } |
|
344 |
|
345 void MainWindow::createStatusBar() |
|
346 { |
|
347 statusBar()->showMessage(tr("Ready")); |
|
348 } |
|
349 |
|
350 void MainWindow::readSettings() |
|
351 { |
|
352 QSettings settings("Trolltech", "MDI Example"); |
|
353 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint(); |
|
354 QSize size = settings.value("size", QSize(400, 400)).toSize(); |
|
355 move(pos); |
|
356 resize(size); |
|
357 } |
|
358 |
|
359 void MainWindow::writeSettings() |
|
360 { |
|
361 QSettings settings("Trolltech", "MDI Example"); |
|
362 settings.setValue("pos", pos()); |
|
363 settings.setValue("size", size()); |
|
364 } |
|
365 |
|
366 MdiChild *MainWindow::activeMdiChild() |
|
367 { |
|
368 if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow()) |
|
369 return qobject_cast<MdiChild *>(activeSubWindow->widget()); |
|
370 return 0; |
|
371 } |
|
372 |
|
373 QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName) |
|
374 { |
|
375 QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath(); |
|
376 |
|
377 foreach (QMdiSubWindow *window, mdiArea->subWindowList()) { |
|
378 MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget()); |
|
379 if (mdiChild->currentFile() == canonicalFilePath) |
|
380 return window; |
|
381 } |
|
382 return 0; |
|
383 } |
|
384 |
|
385 void MainWindow::switchLayoutDirection() |
|
386 { |
|
387 if (layoutDirection() == Qt::LeftToRight) |
|
388 qApp->setLayoutDirection(Qt::RightToLeft); |
|
389 else |
|
390 qApp->setLayoutDirection(Qt::LeftToRight); |
|
391 } |
|
392 |
|
393 void MainWindow::setActiveSubWindow(QWidget *window) |
|
394 { |
|
395 if (!window) |
|
396 return; |
|
397 mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window)); |
|
398 } |