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

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 12.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 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:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
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** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include <QtGui>
43
44#include "mainwindow.h"
45#include "mdichild.h"
46
47MainWindow::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
71void MainWindow::closeEvent(QCloseEvent *event)
72{
73 mdiArea->closeAllSubWindows();
74 if (mdiArea->currentSubWindow()) {
75 event->ignore();
76 } else {
77 writeSettings();
78 event->accept();
79 }
80}
81
82void MainWindow::newFile()
83{
84 MdiChild *child = createMdiChild();
85 child->newFile();
86 child->show();
87}
88
89void 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
109void MainWindow::save()
110{
111 if (activeMdiChild() && activeMdiChild()->save())
112 statusBar()->showMessage(tr("File saved"), 2000);
113}
114
115void MainWindow::saveAs()
116{
117 if (activeMdiChild() && activeMdiChild()->saveAs())
118 statusBar()->showMessage(tr("File saved"), 2000);
119}
120
121void MainWindow::cut()
122{
123 if (activeMdiChild())
124 activeMdiChild()->cut();
125}
126
127void MainWindow::copy()
128{
129 if (activeMdiChild())
130 activeMdiChild()->copy();
131}
132
133void MainWindow::paste()
134{
135 if (activeMdiChild())
136 activeMdiChild()->paste();
137}
138
139void 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
146void 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
166void 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
201MdiChild *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
214void 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
304void 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
332void 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
345void MainWindow::createStatusBar()
346{
347 statusBar()->showMessage(tr("Ready"));
348}
349
350void 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
359void MainWindow::writeSettings()
360{
361 QSettings settings("Trolltech", "MDI Example");
362 settings.setValue("pos", pos());
363 settings.setValue("size", size());
364}
365
366MdiChild *MainWindow::activeMdiChild()
367{
368 if (QMdiSubWindow *activeSubWindow = mdiArea->activeSubWindow())
369 return qobject_cast<MdiChild *>(activeSubWindow->widget());
370 return 0;
371}
372
373QMdiSubWindow *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
385void MainWindow::switchLayoutDirection()
386{
387 if (layoutDirection() == Qt::LeftToRight)
388 qApp->setLayoutDirection(Qt::RightToLeft);
389 else
390 qApp->setLayoutDirection(Qt::LeftToRight);
391}
392
393void MainWindow::setActiveSubWindow(QWidget *window)
394{
395 if (!window)
396 return;
397 mdiArea->setActiveSubWindow(qobject_cast<QMdiSubWindow *>(window));
398}
Note: See TracBrowser for help on using the repository browser.