documenthandler.cpp Example File | Qt Quick Controls 5.12.11

- Qt 5.12
- Qt Quick Controls
- Qt Quick Controls - Text Editor
- documenthandler.cpp Example File
- Qt 5.12.11 Reference Documentation

# documenthandler.cpp Example File

texteditor/documenthandler.cpp

     /****************************************************************************
     **
     ** Copyright (C) 2017 The Qt Company Ltd.
     ** Contact: https://www.qt.io/licensing/
     **
     ** This file is part of the examples of the Qt Toolkit.
     **
     ** $QT_BEGIN_LICENSE:BSD$
     ** Commercial License Usage
     ** Licensees holding valid commercial Qt licenses may use this file in
     ** accordance with the commercial license agreement provided with the
     ** Software or, alternatively, in accordance with the terms contained in
     ** a written agreement between you and The Qt Company. For licensing terms
     ** and conditions see https://www.qt.io/terms-conditions. For further
     ** information use the contact form at https://www.qt.io/contact-us.
     **
     ** BSD License Usage
     ** Alternatively, you may use this file under the terms of the BSD license
     ** as follows:
     **
     ** "Redistribution and use in source and binary forms, with or without
     ** modification, are permitted provided that the following conditions are
     ** met:
     **   * Redistributions of source code must retain the above copyright
     **     notice, this list of conditions and the following disclaimer.
     **   * Redistributions in binary form must reproduce the above copyright
     **     notice, this list of conditions and the following disclaimer in
     **     the documentation and/or other materials provided with the
     **     distribution.
     **   * Neither the name of The Qt Company Ltd nor the names of its
     **     contributors may be used to endorse or promote products derived
     **     from this software without specific prior written permission.
     **
     **
     ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
     ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
     ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
     ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
     ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
     ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
     **
     ** $QT_END_LICENSE$
     **
     ****************************************************************************/

     #include "documenthandler.h"

     #include <QFile>
     #include <QFileInfo>
     #include <QFileSelector>
     #include <QQmlFile>
     #include <QQmlFileSelector>
     #include <QQuickTextDocument>
     #include <QTextCharFormat>
     #include <QTextCodec>
     #include <QTextDocument>
     #include <QDebug>

     DocumentHandler::DocumentHandler(QObject *parent)
         : QObject(parent)
         , m_document(nullptr)
         , m_cursorPosition(-1)
         , m_selectionStart(0)
         , m_selectionEnd(0)
     {
     }

     QQuickTextDocument *DocumentHandler::document() const
     {
         return m_document;
     }

     void DocumentHandler::setDocument(QQuickTextDocument *document)
     {
         if (document == m_document)
             return;

         m_document = document;
         emit documentChanged();
     }

     int DocumentHandler::cursorPosition() const
     {
         return m_cursorPosition;
     }

     void DocumentHandler::setCursorPosition(int position)
     {
         if (position == m_cursorPosition)
             return;

         m_cursorPosition = position;
         reset();
         emit cursorPositionChanged();
     }

     int DocumentHandler::selectionStart() const
     {
         return m_selectionStart;
     }

     void DocumentHandler::setSelectionStart(int position)
     {
         if (position == m_selectionStart)
             return;

         m_selectionStart = position;
         emit selectionStartChanged();
     }

     int DocumentHandler::selectionEnd() const
     {
         return m_selectionEnd;
     }

     void DocumentHandler::setSelectionEnd(int position)
     {
         if (position == m_selectionEnd)
             return;

         m_selectionEnd = position;
         emit selectionEndChanged();
     }

     QString DocumentHandler::fontFamily() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return QString();
         QTextCharFormat format = cursor.charFormat();
         return format.font().family();
     }

     void DocumentHandler::setFontFamily(const QString &family)
     {
         QTextCharFormat format;
         format.setFontFamily(family);
         mergeFormatOnWordOrSelection(format);
         emit fontFamilyChanged();
     }

     QColor DocumentHandler::textColor() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return QColor(Qt::black);
         QTextCharFormat format = cursor.charFormat();
         return format.foreground().color();
     }

     void DocumentHandler::setTextColor(const QColor &color)
     {
         QTextCharFormat format;
         format.setForeground(QBrush(color));
         mergeFormatOnWordOrSelection(format);
         emit textColorChanged();
     }

     Qt::Alignment DocumentHandler::alignment() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return Qt::AlignLeft;
         return textCursor().blockFormat().alignment();
     }

     void DocumentHandler::setAlignment(Qt::Alignment alignment)
     {
         QTextBlockFormat format;
         format.setAlignment(alignment);
         QTextCursor cursor = textCursor();
         cursor.mergeBlockFormat(format);
         emit alignmentChanged();
     }

     bool DocumentHandler::bold() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return false;
         return textCursor().charFormat().fontWeight() == QFont::Bold;
     }

     void DocumentHandler::setBold(bool bold)
     {
         QTextCharFormat format;
         format.setFontWeight(bold ? QFont::Bold : QFont::Normal);
         mergeFormatOnWordOrSelection(format);
         emit boldChanged();
     }

     bool DocumentHandler::italic() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return false;
         return textCursor().charFormat().fontItalic();
     }

     void DocumentHandler::setItalic(bool italic)
     {
         QTextCharFormat format;
         format.setFontItalic(italic);
         mergeFormatOnWordOrSelection(format);
         emit italicChanged();
     }

     bool DocumentHandler::underline() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return false;
         return textCursor().charFormat().fontUnderline();
     }

     void DocumentHandler::setUnderline(bool underline)
     {
         QTextCharFormat format;
         format.setFontUnderline(underline);
         mergeFormatOnWordOrSelection(format);
         emit underlineChanged();
     }

     int DocumentHandler::fontSize() const
     {
         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return 0;
         QTextCharFormat format = cursor.charFormat();
         return format.font().pointSize();
     }

     void DocumentHandler::setFontSize(int size)
     {
         if (size <= 0)
             return;

         QTextCursor cursor = textCursor();
         if (cursor.isNull())
             return;

         if (!cursor.hasSelection())
             cursor.select(QTextCursor::WordUnderCursor);

         if (cursor.charFormat().property(QTextFormat::FontPointSize).toInt() == size)
             return;

         QTextCharFormat format;
         format.setFontPointSize(size);
         mergeFormatOnWordOrSelection(format);
         emit fontSizeChanged();
     }

     QString DocumentHandler::fileName() const
     {
         const QString filePath = QQmlFile::urlToLocalFileOrQrc(m_fileUrl);
         const QString fileName = QFileInfo(filePath).fileName();
         if (fileName.isEmpty())
             return QStringLiteral("untitled.txt");
         return fileName;
     }

     QString DocumentHandler::fileType() const
     {
         return QFileInfo(fileName()).suffix();
     }

     QUrl DocumentHandler::fileUrl() const
     {
         return m_fileUrl;
     }

     void DocumentHandler::load(const QUrl &fileUrl)
     {
         if (fileUrl == m_fileUrl)
             return;

         QQmlEngine *engine = qmlEngine(this);
         if (!engine) {
             qWarning() << "load() called before DocumentHandler has QQmlEngine";
             return;
         }

         const QUrl path = QQmlFileSelector::get(engine)->selector()->select(fileUrl);
         const QString fileName = QQmlFile::urlToLocalFileOrQrc(path);
         if (QFile::exists(fileName)) {
             QFile file(fileName);
             if (file.open(QFile::ReadOnly)) {
                 QByteArray data = file.readAll();
                 QTextCodec *codec = QTextCodec::codecForHtml(data);
                 if (QTextDocument *doc = textDocument())
                     doc->setModified(false);

                 emit loaded(codec->toUnicode(data));
                 reset();
             }
         }

         m_fileUrl = fileUrl;
         emit fileUrlChanged();
     }

     void DocumentHandler::saveAs(const QUrl &fileUrl)
     {
         QTextDocument *doc = textDocument();
         if (!doc)
             return;

         const QString filePath = fileUrl.toLocalFile();
         const bool isHtml = QFileInfo(filePath).suffix().contains(QLatin1String("htm"));
         QFile file(filePath);
         if (!file.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) {
             emit error(tr("Cannot save: ") + file.errorString());
             return;
         }
         file.write((isHtml ? doc->toHtml() : doc->toPlainText()).toUtf8());
         file.close();

         if (fileUrl == m_fileUrl)
             return;

         m_fileUrl = fileUrl;
         emit fileUrlChanged();
     }

     void DocumentHandler::reset()
     {
         emit fontFamilyChanged();
         emit alignmentChanged();
         emit boldChanged();
         emit italicChanged();
         emit underlineChanged();
         emit fontSizeChanged();
         emit textColorChanged();
     }

     QTextCursor DocumentHandler::textCursor() const
     {
         QTextDocument *doc = textDocument();
         if (!doc)
             return QTextCursor();

         QTextCursor cursor = QTextCursor(doc);
         if (m_selectionStart != m_selectionEnd) {
             cursor.setPosition(m_selectionStart);
             cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor);
         } else {
             cursor.setPosition(m_cursorPosition);
         }
         return cursor;
     }

     QTextDocument *DocumentHandler::textDocument() const
     {
         if (!m_document)
             return nullptr;

         return m_document->textDocument();
     }

     void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format)
     {
         QTextCursor cursor = textCursor();
         if (!cursor.hasSelection())
             cursor.select(QTextCursor::WordUnderCursor);
         cursor.mergeCharFormat(format);
     }