source: trunk/examples/mainwindows/mdi/mainwindow.cpp@ 1030

Last change on this file since 1030 was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 13.0 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include <QtGui>
42
43#include "mainwindow.h"
44#include "mdichild.h"
45
46MainWindow::MainWindow()
47{
48 mdiArea = new QMdiArea;
49 mdiArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAsNeeded);
50 mdiArea->setVerticalScrollBarPolicy(Qt::ScrollBarAsNeeded);
51 setCentralWidget(mdiArea);
52 connect(mdiArea, SIGNAL(subWindowActivated(QMdiSubWindow*)),
53 this, SLOT(updateMenus()));
54 windowMapper = new QSignalMapper(this);
55 connect(windowMapper, SIGNAL(mapped(QWidget*)),
56 this, SLOT(setActiveSubWindow(QWidget*)));
57
58 createActions();
59 createMenus();
60 createToolBars();
61 createStatusBar();
62 updateMenus();
63
64 readSettings();
65
66 setWindowTitle(tr("MDI"));
67 setUnifiedTitleAndToolBarOnMac(true);
68}
69
70void MainWindow::closeEvent(QCloseEvent *event)
71{
72 mdiArea->closeAllSubWindows();
73 if (mdiArea->currentSubWindow()) {
74 event->ignore();
75 } else {
76 writeSettings();
77 event->accept();
78 }
79}
80
81void MainWindow::newFile()
82{
83 MdiChild *child = createMdiChild();
84 child->newFile();
85 child->show();
86}
87
88void MainWindow::open()
89{
90 QString fileName = QFileDialog::getOpenFileName(this);
91 if (!fileName.isEmpty()) {
92 QMdiSubWindow *existing = findMdiChild(fileName);
93 if (existing) {
94 mdiArea->setActiveSubWindow(existing);
95 return;
96 }
97
98 MdiChild *child = createMdiChild();
99 if (child->loadFile(fileName)) {
100 statusBar()->showMessage(tr("File loaded"), 2000);
101 child->show();
102 } else {
103 child->close();
104 }
105 }
106}
107
108void MainWindow::save()
109{
110 if (activeMdiChild() && activeMdiChild()->save())
111 statusBar()->showMessage(tr("File saved"), 2000);
112}
113
114void MainWindow::saveAs()
115{
116 if (activeMdiChild() && activeMdiChild()->saveAs())
117 statusBar()->showMessage(tr("File saved"), 2000);
118}
119
120void MainWindow::cut()
121{
122 if (activeMdiChild())
123 activeMdiChild()->cut();
124}
125
126void MainWindow::copy()
127{
128 if (activeMdiChild())
129 activeMdiChild()->copy();
130}
131
132void MainWindow::paste()
133{
134 if (activeMdiChild())
135 activeMdiChild()->paste();
136}
137
138void MainWindow::about()
139{
140 QMessageBox::about(this, tr("About MDI"),
141 tr("The <b>MDI</b> example demonstrates how to write multiple "
142 "document interface applications using Qt."));
143}
144
145void MainWindow::updateMenus()
146{
147 bool hasMdiChild = (activeMdiChild() != 0);
148 saveAct->setEnabled(hasMdiChild);
149 saveAsAct->setEnabled(hasMdiChild);
150 pasteAct->setEnabled(hasMdiChild);
151 closeAct->setEnabled(hasMdiChild);
152 closeAllAct->setEnabled(hasMdiChild);
153 tileAct->setEnabled(hasMdiChild);
154 cascadeAct->setEnabled(hasMdiChild);
155 nextAct->setEnabled(hasMdiChild);
156 previousAct->setEnabled(hasMdiChild);
157 separatorAct->setVisible(hasMdiChild);
158
159 bool hasSelection = (activeMdiChild() &&
160 activeMdiChild()->textCursor().hasSelection());
161 cutAct->setEnabled(hasSelection);
162 copyAct->setEnabled(hasSelection);
163}
164
165void MainWindow::updateWindowMenu()
166{
167 windowMenu->clear();
168 windowMenu->addAction(closeAct);
169 windowMenu->addAction(closeAllAct);
170 windowMenu->addSeparator();
171 windowMenu->addAction(tileAct);
172 windowMenu->addAction(cascadeAct);
173 windowMenu->addSeparator();
174 windowMenu->addAction(nextAct);
175 windowMenu->addAction(previousAct);
176 windowMenu->addAction(separatorAct);
177
178 QList<QMdiSubWindow *> windows = mdiArea->subWindowList();
179 separatorAct->setVisible(!windows.isEmpty());
180
181 for (int i = 0; i < windows.size(); ++i) {
182 MdiChild *child = qobject_cast<MdiChild *>(windows.at(i)->widget());
183
184 QString text;
185 if (i < 9) {
186 text = tr("&%1 %2").arg(i + 1)
187 .arg(child->userFriendlyCurrentFile());
188 } else {
189 text = tr("%1 %2").arg(i + 1)
190 .arg(child->userFriendlyCurrentFile());
191 }
192 QAction *action = windowMenu->addAction(text);
193 action->setCheckable(true);
194 action ->setChecked(child == activeMdiChild());
195 connect(action, SIGNAL(triggered()), windowMapper, SLOT(map()));
196 windowMapper->setMapping(action, windows.at(i));
197 }
198}
199
200MdiChild *MainWindow::createMdiChild()
201{
202 MdiChild *child = new MdiChild;
203 mdiArea->addSubWindow(child);
204
205 connect(child, SIGNAL(copyAvailable(bool)),
206 cutAct, SLOT(setEnabled(bool)));
207 connect(child, SIGNAL(copyAvailable(bool)),
208 copyAct, SLOT(setEnabled(bool)));
209
210 return child;
211}
212
213void MainWindow::createActions()
214{
215 newAct = new QAction(QIcon(":/images/new.png"), tr("&New"), this);
216 newAct->setShortcuts(QKeySequence::New);
217 newAct->setStatusTip(tr("Create a new file"));
218 connect(newAct, SIGNAL(triggered()), this, SLOT(newFile()));
219
220 openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
221 openAct->setShortcuts(QKeySequence::Open);
222 openAct->setStatusTip(tr("Open an existing file"));
223 connect(openAct, SIGNAL(triggered()), this, SLOT(open()));
224
225 saveAct = new QAction(QIcon(":/images/save.png"), tr("&Save"), this);
226 saveAct->setShortcuts(QKeySequence::Save);
227 saveAct->setStatusTip(tr("Save the document to disk"));
228 connect(saveAct, SIGNAL(triggered()), this, SLOT(save()));
229
230 saveAsAct = new QAction(tr("Save &As..."), this);
231 saveAsAct->setShortcuts(QKeySequence::SaveAs);
232 saveAsAct->setStatusTip(tr("Save the document under a new name"));
233 connect(saveAsAct, SIGNAL(triggered()), this, SLOT(saveAs()));
234
235//! [0]
236 exitAct = new QAction(tr("E&xit"), this);
237 exitAct->setShortcuts(QKeySequence::Quit);
238 exitAct->setStatusTip(tr("Exit the application"));
239 connect(exitAct, SIGNAL(triggered()), qApp, SLOT(closeAllWindows()));
240//! [0]
241
242 cutAct = new QAction(QIcon(":/images/cut.png"), tr("Cu&t"), this);
243 cutAct->setShortcuts(QKeySequence::Cut);
244 cutAct->setStatusTip(tr("Cut the current selection's contents to the "
245 "clipboard"));
246 connect(cutAct, SIGNAL(triggered()), this, SLOT(cut()));
247
248 copyAct = new QAction(QIcon(":/images/copy.png"), tr("&Copy"), this);
249 copyAct->setShortcuts(QKeySequence::Copy);
250 copyAct->setStatusTip(tr("Copy the current selection's contents to the "
251 "clipboard"));
252 connect(copyAct, SIGNAL(triggered()), this, SLOT(copy()));
253
254 pasteAct = new QAction(QIcon(":/images/paste.png"), tr("&Paste"), this);
255 pasteAct->setShortcuts(QKeySequence::Paste);
256 pasteAct->setStatusTip(tr("Paste the clipboard's contents into the current "
257 "selection"));
258 connect(pasteAct, SIGNAL(triggered()), this, SLOT(paste()));
259
260 closeAct = new QAction(tr("Cl&ose"), this);
261 closeAct->setStatusTip(tr("Close the active window"));
262 connect(closeAct, SIGNAL(triggered()),
263 mdiArea, SLOT(closeActiveSubWindow()));
264
265 closeAllAct = new QAction(tr("Close &All"), this);
266 closeAllAct->setStatusTip(tr("Close all the windows"));
267 connect(closeAllAct, SIGNAL(triggered()),
268 mdiArea, SLOT(closeAllSubWindows()));
269
270 tileAct = new QAction(tr("&Tile"), this);
271 tileAct->setStatusTip(tr("Tile the windows"));
272 connect(tileAct, SIGNAL(triggered()), mdiArea, SLOT(tileSubWindows()));
273
274 cascadeAct = new QAction(tr("&Cascade"), this);
275 cascadeAct->setStatusTip(tr("Cascade the windows"));
276 connect(cascadeAct, SIGNAL(triggered()), mdiArea, SLOT(cascadeSubWindows()));
277
278 nextAct = new QAction(tr("Ne&xt"), this);
279 nextAct->setShortcuts(QKeySequence::NextChild);
280 nextAct->setStatusTip(tr("Move the focus to the next window"));
281 connect(nextAct, SIGNAL(triggered()),
282 mdiArea, SLOT(activateNextSubWindow()));
283
284 previousAct = new QAction(tr("Pre&vious"), this);
285 previousAct->setShortcuts(QKeySequence::PreviousChild);
286 previousAct->setStatusTip(tr("Move the focus to the previous "
287 "window"));
288 connect(previousAct, SIGNAL(triggered()),
289 mdiArea, SLOT(activatePreviousSubWindow()));
290
291 separatorAct = new QAction(this);
292 separatorAct->setSeparator(true);
293
294 aboutAct = new QAction(tr("&About"), this);
295 aboutAct->setStatusTip(tr("Show the application's About box"));
296 connect(aboutAct, SIGNAL(triggered()), this, SLOT(about()));
297
298 aboutQtAct = new QAction(tr("About &Qt"), this);
299 aboutQtAct->setStatusTip(tr("Show the Qt library's About box"));
300 connect(aboutQtAct, SIGNAL(triggered()), qApp, SLOT(aboutQt()));
301}
302
303void MainWindow::createMenus()
304{
305 fileMenu = menuBar()->addMenu(tr("&File"));
306 fileMenu->addAction(newAct);
307 fileMenu->addAction(openAct);
308 fileMenu->addAction(saveAct);
309 fileMenu->addAction(saveAsAct);
310 fileMenu->addSeparator();
311 QAction *action = fileMenu->addAction(tr("Switch layout direction"));
312 connect(action, SIGNAL(triggered()), this, SLOT(switchLayoutDirection()));
313 fileMenu->addAction(exitAct);
314
315 editMenu = menuBar()->addMenu(tr("&Edit"));
316 editMenu->addAction(cutAct);
317 editMenu->addAction(copyAct);
318 editMenu->addAction(pasteAct);
319
320 windowMenu = menuBar()->addMenu(tr("&Window"));
321 updateWindowMenu();
322 connect(windowMenu, SIGNAL(aboutToShow()), this, SLOT(updateWindowMenu()));
323
324 menuBar()->addSeparator();
325
326 helpMenu = menuBar()->addMenu(tr("&Help"));
327 helpMenu->addAction(aboutAct);
328 helpMenu->addAction(aboutQtAct);
329}
330
331void MainWindow::createToolBars()
332{
333 fileToolBar = addToolBar(tr("File"));
334 fileToolBar->addAction(newAct);
335 fileToolBar->addAction(openAct);
336 fileToolBar->addAction(saveAct);
337
338 editToolBar = addToolBar(tr("Edit"));
339 editToolBar->addAction(cutAct);
340 editToolBar->addAction(copyAct);
341 editToolBar->addAction(pasteAct);
342}
343
344void MainWindow::createStatusBar()
345{
346 statusBar()->showMessage(tr("Ready"));
347}
348
349void MainWindow::readSettings()
350{
351 QSettings settings("Trolltech", "MDI Example");
352 QPoint pos = settings.value("pos", QPoint(200, 200)).toPoint();
353 QSize size = settings.value("size", QSize(400, 400)).toSize();
354 move(pos);
355 resize(size);
356}
357
358void MainWindow::writeSettings()
359{
360 QSettings settings("Trolltech", "MDI Example");
361 settings.setValue("pos", pos());
362 settings.setValue("size", size());
363}
364
365MdiChild *MainWindow::activeMdiChild()
366{
367 if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
368 return qobject_cast<MdiChild *>(activeSubWindow->widget());
369 return 0;
370}
371
372QMdiSubWindow *MainWindow::findMdiChild(const QString &fileName)
373{
374 QString canonicalFilePath = QFileInfo(fileName).canonicalFilePath();
375
376 foreach (QMdiSubWindow *window, mdiArea->subWindowList()) {
377 MdiChild *mdiChild = qobject_cast<MdiChild *>(window->widget());
378 if (mdiChild->currentFile() == canonicalFilePath)
379 return window;
380 }
381 return 0;
382}
383
384void MainWindow::switchLayoutDirection()
385{
386 if (layoutDirection() == Qt::LeftToRight)
387 qApp->setLayoutDirection(Qt::RightToLeft);
388 else
389 qApp->setLayoutDirection(Qt::LeftToRight);
390}
391
392void MainWindow::setActiveSubWindow(QWidget *window)
393{
394 if (!window)
395 return;
396 mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
397}
Note: See TracBrowser for help on using the repository browser.