Qt with Cascades UI Examples Documentation

Contents

Codecs Example

Files:

Description

The Codecs example demonstrates the principles behind importing text using codecs to ensure that characters are encoded properly, avoiding loss of data and retaining the correct symbols used in various scripts.

Overview

In this example we'll learn how to use the QTextCodec class to decode raw data from a file and show them on the screen.

The UI

The sample application provides an UI with two DropDown controls in a row to select a file and a codec and below a TextArea where the decoded content of the selected file is shown. All the business logic is encapsulated in the C++ class CodecController which has been exported to the UI under the name '_codecController'.

                    DropDown {
                        id: fileList
                        title: qsTr ("File")

                        onSelectedIndexChanged: {
                            // Trigger an update of the decoded file content
                            _codecController.updateFileContent()
                        }
                    }

                    DropDown {
                        id: codecList
                        title: qsTr ("Codec")

                        onSelectedIndexChanged: {
                            // Trigger an update of the decoded file content
                            _codecController.updateFileContent()
                        }
                    }

Whenever the user selects a file or a codec from the DropDown controls, the updateFileContent() slot of the CodecController is invoked to update the content of the TextArea.

            onCreationCompleted: {
                // Tell the CodecController which DropDowns will handle the file and codec list
                _codecController.fileList = fileList
                _codecController.codecList = codecList
            }

Since the CodecController is also responsible for filling the DropDown controls with the list of available files and codecs, we have to set the 'fileList' and 'codecList' properties of the CodecController. This is done inside the signal handler for the creationCompleted() signal, which is emitted after the top-level control in main.qml has been created and initialized.

                // Shows the decoded file content
                TextArea {
                    horizontalAlignment: HorizontalAlignment.Fill

                    layoutProperties: StackLayoutProperties {
                        spaceQuota: 1
                    }

                    text: _codecController.fileContent
                    hintText: ""
                }

The CodecController also provides the property 'fileContent' which contains the content of the currently selected file decoded with the currently selected codec or an empty string if no file has been selected. We simply bind that property against the 'text' property of the TextArea.

CodecController

When the UI is loaded and the file selection DropDown is assigned to the 'fileList' property of the CodecController, the fillFileList() method is called which fills the provided DropDown with the entries for all available files. As the text of the entries we use the base name of the files and as value the relative path.

    void CodecController::fillFileList()
    {
        if (!m_fileList)
            return;

        const QStringList fileNames = QStringList()
            << "iso-8859-1.txt"
            << "iso-8859-15.txt"
            << "utf-16.txt"
            << "utf-16be.txt"
            << "utf-16le.txt"
            << "utf-8.txt";

        // Clear the file DropDown
        m_fileList->removeAll();

        // Create one entry for each file
        foreach (const QString fileName, fileNames) {
            Option *option = new Option;
            option->setText(fileName);
            option->setValue(QString("app/native/assets/encodedfiles/%1").arg(fileName));
            m_fileList->add(option);
        }
    }

This list is hard-coded to the list of files that are located in the assets/encodedfiles/ directory in the project folder.

When the codec selection DropDown is assigned to the 'codecList' property, the fillCodecList() method is called.

    void CodecController::fillCodecList()
    {
        if (!m_codecList)
            return;

        // Clear the codec DropDown
        m_codecList->removeAll();

        // Create one entry for each codec available on the system
        foreach (int mib, QTextCodec::availableMibs()) {
            QTextCodec *codec = QTextCodec::codecForMib(mib);

            Option *option = new Option;
            option->setText(codec->name());
            option->setValue(QVariant::fromValue(codec));

            // pre-select the UTF-8 codec in the DropDown
            if (codec->name() == "UTF-8")
                option->setSelected(true);

            m_codecList->add(option);
        }
    }

Here we iterate over the list of available codecs that are provided by Qt on this system and add one entry to the DropDown for each codec. As text for the entry we use the codec name and as value the pointer to the actual QTextCodec object that represents this codec. In addition we preselect the UTF-8 codec.

When the user selects a file or codec from the DropDown controls, the updateFileContent() slot will be invoked:

    void CodecController::updateFileContent()
    {
        if (!m_fileList || !m_codecList)
            return;

        // Check whether the user has selected a file already
        const int selectedIndex = m_fileList->selectedIndex();
        if (selectedIndex == DropDown::SelectedIndexNone)
            return;

        // Retrieve the selected Options from the file and codec DropDowns
        const Option *selectedFileOption = m_fileList->at(selectedIndex);
        const Option *selectedCodecOption = m_codecList->at(m_codecList->selectedIndex());

        // Extract the values associated with the selected Options
        const QString fileName = selectedFileOption->value().toString();
        QTextCodec *codec = selectedCodecOption->value().value<QTextCodec*>();

        // Open the selected file ...
        QFile file(fileName);
        if (!file.open(QIODevice::ReadOnly))
            return;

        // ... set a QTextStream with the selected codec on it ...
        QTextStream stream(&file);
        stream.setAutoDetectUnicode(false);
        stream.setCodec(codec);

        // ... and read out the decoded content
        m_fileContent = stream.readAll();

        emit fileContentChanged();
    }

In this method we first check which file and codec the user has selected in the DropDown controls and extract the file path and the QTextCodec object from the Option objects. Afterwards we try to open the selected file and set a QTextStream on it. The QTextStream allows us to read data from the file and decode them on-the-fly. For that we have to tell QTextStream which codec should be used, which is done by calling setCodec() on it.

Now we read the complete content of the file into the 'fileContent' property and emit the change notification signal, so that the UI will update the content of the TextArea.