/*!
    \example widgets/calculator
    \title Calculator Example

    The example shows how to use signals and slots to implement the
    functionality of a calculator widget, and how to use QGridLayout
    to place child widgets in a grid.

    \image calculator-example.png Screenshot of the Calculator example

    The example consists of two classes:

    \list
    \o \c Calculator is the calculator widget, with all the
       calculator functionality.
    \o \c Button is the widget used for each of the calculator
       button. It derives from QToolButton.
    \endlist

    We will start by reviewing \c Calculator, then we will take a
    look at \c Button.

    \section1 Calculator Class Definition

    \quotefromfile widgets/calculator/calculator.h
    \skipto class Calculator
    \printuntil addToMemory();

    The \c Calculator class provides a simple calculator widget. It
    inherits from QDialog and has several private slots associated
    with the calculator's buttons. QObject::eventFilter() is
    reimplemented to handle mouse events on the calculator's display.

    Buttons are grouped in categories according to their behavior.
    For example, all the digit buttons (labeled \gui 0 to \gui 9)
    append a digit to the current operand. For these, we connect
    multiple buttons to the same slot (e.g., \c digitClicked()). The
    categories are digits, unary operators (\gui{Sqrt}, \gui{x\unicode{178}},
    \gui{1/x}), additive operators (\gui{+}, \gui{-}), and
    multiplicative operators (\gui{\unicode{215}}, \gui{\unicode{247}}). The other buttons
    have their own slots.

    \printline private:
    \printuntil calculate

    The private \c createButton() function is used as part of the
    widget construction. \c abortOperation() is called whenever a
    division by zero occurs or when a square root operation is
    applied to a negative number. \c calculate() applies a binary
    operator (\gui{+}, \gui{-}, \gui{\unicode{215}}, or \gui{\unicode{247}}).

    \printline sumInMemory
    \printline sumSoFar
    \printline factorSoFar
    \printline pendingAdditiveOperator
    \printline pendingMultiplicativeOperator
    \printline waitingForOperand

    These variables, together with the contents of the calculator
    display (a QLineEdit), encode the state of the calculator:

    \list
    \o \c sumInMemory contains the value stored in the calculator's memory
       (using \gui{MS}, \gui{M+}, or \gui{MC}).
    \o \c sumSoFar stores the value accumulated so far. When the user
       clicks \gui{=}, \c sumSoFar is recomputed and shown on the
       display. \gui{Clear All} resets \c sumSoFar to zero.
    \o \c factorSoFar stores a temporary value when doing
        multiplications and divisions.
    \o \c pendingAdditiveOperator stores the last additive operator
       clicked by the user.
    \o \c pendingMultiplicativeOperator stores the last multiplicative operator
       clicked by the user.
    \o \c waitingForOperand is \c true when the calculator is
       expecting the user to start typing an operand.
    \endlist

    Additive and multiplicative operators are treated differently
    because they have different precedences. For example, \gui{1 + 2 \unicode{247}
    3} is interpreted as \gui{1 + (2 \unicode{247} 3)} because \gui{\unicode{247}} has higher
    precedence than \gui{+}.

    The table below shows the evolution of the calculator state as
    the user enters a mathematical expression.

    \table
    \header \o User Input            \o Display  \o Sum so Far \o Add. Op. \o Factor so Far \o Mult. Op. \o Waiting for Operand?
    \row    \o                       \o 0        \o 0          \o          \o               \o           \o \c true
    \row    \o \gui{1}               \o 1        \o 0          \o          \o               \o           \o \c false
    \row    \o \gui{1 +}             \o 1        \o 1          \o \gui{+}  \o               \o           \o \c true
    \row    \o \gui{1 + 2}           \o 2        \o 1          \o \gui{+}  \o               \o           \o \c false
    \row    \o \gui{1 + 2 \unicode{247}}         \o 2        \o 1          \o \gui{+}  \o 2             \o \gui{\unicode{247}}   \o \c true
    \row    \o \gui{1 + 2 \unicode{247} 3}       \o 3        \o 1          \o \gui{+}  \o 2             \o \gui{\unicode{247}}   \o \c false
    \row    \o \gui{1 + 2 \unicode{247} 3 -}     \o 1.66667  \o 1.66667    \o \gui{-}  \o               \o           \o \c true
    \row    \o \gui{1 + 2 \unicode{247} 3 - 4}   \o 4        \o 1.66667    \o \gui{-}  \o               \o           \o \c false
    \row    \o \gui{1 + 2 \unicode{247} 3 - 4 =} \o -2.33333 \o 0          \o          \o               \o           \o \c true
    \endtable

    Unary operators, such as \gui Sqrt, require no special handling;
    they can be applied immediately since the operand is already
    known when the operator button is clicked.

    \printline display
    \printuntil /^\};/

    Finally, we declare the variables associated with the display and the
    buttons used to display numerals.

    \section1 Calculator Class Implementation

    \quotefromfile widgets/calculator/calculator.cpp
    \skipto Calculator
    \printuntil waitingForOperand

    In the constructor, we initialize the calculator's state. The \c
    pendingAdditiveOperator and \c pendingMultiplicativeOperator
    variables don't need to be initialized explicitly, because the
    QString constructor initializes them to empty strings.

    \printline display =
    \printuntil setFont

    We create the QLineEdit representing the calculator's display and
    set up some of its properties. In particular, we set it to be
    read-only.

    We also enlarge \c{display}'s font by 8 points.

    \printline QColor
    \printuntil equalClicked

    We define four colors by specifying the red, green, and blue
    components on a scale from 0 to 255. Then, for each button, we
    call the private \c createButton() function with the proper text
    label, the associated color, and a slot to connect to the button.

    To make the \gui{Clear All} and \gui{=} buttons stand out, we
    call QColor::light() with a factor of 120%, making these buttons
    20% brighter than their neighbors.

    \printline QGridLayout
    \printuntil /^\}/

    The layout is handled by a single QGridLayout. The
    QLayout::setSizeConstraint() call ensures that the \c Calculator
    widget is always shown as its optimal size (its
    \l{QWidget::sizeHint()}{size hint}), preventing the user from
    resizing the calculator. The size hint is determined by the size
    and \l{QWidget::sizePolicy()}{size policy} of the child widgets.

    Most child widgets occupy only one cell in the grid layout. For
    these, we only need to pass a row and a column to
    QGridLayout::addWidget(). The \c display, \c backspaceButton, \c
    clearButton, and \c clearAllButton widgets occupy more than one
    column; for these we must also pass a row span and a column
    span.

    \skipto digitClicked
    \printuntil /^\}/

    Pressing one of the calculator's digit buttons will emit the
    button's \l{QToolButton::clicked()}{clicked()} signal, which will
    trigger the \c digitClicked() slot.

    First, we find out which button sent the signal using
    QObject::sender(). This function returns the sender as a QObject
    pointer. Since we know that the sender is a \c Button object, we
    can safely cast the QObject. We could have used a C-style cast or
    a C++ \c static_cast<>(), but as a defensive programming
    technique we use a \l qobject_cast(). The advantage is that if
    the object has the wrong type, a null pointer is returned.
    Crashes due to null pointers are much easier to diagnose than
    crashes due to unsafe casts. Once we have the button, we extract
    the operator using QToolButton::text().

    The slot needs to consider two situations in particular. If \c
    display contains "0" and the user clicks the \gui{0} button, it
    would be silly to show "00". And if the calculator is in
    a state where it is waiting for a new operand,
    the new digit is the first digit of that new operand; in that case,
    any result of a previous calculation must be cleared first.

    At the end, we append the new digit to the value in the display.

    \printline unaryOperatorClicked
    \printuntil /^\}/

    The \c unaryOperatorClicked() slot is called whenever one of the
    unary operator buttons is clicked. Again a pointer to the clicked
    button is retrieved using QObject::sender(). The operator is
    extracted from the button's text and stored in \c
    clickedOperator. The operand is obtained from \c display.

    Then we perform the operation. If \gui Sqrt is applied to a
    negative number or \gui{1/x} to zero, we call \c
    abortOperation(). If everything goes well, we display the result
    of the operation in the line edit and we set \c waitingForOperand
    to \c true. This ensures that if the user types a new digit, the
    digit will be considered as a new operand, instead of being
    appended to the current value.

    \printline additiveOperatorClicked
    \printto pendingMultiplicativeOperator.isEmpty

    The \c additiveOperatorClicked() slot is called when the user
    clicks the \gui{+} or \gui{-} button.

    Before we can actually do something about the clicked operator,
    we must handle any pending operations. We start with the
    multiplicative operators, since these have higher precedence than
    additive operators:

    \printline pendingMultiplicativeOperator.isEmpty
    \printto pendingAdditiveOperator.isEmpty

    If \gui{\unicode{215}} or \gui{\unicode{247}} has been clicked earlier, without clicking
    \gui{=} afterward, the current value in the display is the right
    operand of the \gui{\unicode{215}} or \gui{\unicode{247}} operator and we can finally
    perform the operation and update the display.

    \printline pendingAdditiveOperator.isEmpty
    \printto clickedOperator

    If \gui{+} or \gui{-} has been clicked earlier, \c sumSoFar is
    the left operand and the current value in the display is the
    right operand of the operator. If there is no pending additive
    operator, \c sumSoFar is simply set to be the text in the
    display.

    \printline clickedOperator
    \printuntil /^\}/

    Finally, we can take care of the operator that was just clicked.
    Since we don't have the right-hand operand yet, we store the clicked
    operator in the \c pendingAdditiveOperator variable. We will
    apply the operation later, when we have a right operand, with \c
    sumSoFar as the left operand.

    \printline multiplicativeOperatorClicked
    \printuntil /^\}/

    The \c multiplicativeOperatorClicked() slot is similar to \c
    additiveOperatorClicked(). We don't need to worry about pending
    additive operators here, because multiplicative operators have
    precedence over additive operators.

    \printline equalClicked
    \printuntil /^\}/

    Like in \c additiveOperatorClicked(), we start by handing any
    pending multiplicative and additive operators. Then we display \c
    sumSoFar and reset the variable to zero. Resetting the variable
    to zero is necessary to avoid counting the value twice.

    \printline pointClicked
    \printuntil /^\}/

    The \c pointClicked() slot adds a decimal point to the content in
    \c display.

    \printline changeSignClicked
    \printuntil /^\}/

    The \c changeSignClicked() slot changes the sign of the value in
    \c display. If the current value is positive, we prepend a minus
    sign; if the current value is negative, we remove the first
    character from the value (the minus sign).

    \printline backspaceClicked
    \printuntil /^\}/

    The \c backspaceClicked() removes the rightmost character in the
    display. If we get an empty string, we show "0" and set \c
    waitingForOperand to \c true.

    \printline clear
    \printuntil /^\}/

    The \c clear() slot resets the current operand to zero. It is
    equivalent to clicking \gui Backspace enough times to erase the
    entire operand.

    \printline clearAll
    \printuntil /^\}/

    The \c clearAll() slot resets the calculator to its initial state.

    \printline clearMemory
    \printto createButton

    The \c clearMemory() slot erases the sum kept in memory, \c
    readMemory() displays the sum as an operand, \c setMemory()
    replace the sum in memory with the current sum, and \c
    addToMemory() adds the current value to the value in memory. For
    \c setMemory() and \c addToMemory(), we start by calling \c
    equalClicked() to update \c sumSoFar and the value in the
    display.

    \printline createButton
    \printuntil /^\}/

    The private \c createButton() function is called from the
    constructor to create calculator buttons.

    \printline abortOperation
    \printuntil /^\}/

    The private \c abortOperation() function is called whenever a
    calculation fails. It resets the calculator state and displays
    "####".

    \printline calculate
    \printuntil /^\}/

    The private \c calculate() function performs a binary operation.
    The right operand is given by \c rightOperand. For additive
    operators, the left operand is \c sumSoFar; for multiplicative
    operators, the left operand is \c factorSoFar. The function
    return \c false if a division by zero occurs.

    \section1 Button Class Definition

    Let's now take a look at the \c Button class:

    \quotefromfile widgets/calculator/button.h
    \skipto class Button
    \printuntil };

    The \c Button class has a convenience constructor that takes a
    text label and a color, and it reimplements QWidget::sizeHint()
    to provide more space around the text than what QToolButton
    normally provides.

    \section1 Button Class Implementation

    \quotefromfile widgets/calculator/button.cpp
    \skipto Button
    \printuntil }

    The buttons' appearance is determined by the layout of the
    calculator widget through the size and
    \l{QWidget::sizePolicy}{size policy} of the layout's child
    widgets. The call to the
    \l{QWidget::setSizePolicy()}{setSizePolicy()} function in the
    constructor ensures that the button will expand horizontally to
    fill all the available space; by default, \l{QToolButton}s don't
    expand to fill available space. Without this call, the different
    buttons in a same column would have different widths.

    \printline QSize
    \printuntil }

    In \l{QWidget::sizeHint()}{sizeHint()}, we try to return a size
    that looks good for most buttons. We reuse the size hint of the
    base class (QToolButton) but modify it in the following ways:

    \list
    \o We add 20 to the \l{QSize::height()}{height} component of the size hint.
    \o We make the \l{QSize::width()}{width} component of the size
       hint at least as much as the \l{QSize::width()}{height}.
    \endlist

    This ensures that with most fonts, the digit and operator buttons
    will be square, without truncating the text on the
    \gui{Backspace}, \gui{Clear}, and \gui{Clear All} buttons.

    The screenshot below shows how the \c Calculator widget would
    look like if we \e didn't set the horizontal size policy to
    QSizePolicy::Expanding in the constructor and if we didn't
    reimplement QWidget::sizeHint().

    \image calculator-ugly.png The Calculator example with default size policies and size hints

*/
