/*!
    \example tools/customcompleter
    \title Custom Completer Example

    The Custom Completer example shows how to provide string-completion
    facilities for an input widget based on data provided by a model. The
    completer pops up suggestions for possible words based on the first three
    characters input by the user and the user's choice of word is inserted
    into the \c TextEdit using QTextCursor.

    \image customcompleter-example.png

    \section1 Setting Up The Resource File

    The Custom Completer example requires a resource file, \e wordlist.txt,
    that has a list of words to help QCompleter complete words. This file
    contains the following:

    \quotefromfile tools/customcompleter/customcompleter.qrc
    \skipto <!DOCTYPE RCC>
    \printuntil </RCC>

    \section1 TextEdit Class Definition

    The \c TextEdit class is a subclass of QTextEdit with a custom
    \c insertCompletion() slot and it reimplements the
    \l{QAbstractScrollArea::keyPressEvent()}{keyPressEvent()} and the
    \l{QWidget::focusInEvent()}{focusInEvent()} functions. \c TextEdit also
    contains a private function \c textUnderCursor() and a private instance
    of QCompleter, \c c.

    \quotefromfile tools/customcompleter/textedit.h
    \skipto class TextEdit
    \printuntil /^\}/

    \section1 TextEdit Class Implementation

    The constructor for \c TextEdit constructs a \c TextEdit with a parent and
    initializes \c c. The instructions to use the completer is displayed on
    the \c TextEdit object, using the
    \l{QTextEdit::setPlainText()}{setPlainText()} function.

    \quotefromfile tools/customcompleter/textedit.cpp
    \skipto TextEdit::TextEdit
    \printuntil /^\}/

    In addition, \c TextEdit also includes a default destructor:

    \skipto TextEdit::~TextEdit
    \printuntil /^\}/

    The \c setCompleter() function accepts a \a completer and sets it up.
    We use \c{if (c)} to check if \c c has been initialized. If it has been
    initialized, the QObject::disconnect() function is invoked to disconnect
    the signal from the slot. This is to ensure that no previous completer
    object is still connected to the slot.

    \skipto void TextEdit::setCompleter
    \printuntil /^\}/

    We then instantiate \c c with \a completer and set it as \c{TextEdit}'s
    widget. The completion mode and case sensitivity are also set and then
    we connect the \l{QCompleter::activated()}{activated()} signal to the
    \c insertCompletion() slot.

    The \c completer() function is a getter function that returns \c c.

    \skipto QCompleter *TextEdit
    \printuntil /^\}/

    The completer pops up the options available, based on the contents of
    \e wordlist.txt, but the text cursor is responsible for filling in the
    missing characters, according to the user's choice of word.

    Suppose the user inputs "ACT" and accepts the completer's suggestion of
    "ACTUAL". The \c completion string is then sent to \c insertCompletion()
    by the completer's \l{QCompleter::activated()}{activated()} signal.

    The \c insertCompletion() function is responsible for completing the word
    using a QTextCursor object, \c tc. It validates to ensure that the
    completer's widget is \c TextEdit before using \c tc to insert the extra
    characters to complete the word.

    \skipto void TextEdit::insertCompletion
    \printuntil /^\}/

    The figure below illustrates this process:

    \image customcompleter-insertcompletion.png

    \c{completion.length()} = 6

    \c{c->completionPrefix().length()}=3

    The difference between these two values is \c extra, which is 3. This
    means that the last three characters from the right, "U", "A", and "L",
    will be inserted by \c tc.

    The \c textUnderCursor() function uses a QTextCursor, \c tc, to select a
    word under the cursor and return it.

    \skipto QString TextEdit::textUnderCursor
    \printuntil /^\}/

    The \c TextEdit class reimplements \l{QWidget::focusInEvent()}
    {focusInEvent()} function, which is an event handler used to receive
    keyboard focus events for the widget.

    \skipto void TextEdit::focusInEvent
    \printuntil /^\}/

    The \l{QAbstractScrollArea::keyPressEvent()}{keyPressEvent()} is
    reimplemented to ignore key events like Qt::Key_Enter, Qt::Key_Return,
    Qt::Key_Escape, Qt::Key_Tab, and Qt::Key_Backtab so the completer can
    handle them.

    If there is an active completer, we cannot process the shortcut, Ctrl+E.

    \skipto void TextEdit::keyPressEvent
    \printuntil QTextEdit::keyPressEvent(e);

    We also handle other modifiers and shortcuts for which we do not want the
    completer to respond to.

    \skipto const bool ctrlOrShift
    \printuntil /^\}/

    Finally, we pop up the completer.

    \section1 MainWindow Class Definition

    The \c MainWindow class is a subclass of QMainWindow and implements a
    private slot, \c about(). This class also has two private functions,
    \c createMenu() and \c modelFromFile() as well as private instances of
    QCompleter and \c TextEdit.

    \quotefromfile tools/customcompleter/mainwindow.h
    \skipto class MainWindow
    \printuntil };

    \section1 MainWindow Class Implementation

    The constructor constructs a \c MainWindow with a parent and initializes
    the \c completer. It also instantiates a \c TextEdit and sets its
    completer. A QStringListModel, obtained from \c modelFromFile(), is used
    to populate the \c completer. The \c{MainWindow}'s central widget is set
    to \c TextEdit and its size is set to 500 x 300.

    \quotefromfile tools/customcompleter/mainwindow.cpp
    \skipto MainWindow::MainWindow
    \printuntil /^\}/

    The \c createMenu() function creates the necessary QAction objects needed
    for the "File" and "Help" menu and their \l{QAction::triggered()}
    {triggered()} signals are connected to the \c quit(), \c about(), and
    \c aboutQt() slots respectively.

    \skipto void MainWindow::createMenu
    \printuntil /^\}/

    The \c modelFromFile() function accepts a \a fileName and attempts to
    extract the contents of this file into a QStringListModel. We display the
    Qt::WaitCursor when we are populating the QStringList, \c words, and
    restore the mouse cursor when we are done.

    \skipto QAbstractItemModel *MainWindow::modelFromFile
    \printuntil /^\}/

    The \c about() function provides a brief description about the Custom
    Completer example.

    \skipto void MainWindow::about()
    \printuntil /^\}/

    \section1 \c main() Function

    The \c main() function instantiates \c MainWindow and invokes the
    \l{QWidget::show()}{show()} function.

    \quotefromfile tools/customcompleter/main.cpp
    \skipto int main
    \printuntil /^\}/
*/
