aboutsummaryrefslogtreecommitdiffstats
path: root/examples/quickcontrols2/texteditor
diff options
context:
space:
mode:
Diffstat (limited to 'examples/quickcontrols2/texteditor')
-rw-r--r--examples/quickcontrols2/texteditor/+touch/texteditor.html19
-rw-r--r--examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpgbin0 -> 76304 bytes
-rw-r--r--examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpgbin0 -> 31203 bytes
-rw-r--r--examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc122
-rw-r--r--examples/quickcontrols2/texteditor/documenthandler.cpp371
-rw-r--r--examples/quickcontrols2/texteditor/documenthandler.h170
-rw-r--r--examples/quickcontrols2/texteditor/fonts/fontello.ttfbin0 -> 10152 bytes
-rw-r--r--examples/quickcontrols2/texteditor/images/qt-logo.pngbin0 -> 5681 bytes
-rw-r--r--examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml260
-rw-r--r--examples/quickcontrols2/texteditor/qml/texteditor.qml442
-rw-r--r--examples/quickcontrols2/texteditor/qtquickcontrols2.conf11
-rw-r--r--examples/quickcontrols2/texteditor/texteditor.cpp89
-rw-r--r--examples/quickcontrols2/texteditor/texteditor.html44
-rw-r--r--examples/quickcontrols2/texteditor/texteditor.pro22
-rw-r--r--examples/quickcontrols2/texteditor/texteditor.qrc11
15 files changed, 1561 insertions, 0 deletions
diff --git a/examples/quickcontrols2/texteditor/+touch/texteditor.html b/examples/quickcontrols2/texteditor/+touch/texteditor.html
new file mode 100644
index 00000000..b5f03f25
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/+touch/texteditor.html
@@ -0,0 +1,19 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="qrichtext" content="1">
+ <title>Text Editor Example</title>
+</head>
+<body>
+<body>
+ <p align="center">
+ <img src="qrc:/images/qt-logo.png" />
+ </p>
+ <h2 align="center">
+ Qt Quick Controls 2
+ </h2>
+ <p align="center">
+ This example demonstrates a modern rich text editor.
+ </p>
+</body>
+</html>
diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg
new file mode 100644
index 00000000..259e0e8b
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-desktop.jpg
Binary files differ
diff --git a/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg
new file mode 100644
index 00000000..6a924cdf
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/doc/images/qtquickcontrols2-texteditor-touch.jpg
Binary files differ
diff --git a/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc
new file mode 100644
index 00000000..1fee54ce
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/doc/src/qtquickcontrols2-texteditor.qdoc
@@ -0,0 +1,122 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the documentation of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:FDL$
+** 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 http://www.qt.io/terms-conditions. For further
+** information use the contact form at http://www.qt.io/contact-us.
+**
+** GNU Free Documentation License Usage
+** Alternatively, this file may be used under the terms of the GNU Free
+** Documentation License version 1.3 as published by the Free Software
+** Foundation and appearing in the file included in the packaging of
+** this file. Please review the following information to ensure
+** the GNU Free Documentation License version 1.3 requirements
+** will be met: http://www.gnu.org/copyleft/fdl.html.
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+/*!
+ \example texteditor
+ \title Qt Quick Controls 2 - Text Editor
+ \ingroup qtquickcontrols2-examples
+ \brief A QML app using Qt Quick Controls 2 and a C++ class to
+ provide a fully-functional rich-text editor application.
+
+ The \e {Text Editor Example} presents a sample HTML file using the TextArea
+ control, preserving the HTML formatting. The application comes with two user
+ interfaces; one for traditional desktop platforms with a mouse pointer, and
+ another simpler, touch-oriented version.
+
+ \section1 Desktop User Interface
+
+ \image qtquickcontrols2-texteditor-desktop.jpg
+
+ The desktop version is a complete text editor with capabilities for formatting
+ text, and opening and saving HTML and plain text files. It demonstrates the
+ native-looking dialogs and menus using the \l{Qt Labs Platform} module. These
+ types are mostly suitable for desktop platforms with support for multiple
+ top-level windows, a mouse pointer, and moderate screen size.
+
+ The desktop UI uses FileDialog for opening and saving files:
+
+ \quotefromfile texteditor/qml/texteditor.qml
+ \skipto FileDialog
+ \printuntil /\bsaveAs\b/
+ \printline }
+
+ It uses FontDialog and ColorDialog for choosing fonts and colors:
+
+ \skipto FontDialog
+ \printuntil /.*colorDialog$/
+ \printuntil /^\s{4}\}$/
+
+ It also uses \l[QML QtLabsPlatform]{Menu} and
+ \l[QML QtLabsPlatform]{MenuItem} that provide a context menu to format text
+ within:
+
+ \skipto /\bMenu\b/
+ \printuntil /^\s{4}\}$/
+
+ \note There is also a standard menubar with more options than the
+ context menu.
+
+ \section1 Touch User Interface
+
+ \image qtquickcontrols2-texteditor-touch.jpg
+
+ The touch user interface is a simplified version of the text editor. It is
+ suitable for touch devices with limited screen size. The example uses
+ \l{Using File Selectors with Qt Quick Controls 2}{file selectors} to load
+ the appropriate user interface automatically.
+
+ Unlike the desktop version, which uses top-level dialogs, the touch version
+ uses the QML \l Dialog type, which is not a top-level window. This type of
+ dialog is fully supported on mobile and embedded platforms that do not support
+ multiple top-level windows.
+
+ \quotefromfile texteditor/qml/+touch/texteditor.qml
+ \skipto /\bDialog\b/
+ \printuntil /^\s{4}\}$/
+
+ \section1 C++ Backend
+
+ Both user interfaces use the same C++ backend, which supports opening, formatting,
+ and editing a document. The C++ class, \c DocumentHandler, extends QObject and is
+ registered as a QML type under the namespace \c {io.qt.examples.texteditor 1.0}.
+
+ The following snippets show how the type is registered under a namespace and later
+ imported and instantiated by \e main.qml. For more information about registering C++
+ classes as QML types, see \l {Defining QML Types from C++}.
+
+ QML type registration:
+
+ \code
+ #include <QtQml/qqml.h>
+ ...
+ qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler");
+ ...
+ \endcode
+
+ QML namespace import:
+
+ \code
+ import io.qt.examples.texteditor 1.0
+ \endcode
+
+ QML instance:
+
+ \quotefromfile texteditor/qml/texteditor.qml
+ \skipto DocumentHandler
+ \printuntil /^\s{4}\}$/
+
+ \include examples-run.qdocinc
+*/
diff --git a/examples/quickcontrols2/texteditor/documenthandler.cpp b/examples/quickcontrols2/texteditor/documenthandler.cpp
new file mode 100644
index 00000000..e57946fd
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/documenthandler.cpp
@@ -0,0 +1,371 @@
+/****************************************************************************
+**
+** 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 <QFile>
+#include <QFileInfo>
+#include <QFileSelector>
+#include <QQmlFile>
+#include <QQmlFileSelector>
+#include <QQuickTextDocument>
+#include <QTextCharFormat>
+#include <QTextCodec>
+#include <QTextDocument>
+
+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);
+}
diff --git a/examples/quickcontrols2/texteditor/documenthandler.h b/examples/quickcontrols2/texteditor/documenthandler.h
new file mode 100644
index 00000000..dd3c3988
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/documenthandler.h
@@ -0,0 +1,170 @@
+/****************************************************************************
+**
+** 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$
+**
+****************************************************************************/
+
+#ifndef DOCUMENTHANDLER_H
+#define DOCUMENTHANDLER_H
+
+#include <QFont>
+#include <QObject>
+#include <QTextCursor>
+#include <QUrl>
+
+QT_BEGIN_NAMESPACE
+class QTextDocument;
+class QQuickTextDocument;
+QT_END_NAMESPACE
+
+class DocumentHandler : public QObject
+{
+ Q_OBJECT
+
+ Q_PROPERTY(QQuickTextDocument *document READ document WRITE setDocument NOTIFY documentChanged)
+ Q_PROPERTY(int cursorPosition READ cursorPosition WRITE setCursorPosition NOTIFY cursorPositionChanged)
+ Q_PROPERTY(int selectionStart READ selectionStart WRITE setSelectionStart NOTIFY selectionStartChanged)
+ Q_PROPERTY(int selectionEnd READ selectionEnd WRITE setSelectionEnd NOTIFY selectionEndChanged)
+
+ Q_PROPERTY(QColor textColor READ textColor WRITE setTextColor NOTIFY textColorChanged)
+ Q_PROPERTY(QString fontFamily READ fontFamily WRITE setFontFamily NOTIFY fontFamilyChanged)
+ Q_PROPERTY(Qt::Alignment alignment READ alignment WRITE setAlignment NOTIFY alignmentChanged)
+
+ Q_PROPERTY(bool bold READ bold WRITE setBold NOTIFY boldChanged)
+ Q_PROPERTY(bool italic READ italic WRITE setItalic NOTIFY italicChanged)
+ Q_PROPERTY(bool underline READ underline WRITE setUnderline NOTIFY underlineChanged)
+
+ Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
+
+ Q_PROPERTY(QString fileName READ fileName NOTIFY fileUrlChanged)
+ Q_PROPERTY(QString fileType READ fileType NOTIFY fileUrlChanged)
+ Q_PROPERTY(QUrl fileUrl READ fileUrl NOTIFY fileUrlChanged)
+
+public:
+ explicit DocumentHandler(QObject *parent = nullptr);
+
+ QQuickTextDocument *document() const;
+ void setDocument(QQuickTextDocument *document);
+
+ int cursorPosition() const;
+ void setCursorPosition(int position);
+
+ int selectionStart() const;
+ void setSelectionStart(int position);
+
+ int selectionEnd() const;
+ void setSelectionEnd(int position);
+
+ QString fontFamily() const;
+ void setFontFamily(const QString &family);
+
+ QColor textColor() const;
+ void setTextColor(const QColor &color);
+
+ Qt::Alignment alignment() const;
+ void setAlignment(Qt::Alignment alignment);
+
+ bool bold() const;
+ void setBold(bool bold);
+
+ bool italic() const;
+ void setItalic(bool italic);
+
+ bool underline() const;
+ void setUnderline(bool underline);
+
+ int fontSize() const;
+ void setFontSize(int size);
+
+ QString fileName() const;
+ QString fileType() const;
+ QUrl fileUrl() const;
+
+public Q_SLOTS:
+ void load(const QUrl &fileUrl);
+ void saveAs(const QUrl &fileUrl);
+
+Q_SIGNALS:
+ void documentChanged();
+ void cursorPositionChanged();
+ void selectionStartChanged();
+ void selectionEndChanged();
+
+ void fontFamilyChanged();
+ void textColorChanged();
+ void alignmentChanged();
+
+ void boldChanged();
+ void italicChanged();
+ void underlineChanged();
+
+ void fontSizeChanged();
+
+ void textChanged();
+ void fileUrlChanged();
+
+ void loaded(const QString &text);
+ void error(const QString &message);
+
+private:
+ void reset();
+ QTextCursor textCursor() const;
+ QTextDocument *textDocument() const;
+ void mergeFormatOnWordOrSelection(const QTextCharFormat &format);
+
+ QQuickTextDocument *m_document;
+
+ int m_cursorPosition;
+ int m_selectionStart;
+ int m_selectionEnd;
+
+ QFont m_font;
+ int m_fontSize;
+ QUrl m_fileUrl;
+};
+
+#endif // DOCUMENTHANDLER_H
diff --git a/examples/quickcontrols2/texteditor/fonts/fontello.ttf b/examples/quickcontrols2/texteditor/fonts/fontello.ttf
new file mode 100644
index 00000000..db957652
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/fonts/fontello.ttf
Binary files differ
diff --git a/examples/quickcontrols2/texteditor/images/qt-logo.png b/examples/quickcontrols2/texteditor/images/qt-logo.png
new file mode 100644
index 00000000..e16b4182
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/images/qt-logo.png
Binary files differ
diff --git a/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml
new file mode 100644
index 00000000..11d153f5
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/qml/+touch/texteditor.qml
@@ -0,0 +1,260 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Controls 2.1
+import QtQuick.Controls.Material 2.1
+import QtQuick.Layouts 1.3
+import QtQuick.Window 2.0
+
+import io.qt.examples.texteditor 1.0
+
+// TODO:
+// - make designer-friendly
+
+ApplicationWindow {
+ id: window
+ visible: true
+ title: document.fileName + " - Text Editor Example"
+
+ header: ToolBar {
+ leftPadding: 5
+
+ RowLayout {
+ anchors.fill: parent
+ spacing: 0
+
+ ToolButton {
+ id: doneEditingButton
+ font.family: "fontello"
+ text: "\uE80A" // icon-ok
+ opacity: !textArea.readOnly ? 1 : 0
+ onClicked: textArea.readOnly = true
+
+ Material.foreground: Material.accent
+ }
+
+ Label {
+ text: qsTr("Text Editor Example")
+ font.bold: true
+ font.pixelSize: 20
+ elide: Label.ElideRight
+ Layout.fillWidth: true
+ }
+
+ ToolButton {
+ font.family: "fontello"
+ text: "\uF142" // icon-ellipsis-vert
+ onClicked: menu.open()
+
+ Menu {
+ id: menu
+
+ MenuItem {
+ text: qsTr("About")
+ onTriggered: aboutDialog.open()
+ }
+ }
+ }
+ }
+ }
+
+ DocumentHandler {
+ id: document
+ document: textArea.textDocument
+ cursorPosition: textArea.cursorPosition
+ selectionStart: textArea.selectionStart
+ selectionEnd: textArea.selectionEnd
+ // textColor: TODO
+ Component.onCompleted: document.load("qrc:/texteditor.html")
+ onLoaded: {
+ textArea.text = text
+ }
+ onError: {
+ errorDialog.text = message
+ errorDialog.visible = true
+ }
+ }
+
+ Flickable {
+ id: flickable
+ flickableDirection: Flickable.VerticalFlick
+ anchors.fill: parent
+
+ TextArea.flickable: TextArea {
+ id: textArea
+ textFormat: Qt.RichText
+ wrapMode: TextArea.Wrap
+ readOnly: true
+ persistentSelection: true
+ // Different styles have different padding and background
+ // decorations, but since this editor is almost taking up the
+ // entire window, we don't need them.
+ leftPadding: 6
+ rightPadding: 6
+ topPadding: 0
+ bottomPadding: 0
+ background: null
+
+ onLinkActivated: Qt.openUrlExternally(link)
+ }
+
+ ScrollBar.vertical: ScrollBar {}
+ }
+
+ footer: ToolBar {
+ visible: !textArea.readOnly && textArea.activeFocus
+
+ Material.primary: "#E0E0E0"
+ Material.elevation: 0
+
+ Flickable {
+ anchors.fill: parent
+ contentWidth: toolRow.implicitWidth
+ flickableDirection: Qt.Horizontal
+ boundsBehavior: Flickable.StopAtBounds
+
+ Row {
+ id: toolRow
+
+ ToolButton {
+ id: boldButton
+ text: "\uE800" // icon-bold
+ font.family: "fontello"
+ // Don't want to close the virtual keyboard when this is clicked.
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.bold
+ onClicked: document.bold = !document.bold
+ }
+ ToolButton {
+ id: italicButton
+ text: "\uE801" // icon-italic
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.italic
+ onClicked: document.italic = !document.italic
+ }
+ ToolButton {
+ id: underlineButton
+ text: "\uF0CD" // icon-underline
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.underline
+ onClicked: document.underline = !document.underline
+ }
+
+ ToolSeparator {}
+
+ ToolButton {
+ id: alignLeftButton
+ text: "\uE803" // icon-align-left
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignLeft
+ onClicked: document.alignment = Qt.AlignLeft
+ }
+ ToolButton {
+ id: alignCenterButton
+ text: "\uE804" // icon-align-center
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignHCenter
+ onClicked: document.alignment = Qt.AlignHCenter
+ }
+ ToolButton {
+ id: alignRightButton
+ text: "\uE805" // icon-align-right
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignRight
+ onClicked: document.alignment = Qt.AlignRight
+ }
+ ToolButton {
+ id: alignJustifyButton
+ text: "\uE806" // icon-align-justify
+ font.family: "fontello"
+ focusPolicy: Qt.NoFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignJustify
+ onClicked: document.alignment = Qt.AlignJustify
+ }
+ }
+ }
+ }
+
+ RoundButton {
+ id: editButton
+ font.family: "fontello"
+ text: "\uE809" // icon-pencil
+ width: 48
+ height: width
+ // Don't want to use anchors for the y position, because it will anchor
+ // to the footer, leaving a large vertical gap.
+ y: parent.height - height - 12
+ anchors.right: parent.right
+ anchors.margins: 12
+ visible: textArea.readOnly
+ highlighted: true
+
+ onClicked: {
+ textArea.readOnly = false
+ // Force focus on the text area so the cursor and footer show up.
+ textArea.forceActiveFocus()
+ }
+ }
+
+ Dialog {
+ id: aboutDialog
+ standardButtons: Dialog.Ok
+ modal: true
+ x: parent.width / 2 - width / 2
+ y: parent.height / 2 - height / 2
+
+ contentItem: Label {
+ text: qsTr("Qt Quick Controls 2 - Text Editor Example")
+ }
+ }
+}
diff --git a/examples/quickcontrols2/texteditor/qml/texteditor.qml b/examples/quickcontrols2/texteditor/qml/texteditor.qml
new file mode 100644
index 00000000..2247e8f1
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/qml/texteditor.qml
@@ -0,0 +1,442 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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$
+**
+****************************************************************************/
+
+import QtQuick 2.8
+import QtQuick.Controls 2.1
+import QtQuick.Window 2.0
+import Qt.labs.platform 1.0
+
+import io.qt.examples.texteditor 1.0
+
+// TODO:
+// - make designer-friendly
+
+ApplicationWindow {
+ id: window
+ width: 1024
+ height: 600
+ visible: true
+ title: document.fileName + " - Text Editor Example"
+
+ Component.onCompleted: {
+ x = Screen.width / 2 - width / 2
+ y = Screen.height / 2 - height / 2
+ }
+
+ Shortcut {
+ sequence: StandardKey.Open
+ onActivated: openDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.SaveAs
+ onActivated: saveDialog.open()
+ }
+ Shortcut {
+ sequence: StandardKey.Quit
+ onActivated: Qt.quit()
+ }
+ Shortcut {
+ sequence: StandardKey.Copy
+ onActivated: textArea.copy()
+ }
+ Shortcut {
+ sequence: StandardKey.Cut
+ onActivated: textArea.cut()
+ }
+ Shortcut {
+ sequence: StandardKey.Paste
+ onActivated: textArea.paste()
+ }
+ Shortcut {
+ sequence: StandardKey.Bold
+ onActivated: document.bold = !document.bold
+ }
+ Shortcut {
+ sequence: StandardKey.Italic
+ onActivated: document.italic = !document.italic
+ }
+ Shortcut {
+ sequence: StandardKey.Underline
+ onActivated: document.underline = !document.underline
+ }
+
+ MenuBar {
+ Menu {
+ title: qsTr("&File")
+
+ MenuItem {
+ text: qsTr("&Open")
+ onTriggered: openDialog.open()
+ }
+ MenuItem {
+ text: qsTr("&Save As...")
+ onTriggered: saveDialog.open()
+ }
+ MenuItem {
+ text: qsTr("&Quit")
+ onTriggered: Qt.quit()
+ }
+ }
+
+ Menu {
+ title: qsTr("&Edit")
+
+ MenuItem {
+ text: qsTr("&Copy")
+ enabled: textArea.selectedText
+ onTriggered: textArea.copy()
+ }
+ MenuItem {
+ text: qsTr("Cu&t")
+ enabled: textArea.selectedText
+ onTriggered: textArea.cut()
+ }
+ MenuItem {
+ text: qsTr("&Paste")
+ enabled: textArea.canPaste
+ onTriggered: textArea.paste()
+ }
+ }
+
+ Menu {
+ title: qsTr("F&ormat")
+
+ MenuItem {
+ text: qsTr("&Bold")
+ checkable: true
+ checked: document.bold
+ onTriggered: document.bold = !document.bold
+ }
+ MenuItem {
+ text: qsTr("&Italic")
+ checkable: true
+ checked: document.italic
+ onTriggered: document.italic = !document.italic
+ }
+ MenuItem {
+ text: qsTr("&Underline")
+ checkable: true
+ checked: document.underline
+ onTriggered: document.underline = !document.underline
+ }
+ }
+ }
+
+ FileDialog {
+ id: openDialog
+ fileMode: FileDialog.OpenFile
+ selectedNameFilter.index: 1
+ nameFilters: ["Text files (*.txt)", "HTML files (*.html *.htm)"]
+ folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
+ onAccepted: document.load(file)
+ }
+
+ FileDialog {
+ id: saveDialog
+ fileMode: FileDialog.SaveFile
+ defaultSuffix: document.fileType
+ nameFilters: openDialog.nameFilters
+ selectedNameFilter.index: document.fileType === "txt" ? 0 : 1
+ folder: StandardPaths.writableLocation(StandardPaths.DocumentsLocation)
+ onAccepted: document.saveAs(file)
+ }
+
+ FontDialog {
+ id: fontDialog
+ onAccepted: {
+ document.fontFamily = font.family;
+ document.fontSize = font.pointSize;
+ }
+ }
+
+ ColorDialog {
+ id: colorDialog
+ currentColor: "black"
+ }
+
+ MessageDialog {
+ id: errorDialog
+ }
+
+ header: ToolBar {
+ leftPadding: 8
+
+ Flow {
+ id: flow
+ width: parent.width
+
+ Row {
+ id: fileRow
+ ToolButton {
+ id: openButton
+ text: "\uF115" // icon-folder-open-empty
+ font.family: "fontello"
+ onClicked: openDialog.open()
+ }
+ ToolSeparator {
+ contentItem.visible: fileRow.y === editRow.y
+ }
+ }
+
+ Row {
+ id: editRow
+ ToolButton {
+ id: copyButton
+ text: "\uF0C5" // icon-docs
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ enabled: textArea.selectedText
+ onClicked: textArea.copy()
+ }
+ ToolButton {
+ id: cutButton
+ text: "\uE802" // icon-scissors
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ enabled: textArea.selectedText
+ onClicked: textArea.cut()
+ }
+ ToolButton {
+ id: pasteButton
+ text: "\uF0EA" // icon-paste
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ enabled: textArea.canPaste
+ onClicked: textArea.paste()
+ }
+ ToolSeparator {
+ contentItem.visible: editRow.y === formatRow.y
+ }
+ }
+
+ Row {
+ id: formatRow
+ ToolButton {
+ id: boldButton
+ text: "\uE800" // icon-bold
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.bold
+ onClicked: document.bold = !document.bold
+ }
+ ToolButton {
+ id: italicButton
+ text: "\uE801" // icon-italic
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.italic
+ onClicked: document.italic = !document.italic
+ }
+ ToolButton {
+ id: underlineButton
+ text: "\uF0CD" // icon-underline
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.underline
+ onClicked: document.underline = !document.underline
+ }
+ ToolButton {
+ id: fontFamilyToolButton
+ text: qsTr("\uE808") // icon-font
+ font.family: "fontello"
+ font.bold: document.bold
+ font.italic: document.italic
+ font.underline: document.underline
+ onClicked: {
+ fontDialog.currentFont.family = document.fontFamily;
+ fontDialog.currentFont.pointSize = document.fontSize;
+ fontDialog.open();
+ }
+ }
+ ToolButton {
+ id: textColorButton
+ text: "\uF1FC" // icon-brush
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ onClicked: colorDialog.open()
+
+ Rectangle {
+ width: aFontMetrics.width + 3
+ height: 2
+ color: document.textColor
+ parent: textColorButton.contentItem
+ anchors.horizontalCenter: parent.horizontalCenter
+ anchors.baseline: parent.baseline
+ anchors.baselineOffset: 6
+
+ TextMetrics {
+ id: aFontMetrics
+ font: textColorButton.font
+ text: textColorButton.text
+ }
+ }
+ }
+ ToolSeparator {
+ contentItem.visible: formatRow.y === alignRow.y
+ }
+ }
+
+ Row {
+ id: alignRow
+ ToolButton {
+ id: alignLeftButton
+ text: "\uE803" // icon-align-left
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignLeft
+ onClicked: document.alignment = Qt.AlignLeft
+ }
+ ToolButton {
+ id: alignCenterButton
+ text: "\uE804" // icon-align-center
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignHCenter
+ onClicked: document.alignment = Qt.AlignHCenter
+ }
+ ToolButton {
+ id: alignRightButton
+ text: "\uE805" // icon-align-right
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignRight
+ onClicked: document.alignment = Qt.AlignRight
+ }
+ ToolButton {
+ id: alignJustifyButton
+ text: "\uE806" // icon-align-justify
+ font.family: "fontello"
+ focusPolicy: Qt.TabFocus
+ checkable: true
+ checked: document.alignment == Qt.AlignJustify
+ onClicked: document.alignment = Qt.AlignJustify
+ }
+ }
+ }
+ }
+
+ DocumentHandler {
+ id: document
+ document: textArea.textDocument
+ cursorPosition: textArea.cursorPosition
+ selectionStart: textArea.selectionStart
+ selectionEnd: textArea.selectionEnd
+ textColor: colorDialog.color
+ Component.onCompleted: document.load("qrc:/texteditor.html")
+ onLoaded: {
+ textArea.text = text
+ }
+ onError: {
+ errorDialog.text = message
+ errorDialog.visible = true
+ }
+ }
+
+ Flickable {
+ id: flickable
+ flickableDirection: Flickable.VerticalFlick
+ anchors.fill: parent
+
+ TextArea.flickable: TextArea {
+ id: textArea
+ textFormat: Qt.RichText
+ wrapMode: TextArea.Wrap
+ focus: true
+ selectByMouse: true
+ persistentSelection: true
+ // Different styles have different padding and background
+ // decorations, but since this editor is almost taking up the
+ // entire window, we don't need them.
+ leftPadding: 6
+ rightPadding: 6
+ topPadding: 0
+ bottomPadding: 0
+ background: null
+
+ MouseArea {
+ acceptedButtons: Qt.RightButton
+ anchors.fill: parent
+ onClicked: contextMenu.open()
+ }
+
+ onLinkActivated: Qt.openUrlExternally(link)
+ }
+
+ ScrollBar.vertical: ScrollBar {}
+ }
+
+ Menu {
+ id: contextMenu
+
+ MenuItem {
+ text: qsTr("Copy")
+ enabled: textArea.selectedText
+ onTriggered: textArea.copy()
+ }
+ MenuItem {
+ text: qsTr("Cut")
+ enabled: textArea.selectedText
+ onTriggered: textArea.cut()
+ }
+ MenuItem {
+ text: qsTr("Paste")
+ enabled: textArea.canPaste
+ onTriggered: textArea.paste()
+ }
+
+ MenuSeparator {}
+
+ MenuItem {
+ text: qsTr("Font...")
+ onTriggered: fontDialog.open()
+ }
+
+ MenuItem {
+ text: qsTr("Color...")
+ onTriggered: colorDialog.open()
+ }
+ }
+}
diff --git a/examples/quickcontrols2/texteditor/qtquickcontrols2.conf b/examples/quickcontrols2/texteditor/qtquickcontrols2.conf
new file mode 100644
index 00000000..ecac617f
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/qtquickcontrols2.conf
@@ -0,0 +1,11 @@
+[Controls]
+Style=Material
+
+[Material]
+Primary=White
+Foreground=#444444
+Accent=Blue
+Theme=System
+
+[Universal]
+Theme=System
diff --git a/examples/quickcontrols2/texteditor/texteditor.cpp b/examples/quickcontrols2/texteditor/texteditor.cpp
new file mode 100644
index 00000000..10ba675c
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/texteditor.cpp
@@ -0,0 +1,89 @@
+/****************************************************************************
+**
+** Copyright (C) 2016 The Qt Company Ltd.
+** Contact: http://www.qt.io/licensing/
+**
+** This file is part of the examples of the Qt Toolkit.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** 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$
+**
+****************************************************************************/
+
+#ifdef QT_WIDGETS_LIB
+#include <QApplication>
+#else
+#include <QGuiApplication>
+#endif
+#include <QFontDatabase>
+#include <QDebug>
+#include <QQmlApplicationEngine>
+#include <QQmlContext>
+#include <QQmlFileSelector>
+#include <QQuickStyle>
+
+#include "documenthandler.h"
+
+int main(int argc, char *argv[])
+{
+ QGuiApplication::setApplicationName("Text Editor");
+ QGuiApplication::setOrganizationName("QtProject");
+ QGuiApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
+
+#ifdef QT_WIDGETS_LIB
+ QApplication app(argc, argv);
+#else
+ QGuiApplication app(argc, argv);
+#endif
+
+ QFontDatabase fontDatabase;
+ if (fontDatabase.addApplicationFont(":/fonts/fontello.ttf") == -1)
+ qWarning() << "Failed to load fontello.ttf";
+
+ qmlRegisterType<DocumentHandler>("io.qt.examples.texteditor", 1, 0, "DocumentHandler");
+
+ QStringList selectors;
+#ifdef QT_EXTRA_FILE_SELECTOR
+ selectors += QT_EXTRA_FILE_SELECTOR;
+#else
+ if (app.arguments().contains("-touch"))
+ selectors += "touch";
+#endif
+
+ QQmlApplicationEngine engine;
+ QQmlFileSelector::get(&engine)->setExtraSelectors(selectors);
+
+ engine.load(QUrl("qrc:/qml/texteditor.qml"));
+ if (engine.rootObjects().isEmpty())
+ return -1;
+
+ return app.exec();
+}
diff --git a/examples/quickcontrols2/texteditor/texteditor.html b/examples/quickcontrols2/texteditor/texteditor.html
new file mode 100644
index 00000000..1310da42
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/texteditor.html
@@ -0,0 +1,44 @@
+<html>
+<head>
+ <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+ <meta name="qrichtext" content="1">
+ <title>Text Editor Example</title>
+ <style type="text/css">
+ p,
+ body, <!-- specifiying font-size for body seems to be necessary to avoid bullet points being incorrectly positioned -->
+ li {
+ white-space: pre-wrap;
+ font-size:11pt;
+ }
+ </style>
+</head>
+<body>
+ <p align="center">
+ <img src="qrc:/images/qt-logo.png" />
+ </p>
+ <h2 align="center">
+ Qt Quick Controls 2
+ </h2>
+ <p align="center">
+ This example demonstrates a modern rich text editor. The UI uses Qt Labs Platforms to provide native menus and dialogs.
+ </p>
+ <br />
+ <br />
+ <br />
+
+ <p>
+ Below you'll find a list of the native controls used in this application.
+ </p>
+
+ <ul>
+ <!-- TODO: update the links before the 5.8 release -->
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menu.html">Menu</a> - provides a QML API for native platform menu popups.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menubar.html">MenuBar</a> - provides a QML API for native platform menubars.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-menuitem.html">MenuItem</a> - provides a QML API for native platform menu items.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-filedialog.html">FileDialog</a> - provides a QML API for native platform file dialogs.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-fontdialog.html">FontDialog</a> - provides a QML API for native platform font dialogs.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-colordialog.html">ColorDialog</a> - provides a QML API for native platform color dialogs.</li>
+ <li><a href="http://doc-snapshots.qt.io/qt5-dev/qml-qt-labs-platform-messagedialog.html">MessageDialog</a> - provides a QML API for native platform message dialogs.</li>
+ </ul>
+</body>
+</html>
diff --git a/examples/quickcontrols2/texteditor/texteditor.pro b/examples/quickcontrols2/texteditor/texteditor.pro
new file mode 100644
index 00000000..deb24576
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/texteditor.pro
@@ -0,0 +1,22 @@
+TEMPLATE = app
+TARGET = texteditor
+QT += quick quickcontrols2
+qtHaveModule(widgets): QT += widgets
+
+cross_compile: DEFINES += QT_EXTRA_FILE_SELECTOR=\\\"touch\\\"
+
+HEADERS += \
+ documenthandler.h
+
+SOURCES += \
+ texteditor.cpp \
+ documenthandler.cpp
+
+OTHER_FILES += \
+ qml/*.qml
+
+RESOURCES += \
+ texteditor.qrc
+
+target.path = $$[QT_INSTALL_EXAMPLES]/quickcontrols2/texteditor
+INSTALLS += target
diff --git a/examples/quickcontrols2/texteditor/texteditor.qrc b/examples/quickcontrols2/texteditor/texteditor.qrc
new file mode 100644
index 00000000..8f2da843
--- /dev/null
+++ b/examples/quickcontrols2/texteditor/texteditor.qrc
@@ -0,0 +1,11 @@
+<RCC>
+ <qresource prefix="/">
+ <file>qtquickcontrols2.conf</file>
+ <file>images/qt-logo.png</file>
+ <file>fonts/fontello.ttf</file>
+ <file>qml/texteditor.qml</file>
+ <file>texteditor.html</file>
+ <file>qml/+touch/texteditor.qml</file>
+ <file>+touch/texteditor.html</file>
+ </qresource>
+</RCC>