doc/src/examples/imageviewer.qdoc
changeset 0 1918ee327afb
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/doc/src/examples/imageviewer.qdoc	Mon Jan 11 14:00:40 2010 +0000
@@ -0,0 +1,340 @@
+/****************************************************************************
+**
+** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:LGPL$
+** No Commercial Usage
+** This file contains pre-release code and may not be distributed.
+** You may use this file in accordance with the terms and conditions
+** contained in the Technology Preview License Agreement accompanying
+** this package.
+**
+** GNU Lesser General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU Lesser
+** General Public License version 2.1 as published by the Free Software
+** Foundation and appearing in the file LICENSE.LGPL included in the
+** packaging of this file.  Please review the following information to
+** ensure the GNU Lesser General Public License version 2.1 requirements
+** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
+**
+** In addition, as a special exception, Nokia gives you certain additional
+** rights.  These rights are described in the Nokia Qt LGPL Exception
+** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
+**
+** If you have questions regarding the use of this file, please contact
+** Nokia at qt-info@nokia.com.
+**
+**
+**
+**
+**
+**
+**
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+/*!
+    \example widgets/imageviewer
+    \title Image Viewer Example
+
+    The example shows how to combine QLabel and QScrollArea to
+    display an image. QLabel is typically used for displaying text,
+    but it can also display an image. QScrollArea provides a
+    scrolling view around another widget. If the child widget exceeds
+    the size of the frame, QScrollArea automatically provides scroll
+    bars.
+
+    The example demonstrates how QLabel's ability to scale its
+    contents (QLabel::scaledContents), and QScrollArea's ability to
+    automatically resize its contents (QScrollArea::widgetResizable),
+    can be used to implement zooming and scaling features. In
+    addition the example shows how to use QPainter to print an image.
+
+    \image imageviewer-example.png Screenshot of the Image Viewer example
+
+    With the Image Viewer application, the users can view an image of
+    their choice. The \gui File menu gives the user the possibility
+    to:
+
+    \list
+    \o \gui{Open...} - Open an image file
+    \o \gui{Print...} - Print an image
+    \o \gui{Exit} - Exit the application
+    \endlist
+
+    Once an image is loaded, the \gui View menu allows the users to:
+
+    \list
+    \o \gui{Zoom In} - Scale the image up by 25%
+    \o \gui{Zoom Out} - Scale the image down by 25%
+    \o \gui{Normal Size} - Show the image at its original size
+    \o \gui{Fit to Window} - Stretch the image to occupy the entire window
+    \endlist
+
+    In addition the \gui Help menu provides the users with information
+    about the Image Viewer example in particular, and about Qt in
+    general.
+
+    \section1 ImageViewer Class Definition
+
+    \snippet examples/widgets/imageviewer/imageviewer.h 0
+
+    The \c ImageViewer class inherits from QMainWindow. We reimplement
+    the constructor, and create several private slots to facilitate
+    the menu entries. In addition we create four private functions.
+
+    We use \c createActions() and \c createMenus() when constructing
+    the \c ImageViewer widget. We use the \c updateActions() function
+    to update the menu entries when a new image is loaded, or when
+    the \gui {Fit to Window} option is toggled. The zoom slots use \c
+    scaleImage() to perform the zooming. In turn, \c
+    scaleImage() uses \c adjustScrollBar() to preserve the focal point after
+    scaling an image.
+
+    \section1 ImageViewer Class Implementation
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 0
+
+    In the constructor we first create the label and the scroll area.
+
+    We set \c {imageLabel}'s size policy to \l
+    {QSizePolicy::Ignored}{ignored}, making the users able to scale
+    the image to whatever size they want when the \gui {Fit to Window}
+    option is turned on. Otherwise, the default size polizy (\l
+    {QSizePolicy::Preferred}{preferred}) will make scroll bars appear
+    when the scroll area becomes smaller than the label's minimum size
+    hint.
+
+    We ensure that the label will scale its contents to fill all
+    available space, to enable the image to scale properly when
+    zooming. If we omitted to set the \c {imageLabel}'s \l
+    {QLabel::scaledContents}{scaledContents} property, zooming in
+    would enlarge the QLabel, but leave the pixmap at
+    its original size, exposing the QLabel's background.
+
+    We make \c imageLabel the scroll area's child widget, and we make
+    \c scrollArea the central widget of the QMainWindow. At the end
+    we create the associated actions and menus, and customize the \c
+    {ImageViewer}'s appearance.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 1
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 2
+
+    In the \c open() slot, we show a file dialog to the user. The
+    easiest way to create a QFileDialog is to use the static
+    convenience functions. QFileDialog::getOpenFileName() returns an
+    existing file selected by the user. If the user presses \gui
+    Cancel, QFileDialog returns an empty string.
+
+    Unless the file name is a empty string, we check if the file's
+    format is an image format by constructing a QImage which tries to
+    load the image from the file. If the constructor returns a null
+    image, we use a QMessageBox to alert the user.
+
+    The QMessageBox class provides a modal dialog with a short
+    message, an icon, and some buttons. As with QFileDialog the
+    easiest way to create a QMessageBox is to use its static
+    convenience functions. QMessageBox provides a range of different
+    messages arranged along two axes: severity (question,
+    information, warning and critical) and complexity (the number of
+    necessary response buttons). In this particular example an
+    information message with an \gui OK button (the default) is
+    sufficient, since the message is part of a normal operation.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 3
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 4
+
+    If the format is supported, we display the image in \c imageLabel
+    by setting the label's \l {QLabel::pixmap}{pixmap}. Then we enable
+    the \gui Print and \gui {Fit to Window} menu entries and update
+    the rest of the view menu entries. The \gui Open and \gui Exit
+    entries are enabled by default.
+
+    If the \gui {Fit to Window} option is turned off, the
+    QScrollArea::widgetResizable property is \c false and it is
+    our responsibility (not QScrollArea's) to give the QLabel a
+    reasonable size based on its contents. We call
+    \{QWidget::adjustSize()}{adjustSize()} to achieve this, which is
+    essentially the same as
+
+    \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 0
+
+    In the \c print() slot, we first make sure that an image has been
+    loaded into the application:
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 5
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 6
+
+    If the application is built in debug mode, the \c Q_ASSERT() macro
+    will expand to
+
+    \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 1
+
+    In release mode, the macro simply disappear. The mode can be set
+    in the application's \c .pro file. One way to do so is to add an
+    option to \gui qmake when building the appliction:
+
+    \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 2
+
+    or
+
+    \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 3
+
+    Another approach is to add this line directly to the \c .pro
+    file.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 7
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 8
+
+    Then we present a print dialog allowing the user to choose a
+    printer and to set a few options. We construct a painter with a
+    QPrinter as the paint device. We set the painter's window
+    and viewport in such a way that the image is as large as possible
+    on the paper, but without altering its
+    \l{Qt::KeepAspectRatio}{aspect ratio}.
+
+    In the end we draw the pixmap at position (0, 0).
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 9
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 10
+
+    We implement the zooming slots using the private \c scaleImage()
+    function. We set the scaling factors to 1.25 and 0.8,
+    respectively. These factor values ensure that a \gui {Zoom In}
+    action and a \gui {Zoom Out} action will cancel each other (since
+    1.25 * 0.8 == 1), and in that way the normal image size can be
+    restored using the zooming features.
+
+    The screenshots below show an image in its normal size, and the
+    same image after zooming in:
+
+    \table
+    \row
+    \o \inlineimage imageviewer-original_size.png
+    \o \inlineimage imageviewer-zoom_in_1.png
+    \o \inlineimage imageviewer-zoom_in_2.png
+    \endtable
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 11
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 12
+
+    When zooming, we use the QLabel's ability to scale its contents.
+    Such scaling doesn't change the actual size hint of the contents.
+    And since the \l {QLabel::adjustSize()}{adjustSize()} function
+    use those size hint, the only thing we need to do to restore the
+    normal size of the currently displayed image is to call \c
+    adjustSize() and reset the scale factor to 1.0.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 13
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 14
+
+    The \c fitToWindow() slot is called each time the user toggled
+    the \gui {Fit to Window} option. If the slot is called to turn on
+    the option, we tell the scroll area to resize its child widget
+    with the QScrollArea::setWidgetResizable() function. Then we
+    disable the \gui {Zoom In}, \gui {Zoom Out} and \gui {Normal
+    Size} menu entries using the private \c updateActions() function.
+
+    If the \l {QScrollArea::widgetResizable} property is set to \c
+    false (the default), the scroll area honors the size of its child
+    widget. If this property is set to \c true, the scroll area will
+    automatically resize the widget in order to avoid scroll bars
+    where they can be avoided, or to take advantage of extra space.
+    But the scroll area will honor the minimum size hint of its child
+    widget independent of the widget resizable property. So in this
+    example we set \c {imageLabel}'s size policy to \l
+    {QSizePolicy::Ignored}{ignored} in the constructor, to avoid that
+    scroll bars appear when the scroll area becomes smaller than the
+    label's minimum size hint.
+
+    The screenshots below shows an image in its normal size, and the
+    same image with the \gui {Fit to window} option turned on.
+    Enlarging the window will stretch the image further, as shown in
+    the third screenshot.
+
+    \table
+    \row
+    \o \inlineimage imageviewer-original_size.png
+    \o \inlineimage imageviewer-fit_to_window_1.png
+    \o \inlineimage imageviewer-fit_to_window_2.png
+    \endtable
+
+    If the slot is called to turn off the option, the
+    {QScrollArea::setWidgetResizable} property is set to \c false. We
+    also restore the image pixmap to its normal size by adjusting the
+    label's size to its content. And in the end we update the view
+    menu entries.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 15
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 16
+
+    We implement the \c about() slot to create a message box
+    describing what the example is designed to show.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 17
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 18
+
+    In the private \c createAction() function, we create the
+    actions providing the application features.
+
+    We assign a short-cut key to each action and connect them to the
+    appropiate slots. We only enable the \c openAct and \c exitAxt at
+    the time of creation, the others are updated once an image has
+    been loaded into the application. In addition we make the \c
+    fitToWindowAct \l {QAction::checkable}{checkable}.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 19
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 20
+
+    In the private \c createMenu() function, we add the previously
+    created actions to the \gui File, \gui View and \gui Help menus.
+
+    The QMenu class provides a menu widget for use in menu bars,
+    context menus, and other popup menus. The QMenuBar class provides
+    a horizontal menu bar that consists of a list of pull-down menu
+    items. So at the end we put the menus in the \c {ImageViewer}'s
+    menu bar which we retrieve with the QMainWindow::menuBar()
+    function.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 21
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 22
+
+    The private \c updateActions() function enables or disables the
+    \gui {Zoom In}, \gui {Zoom Out} and \gui {Normal Size} menu
+    entries depending on whether the \gui {Fit to Window} option is
+    turned on or off.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 23
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 24
+
+    In \c scaleImage(), we use the \c factor parameter to calculate
+    the new scaling factor for the displayed image, and resize \c
+    imageLabel. Since we set the
+    \l{QLabel::scaledContents}{scaledContents} property to \c true in
+    the constructor, the call to QWidget::resize() will scale the
+    image displayed in the label. We also adjust the scroll bars to
+    preserve the focal point of the image.
+
+    At the end, if the scale factor is less than 33.3% or greater
+    than 300%, we disable the respective menu entry to prevent the
+    image pixmap from becoming too large, consuming too much
+    resources in the window system.
+
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 25
+    \snippet examples/widgets/imageviewer/imageviewer.cpp 26
+
+    Whenever we zoom in or out, we need to adjust the scroll bars in
+    consequence. It would have been tempting to simply call
+
+    \snippet doc/src/snippets/code/doc_src_examples_imageviewer.qdoc 4
+
+    but this would make the top-left corner the focal point, not the
+    center. Therefore we need to take into account the scroll bar
+    handle's size (the \l{QScrollBar::pageStep}{page step}).
+*/