// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \example mainwindows/menus
    \title Menus Example
    \examplecategory {User Interface Components}
    \ingroup examples-mainwindow
    \ingroup examples-layout

    \brief The Menus example demonstrates how menus can be used in a main
    window application.

    A menu widget can be either a pull-down menu in a menu bar or a
    standalone context menu. Pull-down menus are shown by the menu bar
    when the user clicks on the respective item or presses the
    specified shortcut key. Context menus are usually invoked by some
    special keyboard key or by right-clicking.

    \image menus-example.png

    A menu consists of a list of \e action items. In applications,
    many common commands can be invoked via menus, toolbar buttons as
    well as keyboard shortcuts. Since the user expects the commands to
    be performed in the same way, regardless of the user interface
    used, it is useful to represent each command as an action.

    The Menus example consists of one single class, \c MainWindow, derived
    from the QMainWindow class. When choosing one of the
    action items in our application, it will display the item's path
    in its central widget.

    \section1 MainWindow Class Definition

    QMainWindow provides a main application window, with a menu bar,
    tool bars, dock widgets and a status bar around a large central
    widget.

    \snippet mainwindows/menus/mainwindow.h 0

    In this example, we will see how to implement pull-down menus as
    well as a context menu. In order to implement a custom context
    menu we must reimplement QWidget's \l
    {QWidget::}{contextMenuEvent()} function to receive the context
    menu events for our main window.

    \snippet mainwindows/menus/mainwindow.h 1

    We must also implement a collection of private slots to respond to
    the user activating any of our menu entries.  Note that these
    slots are left out of this documentation since they are trivial,
    i.e., most of them are only displaying the action's path in the
    main window's central widget.

    \snippet mainwindows/menus/mainwindow.h 2

    We have chosen to simplify the constructor by implementing two
    private convenience functions to create the various actions, to
    add them to menus and to insert the menus into our main window's
    menu bar.

    \snippet mainwindows/menus/mainwindow.h 3

    Finally, we declare the various menus and actions as well as a
    simple information label in the application wide scope.

    The QMenu class provides a menu widget for use in menu bars,
    context menus, and other popup menus while the QAction class
    provides an abstract user interface action that can be inserted
    into widgets.

    In some situations it is useful to group actions together, e.g.,
    we have a \uicontrol {Left Align} action, a \uicontrol {Right Align} action, a
    \uicontrol {Justify} action, and a \uicontrol {Center} action, and we want
    only one of these actions to be active at any one time. One simple
    way of achieving this is to group the actions together in an
    action group using the QActionGroup class.

    \section1 MainWindow Class Implementation

    In the constructor, we start off by creating a regular QWidget and
    make it our main window's central widget. Note that the main
    window takes ownership of the widget pointer and deletes it at the
    appropriate time.

    \snippet mainwindows/menus/mainwindow.cpp 0
    \codeline
    \snippet mainwindows/menus/mainwindow.cpp 1

    Then we create the information label as well as a top and bottom
    filler that we add to a layout which we install on the central
    widget. QMainWindow objects come with their own customized layout
    and setting a layout on a the actual main window, or creating a
    layout with a main window as a parent, is considered an error. You
    should always set your own layout on the central widget instead.

    \snippet mainwindows/menus/mainwindow.cpp 2

    To create the actions and menus we call our two convenience
    functions: \c createActions() and \c createMenus(). We will get
    back to these shortly.

    QMainWindow's \l {QMainWindow::statusBar()}{statusBar()} function
    returns the status bar for the main window (if the status bar does
    not exist, this function will create and return an empty status
    bar). We initialize the status bar and window title, resize the
    window to an appropriate size as well as ensure that the main
    window cannot be resized to a smaller size than the given
    one.

    Now, let's take a closer look at the \c createActions() convenience
    function that creates the various actions:

    \snippet mainwindows/menus/mainwindow.cpp 4
    \dots

    A QAction object may contain an icon, a text, a shortcut, a status
    tip, a "What's This?" text, and a tooltip. Most of these can be
    set in the constructor, but they can also be set independently
    using the provided convenience functions.

    In the \c createActions() function, we first create a \c newAct
    action, passing the text and and an icon using one of the theme
    icon constants. We make \uicontrol Ctrl+N its shortcut using the
    QAction::setShortcut() function, and we set its status tip using the
    QAction::setStatusTip() function (the status tip is displayed on all
    status bars provided by the action's top-level parent widget). We
    also connect its \l {QAction::}{triggered()} signal to the \c
    newFile() slot.

    The rest of the actions are created in a similar manner. Please
    see the source code for details.

    \snippet mainwindows/menus/mainwindow.cpp 7


    Once we have created the \uicontrol {Left Align}, \uicontrol {Right Align},
    \uicontrol {Justify}, and a \uicontrol {Center} actions, we can also create
    the previously mentioned action group.

    Each action is added to the group using QActionGroup's \l
    {QActionGroup::}{addAction()} function. Note that an action also
    can be added to a group by creating it with the group as its
    parent. Since an action group is exclusive by default, only one of
    the actions in the group is checked at any one time (this can be
    altered using the QActionGroup::setExclusive() function).

    When all the actions are created, we use the \c createMenus()
    function to add the actions to the menus and to insert the menus
    into the menu bar:

    \snippet mainwindows/menus/mainwindow.cpp 8

    QMenuBar's \l {QMenuBar::addMenu()}{addMenu()} function appends a
    new QMenu with the given title, to the menu bar (note that the
    menu bar takes ownership of the menu). We use QWidget's \l
    {QWidget::addAction()}{addAction()} function to add each action to
    the corresponding menu.

    Alternatively, the QMenu class provides several \l
    {QMenu::addAction()}{addAction()} convenience functions that create
    and add new actions from given texts and/or icons. You can also
    provide a member that will automatically connect to the new
    action's \l {QAction::triggered()}{triggered()} signal, and a
    shortcut represented by a QKeySequence instance.

    The QMenu::addSeparator() function creates and returns a new
    separator action, i.e. an action for which QAction::isSeparator()
    returns true, and adds the new action to the menu's list of
    actions.

    \snippet mainwindows/menus/mainwindow.cpp 12

    Note the \uicontrol Format menu. First of all, it is added as a submenu
    to the \uicontrol Edit Menu using QMenu's \l
    {QMenu::addMenu()}{addMenu()} function. Secondly, take a look at the
    alignment actions: In the \c createActions() function we added the
    \c leftAlignAct, \c rightAlignAct, \c justifyAct and \c centerAct
    actions to an action group. Nevertheless, we must add each action
    to the menu separately while the action group does its magic
    behind the scene.

    \snippet mainwindows/menus/mainwindow.cpp 3

    To provide a custom context menu, we must reimplement QWidget's \l
    {QWidget::}{contextMenuEvent()} function to receive the widget's
    context menu events (note that the default implementation simply
    ignores these events).

    Whenever we receive such an event, we create a menu containing the
    \uicontrol Cut, \uicontrol Copy and \uicontrol Paste actions. Context menus can be
    executed either asynchronously using the \l {QMenu::}{popup()}
    function or synchronously using the \l {QMenu::}{exec()}
    function. In this example, we have chosen to show the menu using
    its \l {QMenu::}{exec()} function. By passing the event's position
    as argument we ensure that the context menu appears at the
    expected position.
*/
