documenthandler.cpp Example File
texteditor/src/documenthandler.cpp/**************************************************************************** ** ** 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 <QtGui/QTextDocument> #include <QtGui/QTextCursor> #include <QtGui/QFontDatabase> #include <QtCore/QFileInfo> DocumentHandler::DocumentHandler() : m_target(0) , m_doc(0) , m_cursorPosition(-1) , m_selectionStart(0) , m_selectionEnd(0) { } void DocumentHandler::setTarget(QQuickItem *target) { m_doc = 0; m_target = target; if (!m_target) return; QVariant doc = m_target->property("textDocument"); if (doc.canConvert<QQuickTextDocument*>()) { QQuickTextDocument *qqdoc = doc.value<QQuickTextDocument*>(); if (qqdoc) m_doc = qqdoc->textDocument(); } emit targetChanged(); } void DocumentHandler::setFileUrl(const QUrl &arg) { if (m_fileUrl != arg) { m_fileUrl = arg; QString fileName = QQmlFile::urlToLocalFileOrQrc(arg); 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(QString arg) { if (m_documentTitle != arg) { m_documentTitle = arg; emit documentTitleChanged(); } } void DocumentHandler::setText(const QString &arg) { if (m_text != arg) { m_text = arg; emit textChanged(); } } void DocumentHandler::saveAs(const QUrl &arg, const QString &fileType) { bool isHtml = fileType.contains(QLatin1String("htm")); QLatin1String ext(isHtml ? ".html" : ".txt"); QString localPath = arg.toLocalFile(); if (!localPath.endsWith(ext)) localPath += ext; 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) { m_selectionStart = position; } void DocumentHandler::setSelectionEnd(int position) { m_selectionEnd = position; } void DocumentHandler::setAlignment(Qt::Alignment a) { if (!m_doc) return; QTextBlockFormat fmt; fmt.setAlignment((Qt::Alignment) a); QTextCursor cursor = QTextCursor(m_doc); cursor.setPosition(m_selectionStart, QTextCursor::MoveAnchor); cursor.setPosition(m_selectionEnd, QTextCursor::KeepAnchor); cursor.mergeBlockFormat(fmt); 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 arg) { QTextCharFormat fmt; fmt.setFontWeight(arg ? QFont::Bold : QFont::Normal); mergeFormatOnWordOrSelection(fmt); emit boldChanged(); } void DocumentHandler::setItalic(bool arg) { QTextCharFormat fmt; fmt.setFontItalic(arg); mergeFormatOnWordOrSelection(fmt); emit italicChanged(); } void DocumentHandler::setUnderline(bool arg) { QTextCharFormat fmt; fmt.setFontUnderline(arg); mergeFormatOnWordOrSelection(fmt); 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 arg) { QTextCursor cursor = textCursor(); if (cursor.isNull()) return; QTextCharFormat format; format.setFontPointSize(arg); 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 &c) { QTextCursor cursor = textCursor(); if (cursor.isNull()) return; QTextCharFormat format; format.setForeground(QBrush(c)); 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 &arg) { QTextCursor cursor = textCursor(); if (cursor.isNull()) return; QTextCharFormat format; format.setFontFamily(arg); mergeFormatOnWordOrSelection(format); emit fontFamilyChanged(); } QStringList DocumentHandler::defaultFontSizes() const { // uhm... this is quite ugly QStringList sizes; QFontDatabase db; foreach (int size, db.standardSizes()) sizes.append(QString::number(size)); return sizes; }