Revision control
++ // Copyright (C) 2016 The Qt Company Ltd.
++ // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only
++
++ /*!
++ \example richtext/orderform
++ \title Order Form Example
++ \examplecategory {User Interface Components}
++ \ingroup examples-richtext
++ \brief The Order Form example shows how to generate rich text
++ documents by combining a simple template with data input by the
++ user in a dialog.
++
++ \brief The Order Form example shows how to generate rich text documents by
++ combining a simple template with data input by the user in a dialog. Data
++ is extracted from a \c DetailsDialog object and displayed on a QTextEdit
++ with a QTextCursor, using various formats. Each form generated is added
++ to a QTabWidget for easy access.
++
++ \image orderform-example.png
++ {Application showing a completed order form for a customer}
++
++ \section1 DetailsDialog Definition
++
++ The \c DetailsDialog class is a subclass of QDialog, implementing a slot
++ \c verify() to allow contents of the \c DetailsDialog to be verified later.
++ This is further explained in \c DetailsDialog Implementation.
++
++ \snippet richtext/orderform/detailsdialog.h 0
++
++ The constructor of \c DetailsDialog accepts parameters \a title and
++ \a parent. The class defines four \e{getter} functions: \c orderItems(),
++ \c senderName(), \c senderAddress(), and \c sendOffers() to allow data
++ to be accessed externally.
++
++ The class definition includes input widgets for the required
++ fields, \c nameEdit and \c addressEdit. Also, a QCheckBox and a
++ QDialogButtonBox are defined; the former to provide the user with the
++ option to receive information on products and offers, and the latter
++ to ensure that buttons used are arranged according to the user's native
++ platform. In addition, a QTableWidget, \c itemsTable, is used to hold
++ order details.
++
++ The screenshot below shows the \c DetailsDialog we intend to create.
++
++ \image orderform-example-detailsdialog.png
++ {Dialog for entering customer order information}
++
++ \section1 DetailsDialog Implementation
++
++ The constructor of \c DetailsDialog instantiates the earlier defined fields
++ and their respective labels. The label for \c offersCheckBox is set and the
++ \c setupItemsTable() function is invoked to setup and populate
++ \c itemsTable. The QDialogButtonBox object, \c buttonBox, is instantiated
++ with \uicontrol OK and \uicontrol Cancel buttons. This \c buttonBox's \c accepted() and
++ \c rejected() signals are connected to the \c verify() and \c reject()
++ slots in \c DetailsDialog.
++
++ \snippet richtext/orderform/detailsdialog.cpp 0
++
++ A QGridLayout is used to place all the objects on the \c DetailsDialog.
++
++ \snippet richtext/orderform/detailsdialog.cpp 1
++
++ The \c setupItemsTable() function instantiates the QTableWidget object,
++ \c itemsTable, and sets the number of rows based on the QStringList
++ object, \c items, which holds the type of items ordered. The number of
++ columns is set to 2, providing a "name" and "quantity" layout. A \c for
++ loop is used to populate the \c itemsTable and the \c name item's flag
++ is set to Qt::ItemIsEnabled or Qt::ItemIsSelectable. For demonstration
++ purposes, the \c quantity item is set to a 1 and all items in the
++ \c itemsTable have this value for quantity; but this can be modified by
++ editing the contents of the cells at run time.
++
++ \snippet richtext/orderform/detailsdialog.cpp 2
++
++ The \c orderItems() function extracts data from the \c itemsTable and
++ returns it in the form of a QList<QPair<QString,int>> where each QPair
++ corresponds to an item and the quantity ordered.
++
++ \snippet richtext/orderform/detailsdialog.cpp 3
++
++ The \c senderName() function is used to return the value of the QLineEdit
++ used to store the name field for the order form.
++
++ \snippet richtext/orderform/detailsdialog.cpp 4
++
++ The \c senderAddress() function is used to return the value of the
++ QTextEdit containing the address for the order form.
++
++ \snippet richtext/orderform/detailsdialog.cpp 5
++
++ The \c sendOffers() function is used to return a \c true or \c false
++ value that is used to determine if the customer in the order form
++ wishes to receive more information on the company's offers and promotions.
++
++ \snippet richtext/orderform/detailsdialog.cpp 6
++
++ The \c verify() function is an additionally implemented slot used to
++ verify the details entered by the user into the \c DetailsDialog. If
++ the details entered are incomplete, a QMessageBox is displayed
++ providing the user the option to discard the \c DetailsDialog. Otherwise,
++ the details are accepted and the \c accept() function is invoked.
++
++ \snippet richtext/orderform/detailsdialog.cpp 7
++
++ \section1 MainWindow Definition
++
++ The \c MainWindow class is a subclass of QMainWindow, implementing two
++ slots - \c openDialog() and \c printFile(). It also contains a private
++ instance of QTabWidget, \c letters.
++
++ \snippet richtext/orderform/mainwindow.h 0
++
++ \section1 MainWindow Implementation
++
++ The \c MainWindow constructor sets up the \c fileMenu and the required
++ actions, \c newAction and \c printAction. These actions' \c triggered()
++ signals are connected to the additionally implemented openDialog() slot
++ and the default close() slot. The QTabWidget, \c letters, is
++ instantiated and set as the window's central widget.
++
++ \snippet richtext/orderform/mainwindow.cpp 0
++
++ The \c createLetter() function creates a new QTabWidget with a QTextEdit,
++ \c editor, as the parent. This function accepts four parameters that
++ correspond to we obtained through \c DetailsDialog, in order to "fill"
++ the \c editor.
++
++ \snippet richtext/orderform/mainwindow.cpp 1
++
++ We then obtain the cursor for the \c editor using QTextEdit::textCursor().
++ The \c cursor is then moved to the start of the document using
++ QTextCursor::Start.
++
++ \snippet richtext/orderform/mainwindow.cpp 2
++
++ Recall the structure of a \l{Rich Text Document Structure}
++ {Rich Text Document}, where sequences of frames and
++ tables are always separated by text blocks, some of which may contain no
++ information.
++
++ In the case of the Order Form Example, the document structure for this portion
++ is described by the table below:
++
++ \table
++ \row
++ \li {1, 8} frame with \e{referenceFrameFormat}
++ \row
++ \li block \li \c{A company}
++ \row
++ \li block
++ \row
++ \li block \li \c{321 City Street}
++ \row
++ \li block
++ \row
++ \li block \li \c{Industry Park}
++ \row
++ \li block
++ \row
++ \li block \li \c{Another country}
++ \endtable
++
++ This is accomplished with the following code:
++
++ \snippet richtext/orderform/mainwindow.cpp 3
++
++ Note that \c topFrame is the \c {editor}'s top-level frame and is not shown
++ in the document structure.
++
++ We then set the \c{cursor}'s position back to its last position in
++ \c topFrame and fill in the customer's name (provided by the constructor)
++ and address - using a range-based for loop to traverse the QString, \c address.
++
++ \snippet richtext/orderform/mainwindow.cpp 4
++
++ The \c cursor is now back in \c topFrame and the document structure for
++ the above portion of code is:
++
++ \table
++ \row
++ \li block \li \c{Donald}
++ \row
++ \li block \li \c{47338 Park Avenue}
++ \row
++ \li block \li \c{Big City}
++ \endtable
++
++ For spacing purposes, we invoke \l{QTextCursor::insertBlock()}
++ {insertBlock()} twice. The \l{QDate::currentDate()}{currentDate()} is
++ obtained and displayed. We use \l{QTextFrameFormat::setWidth()}
++ {setWidth()} to increase the width of \c bodyFrameFormat and we insert
++ a new frame with that width.
++
++ \snippet richtext/orderform/mainwindow.cpp 5
++
++ The following code inserts standard text into the order form.
++
++ \snippet richtext/orderform/mainwindow.cpp 6
++ \snippet richtext/orderform/mainwindow.cpp 7
++
++ This part of the document structure now contains the date, a frame with
++ \c bodyFrameFormat, as well as the standard text.
++
++ \table
++ \row
++ \li block
++ \row
++ \li block
++ \row
++ \li block \li \c{Date: 25 May 2007}
++ \row
++ \li block
++ \row
++ \li {1, 4} frame with \e{bodyFrameFormat}
++ \row
++ \li block \li \c{I would like to place an order for the following items:}
++ \row
++ \li block
++ \row
++ \li block
++ \endtable
++
++ A QTextTableFormat object, \c orderTableFormat, is used to hold the type
++ of item and the quantity ordered.
++
++ \snippet richtext/orderform/mainwindow.cpp 8
++
++ We use \l{QTextTable::cellAt()}{cellAt()} to set the headers for the
++ \c orderTable.
++
++ \snippet richtext/orderform/mainwindow.cpp 9
++
++ Then, we iterate through the QList of QPair objects to populate
++ \c orderTable.
++
++ \snippet richtext/orderform/mainwindow.cpp 10
++
++ The resulting document structure for this section is:
++
++ \table
++ \row
++ \li {1, 11} \c{orderTable} with \e{orderTableFormat}
++ \row
++ \li block \li \c{Product}
++ \row
++ \li block \li \c{Quantity}
++ \row
++ \li block \li \c{T-shirt}
++ \row
++ \li block \li \c{4}
++ \row
++ \li block \li \c{Badge}
++ \row
++ \li block \li \c{3}
++ \row
++ \li block \li \c{Reference book}
++ \row
++ \li block \li \c{2}
++ \row
++ \li block \li \c{Coffee cup}
++ \row
++ \li block \li \c{5}
++ \endtable
++
++ The \c cursor is then moved back to \c{topFrame}'s
++ \l{QTextFrame::lastPosition()}{lastPosition()} and more standard text
++ is inserted.
++
++ \snippet richtext/orderform/mainwindow.cpp 11
++ \snippet richtext/orderform/mainwindow.cpp 12
++
++ Another QTextTable is inserted, to display the customer's
++ preference regarding offers.
++
++ \snippet richtext/orderform/mainwindow.cpp 13
++
++ The document structure for this portion is:
++
++ \table
++ \row
++ \li block
++ \row
++ \li block\li \c{Please update my...}
++ \row
++ \li {1, 5} block
++ \row
++ \li {1, 4} \c{offersTable}
++ \row
++ \li block \li \c{I want to receive...}
++ \row
++ \li block \li \c{I do not want to receive...}
++ \row
++ \li block \li \c{X}
++ \endtable
++
++ The \c cursor is moved to insert "Sincerely" along with the customer's
++ name. More blocks are inserted for spacing purposes. The \c printAction
++ is enabled to indicate that an order form can now be printed.
++
++ \snippet richtext/orderform/mainwindow.cpp 14
++
++ The bottom portion of the document structure is:
++
++ \table
++ \row
++ \li block
++ \row
++ \li {1, 5} block\li \c{Sincerely,}
++ \row
++ \li block
++ \row
++ \li block
++ \row
++ \li block
++ \row
++ \li block \li \c{Donald}
++ \endtable
++
++ The \c createSample() function is used for illustration purposes, to create
++ a sample order form.
++
++ \snippet richtext/orderform/mainwindow.cpp 15
++
++ The \c openDialog() function opens a \c DetailsDialog object. If the
++ details in \c dialog are accepted, the \c createLetter() function is
++ invoked using the parameters extracted from \c dialog.
++
++ \snippet richtext/orderform/mainwindow.cpp 16
++
++ In order to print out the order form, a \c printFile() function is
++ included, as shown below:
++
++ \snippet richtext/orderform/mainwindow.cpp 17
++
++ This function also allows the user to print a selected area with
++ QTextCursor::hasSelection(), instead of printing the entire document.
++
++ \section1 \c main() Function
++
++ The \c main() function instantiates \c MainWindow and sets its size to
++ 640x480 pixels before invoking the \c show() function and
++ \c createSample() function.
++
++ \snippet richtext/orderform/main.cpp 0
++
++ */