diff options
author | Mitch Curtis <mitch.curtis@qt.io> | 2016-07-06 13:04:07 +0200 |
---|---|---|
committer | J-P Nurmi <jpnurmi@qt.io> | 2016-08-11 16:47:48 +0000 |
commit | fcf4a1ed81c547f24384e005e9776f478161c616 (patch) | |
tree | 373907ca5fc1f87d0780fb7e2e4a4e9c5c6109fa /examples/quickcontrols2/texteditor/documenthandler.cpp | |
parent | 4092df376916ad9477547ecd4ef4679dc59e0fdf (diff) |
Add Text Editor example
A follow up commit will contain the touch UI.
Change-Id: I26275fdd31294506821fa3e3e4a4bb63329665b9
Task-number: QTBUG-54952
Reviewed-by: J-P Nurmi <jpnurmi@qt.io>
Diffstat (limited to 'examples/quickcontrols2/texteditor/documenthandler.cpp')
-rw-r--r-- | examples/quickcontrols2/texteditor/documenthandler.cpp | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/examples/quickcontrols2/texteditor/documenthandler.cpp b/examples/quickcontrols2/texteditor/documenthandler.cpp new file mode 100644 index 00000000..2a13b211 --- /dev/null +++ b/examples/quickcontrols2/texteditor/documenthandler.cpp @@ -0,0 +1,381 @@ +/**************************************************************************** +** +** Copyright (C) 2016 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 <QFileInfo> +#include <QFontDatabase> +#include <QQmlFile> +#include <QQuickTextDocument> +#include <QTextCharFormat> +#include <QTextCodec> +#include <QTextCursor> +#include <QTextDocument> + +DocumentHandler::DocumentHandler(QObject *parent) + : QObject(parent) + , m_doc(nullptr) + , m_cursorPosition(-1) + , m_selectionStart(0) + , m_selectionEnd(0) +{ +} + +QQuickTextDocument *DocumentHandler::document() const +{ + return m_quickDoc; +} + +void DocumentHandler::setDocument(QQuickTextDocument *quickDoc) +{ + if (quickDoc == m_quickDoc) + return; + + m_quickDoc = quickDoc; + m_doc = nullptr; + + if (quickDoc) + m_doc = quickDoc->textDocument(); + + emit documentChanged(); +} + +void DocumentHandler::setFileUrl(const QUrl &fileUrl) +{ + if (fileUrl == m_fileUrl) + return; + + m_fileUrl = fileUrl; + QString fileName = QQmlFile::urlToLocalFileOrQrc(fileUrl); + if (QFile::exists(fileName)) { + QFile file(fileName); + if (file.open(QFile::ReadOnly)) { + QByteArray data = file.readAll(); + QTextCodec *codec = QTextCodec::codecForHtml(data); + setText(codec->toUnicode(data)); + if (m_doc) + m_doc->setModified(false); + if (fileName.isEmpty()) + m_documentTitle = QStringLiteral("untitled.txt"); + else + m_documentTitle = QFileInfo(fileName).fileName(); + + emit textChanged(); + emit documentTitleChanged(); + + reset(); + } + } + emit fileUrlChanged(); +} + +QString DocumentHandler::documentTitle() const +{ + return m_documentTitle; +} + +void DocumentHandler::setDocumentTitle(const QString &documentTitle) +{ + if (documentTitle == m_documentTitle) + return; + + m_documentTitle = documentTitle; + emit documentTitleChanged(); +} + +void DocumentHandler::setText(const QString &text) +{ + if (text == m_text) + return; + + m_text = text; + emit textChanged(); +} + +void DocumentHandler::saveAs(const QUrl &fileUrl, const QString &fileType) +{ + if (!m_doc) + return; + + // TODO: remove this when FileDialog gets suffix property + QString localPath = fileUrl.toLocalFile(); + QString extension = fileType; + if (extension.isEmpty()) { + if (QFile::exists(localPath)) { + extension = QFileInfo(localPath).suffix(); + } else { + const int periodIndex = localPath.indexOf(QLatin1Char('.')); + if (periodIndex != -1) + extension = localPath.mid(periodIndex); + } + } + + const bool isHtml = extension.contains(QLatin1String("htm")); + if (!localPath.endsWith(extension)) + localPath += extension; + QFile f(localPath); + if (!f.open(QFile::WriteOnly | QFile::Truncate | (isHtml ? QFile::NotOpen : QFile::Text))) { + emit error(tr("Cannot save: ") + f.errorString()); + return; + } + f.write((isHtml ? m_doc->toHtml() : m_doc->toPlainText()).toLocal8Bit()); + f.close(); + setFileUrl(QUrl::fromLocalFile(localPath)); +} + +QUrl DocumentHandler::fileUrl() const +{ + return m_fileUrl; +} + +QString DocumentHandler::text() const +{ + return m_text; +} + +void DocumentHandler::setCursorPosition(int position) +{ + if (position == m_cursorPosition) + return; + + m_cursorPosition = position; + + reset(); +} + +void DocumentHandler::reset() +{ + emit fontFamilyChanged(); + emit alignmentChanged(); + emit boldChanged(); + emit italicChanged(); + emit underlineChanged(); + emit fontSizeChanged(); + emit textColorChanged(); +} + +QTextCursor DocumentHandler::textCursor() const +{ + if (!m_doc) + return QTextCursor(); + + QTextCursor cursor = QTextCursor(m_doc); + if (m_selectionStart != m_selectionEnd) { + cursor.setPosition(m_selectionStart); + cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); + } else { + cursor.setPosition(m_cursorPosition); + } + return cursor; +} + +void DocumentHandler::mergeFormatOnWordOrSelection(const QTextCharFormat &format) +{ + QTextCursor cursor = textCursor(); + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + cursor.mergeCharFormat(format); +} + +void DocumentHandler::setSelectionStart(int position) +{ + if (position == m_selectionStart) + return; + + m_selectionStart = position; + emit selectionStartChanged(); +} + +void DocumentHandler::setSelectionEnd(int position) +{ + if (position == m_selectionEnd) + return; + + m_selectionEnd = position; + emit selectionEndChanged(); +} + +void DocumentHandler::setAlignment(Qt::Alignment alignment) +{ + if (!m_doc) + return; + + QTextBlockFormat format; + format.setAlignment(alignment); + QTextCursor cursor = textCursor(); + cursor.mergeBlockFormat(format); + emit alignmentChanged(); +} + +Qt::Alignment DocumentHandler::alignment() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return Qt::AlignLeft; + return textCursor().blockFormat().alignment(); +} + +bool DocumentHandler::bold() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontWeight() == QFont::Bold; +} + +bool DocumentHandler::italic() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontItalic(); +} + +bool DocumentHandler::underline() const +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return false; + return textCursor().charFormat().fontUnderline(); +} + +void DocumentHandler::setBold(bool bold) +{ + QTextCharFormat format; + format.setFontWeight(bold ? QFont::Bold : QFont::Normal); + mergeFormatOnWordOrSelection(format); + emit boldChanged(); +} + +void DocumentHandler::setItalic(bool italic) +{ + QTextCharFormat format; + format.setFontItalic(italic); + mergeFormatOnWordOrSelection(format); + emit italicChanged(); +} + +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 fontSize) +{ + if (fontSize <= 0) + return; + + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return; + + if (!cursor.hasSelection()) + cursor.select(QTextCursor::WordUnderCursor); + + if (cursor.charFormat().property(QTextFormat::FontPointSize).toInt() == fontSize) + return; + + QTextCharFormat format; + format.setFontPointSize(fontSize); + mergeFormatOnWordOrSelection(format); + emit fontSizeChanged(); +} + +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) +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return; + QTextCharFormat format; + format.setForeground(QBrush(color)); + mergeFormatOnWordOrSelection(format); + emit textColorChanged(); +} + +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 &fontFamily) +{ + QTextCursor cursor = textCursor(); + if (cursor.isNull()) + return; + QTextCharFormat format; + format.setFontFamily(fontFamily); + mergeFormatOnWordOrSelection(format); + emit fontFamilyChanged(); +} |