examples/mainwindows/mdi/mainwindow.cpp
changeset 0 1918ee327afb
child 3 41300fa6a67c
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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 }