// Copyright (C) 2011 - 2012 Denis Shienkov <denis.shienkov@gmail.com>
// Copyright (C) 2023 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \example terminal
    \title Serial Terminal
    \ingroup qtserialport-examples
    \examplecategory Connectivity

    \brief Shows how to use various features of QSerialPort.

    \e Terminal  shows how to create a terminal for a simple serial interface by
    using \l{Qt Serial Port}.

    \image terminal-example.png

    This example shows the main features of the QSerialPort class, like
    configuration, I/O implementation and so forth. Also, the class
    QSerialPortInfo is invoked to display information about the serial ports
    available in the system.

    QSerialPort supports two general programming approaches:

    \list

    \li \b{The asynchronous (non-blocking) approach.} Operations are scheduled
    and performed when the control returns to Qt's event loop. QSerialPort emits
    a signal when the operation is finished. For example, QSerialPort::write()
    returns immediately. When the data is sent to the serial port,
    QSerialPort emits \l{QIODevice::bytesWritten()}{bytesWritten()}.

    \li \b{The synchronous (blocking) approach.} In non-GUI and multithreaded
    applications, the \c waitFor...() functions can be called (i.e.
    QSerialPort::waitForReadyRead()) to suspend the calling thread until the
    operation has completed.

    \endlist

    In this example, the asynchronous approach is demonstrated. The
    \l{blockingreceiver}{Blocking Receiver} example illustrates the synchronous
    approach.

    Our example contains some GUI widgets:

    \list

    \li \c{MainWindow} (\c{terminal/mainwindow.cpp}) - is the main application
    window that contains all the working logic for the serial port programming,
    including configuration, I/O processing and so forth, while inheriting the
    QMainWindow.

    \li \c{Console} (\c{terminal/console.cpp}) - is the central widget of the
    main window, displaying the transmitted or received data. The widget is
    derived from the QPlainTextEdit class.

    \li \c{SettingsDialog} (\c{terminal/settingsdialog.cpp}) - is a dialog for
    configuring the serial port, as well as for displaying the available serial
    ports and information about them.

    \endlist

    The serial port is instantiated in the \c MainWindow
    constructor. The main widget is passed as the parent, so the object deletion
    happens automatically according to the parent and child mechanism in Qt:

    \snippet terminal/mainwindow.cpp 0
    \snippet terminal/mainwindow.cpp 1
    \dots

    This example demonstrates the following \l QSerialPort signals:
    \list
        \li \l {QIODevice::}{readyRead()} - shows that new data has been
        received and hence available
        \li \l {QIODevice::}{bytesWritten()} - used to check that all data was
        written successfully
    \endlist

    \dots
    \snippet terminal/mainwindow.cpp 2
    \dots
    \snippet terminal/mainwindow.cpp 3

    Clicking on the \b{Connect} button invokes the \c openSerialPort() slot:

    \snippet terminal/mainwindow.cpp 4

    In this slot, the settings are read from \c{SettingsDialog} and an attempt
    is made to open and initialize the serial
    port accordingly. If successful, the status bar displays a message that the
    opening was successful with the given configuration; otherwise, a messagebox
    is displayed with the appropriate error code and message. If the serial port
    settings have never been called then the terminal attempts to open
    the port with the default settings: 9600 8N1.

    Clicking on the \b{Disconnect} button invokes the \c closeSerialPort()
    slot:

    \snippet terminal/mainwindow.cpp 5

    In this case, handled by the closure of the serial port.

    Clicking on the \b{Configure} button invokes the \c{show()} slot which
    belongs to the \c{SettingsDialog} widget.

    This method (\c{terminal/settingsdialog.cpp}) displays the \c{SettingsDialog},
    in which the user can choose the desired serial port, see the information
    about the selected port, and set the desired parameters of the given serial
    port.

    \section2 Writing Data

    Typing characters in the console invokes the \c writeData() slot:

    \snippet terminal/mainwindow.cpp 6

    This slot sends the characters typed in the given
    Console widget to the serial port - see \c terminal/console.cpp.
    It also starts a timer to track if the write actually succeeded or not.
    We use the \l {QIODevice::}{bytesWritten()} signal to make sure that all
    bytes are actually written. It is connected to the
    \c {MainWindow::handleBytesWritten()} slot:

    \snippet terminal/mainwindow.cpp 9

    \section2 Reading Data

    When the serial port receives new data, the signal
    \l{QIODevice::}{readyRead()} is emitted, and that signal is
    connected to the \c{MainWindow::readData()} slot:

    \snippet terminal/mainwindow.cpp 7

    This slot reads the data from the serial port and displays that in the
    Console widget.

    \sa {Blocking Receiver}

    \include examples-run.qdocinc
*/
