textedit.cpp Example File
richtext/textedit/textedit.cpp
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the demonstration applications 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 <QAction>
#include <QApplication>
#include <QClipboard>
#include <QColorDialog>
#include <QComboBox>
#include <QFontComboBox>
#include <QFile>
#include <QFileDialog>
#include <QFileInfo>
#include <QFontDatabase>
#include <QMenu>
#include <QMenuBar>
#include <QTextCodec>
#include <QTextEdit>
#include <QStatusBar>
#include <QToolBar>
#include <QTextCursor>
#include <QTextDocumentWriter>
#include <QTextList>
#include <QtDebug>
#include <QCloseEvent>
#include <QMessageBox>
#include <QMimeData>
#if defined(QT_PRINTSUPPORT_LIB)
#include <QtPrintSupport/qtprintsupportglobal.h>
#if QT_CONFIG(printer)
#if QT_CONFIG(printdialog)
#include <QPrintDialog>
#endif
#include <QPrinter>
#if QT_CONFIG(printpreviewdialog)
#include <QPrintPreviewDialog>
#endif
#endif
#endif
#include "textedit.h"
#ifdef Q_OS_MAC
const QString rsrcPath = ":/images/mac" ;
#else
const QString rsrcPath = ":/images/win" ;
#endif
TextEdit:: TextEdit(QWidget * parent)
: QMainWindow (parent)
{
#ifdef Q_OS_OSX
setUnifiedTitleAndToolBarOnMac(true );
#endif
setWindowTitle(QCoreApplication :: applicationName());
textEdit = new QTextEdit (this );
connect(textEdit, & QTextEdit :: currentCharFormatChanged,
this , & TextEdit:: currentCharFormatChanged);
connect(textEdit, & QTextEdit :: cursorPositionChanged,
this , & TextEdit:: cursorPositionChanged);
setCentralWidget(textEdit);
setToolButtonStyle(Qt :: ToolButtonFollowStyle);
setupFileActions();
setupEditActions();
setupTextActions();
{
QMenu * helpMenu = menuBar()- > addMenu(tr("Help" ));
helpMenu- > addAction(tr("About" ), this , & TextEdit:: about);
helpMenu- > addAction(tr("About &Qt" ), qApp , & QApplication :: aboutQt);
}
QFont textFont("Helvetica" );
textFont. setStyleHint(QFont :: SansSerif);
textEdit- > setFont(textFont);
fontChanged(textEdit- > font());
colorChanged(textEdit- > textColor());
alignmentChanged(textEdit- > alignment());
connect(textEdit- > document(), & QTextDocument :: modificationChanged,
actionSave, & QAction :: setEnabled);
connect(textEdit- > document(), & QTextDocument :: modificationChanged,
this , & QWidget :: setWindowModified);
connect(textEdit- > document(), & QTextDocument :: undoAvailable,
actionUndo, & QAction :: setEnabled);
connect(textEdit- > document(), & QTextDocument :: redoAvailable,
actionRedo, & QAction :: setEnabled);
setWindowModified(textEdit- > document()- > isModified());
actionSave- > setEnabled(textEdit- > document()- > isModified());
actionUndo- > setEnabled(textEdit- > document()- > isUndoAvailable());
actionRedo- > setEnabled(textEdit- > document()- > isRedoAvailable());
#ifndef QT_NO_CLIPBOARD
actionCut- > setEnabled(false );
connect(textEdit, & QTextEdit :: copyAvailable, actionCut, & QAction :: setEnabled);
actionCopy- > setEnabled(false );
connect(textEdit, & QTextEdit :: copyAvailable, actionCopy, & QAction :: setEnabled);
connect(QApplication :: clipboard(), & QClipboard :: dataChanged, this , & TextEdit:: clipboardDataChanged);
#endif
textEdit- > setFocus();
setCurrentFileName(QString ());
#ifdef Q_OS_MACOS
// Use dark text on light background on macOS, also in dark mode.
QPalette pal = textEdit- > palette();
pal. setColor(QPalette :: Base, QColor (Qt :: white));
pal. setColor(QPalette :: Text, QColor (Qt :: black));
textEdit- > setPalette(pal);
#endif
}
void TextEdit:: closeEvent(QCloseEvent * e)
{
if (maybeSave())
e- > accept();
else
e- > ignore();
}
void TextEdit:: setupFileActions()
{
QToolBar * tb = addToolBar(tr("File Actions" ));
QMenu * menu = menuBar()- > addMenu(tr("&File" ));
const QIcon newIcon = QIcon :: fromTheme("document-new" , QIcon (rsrcPath + "/filenew.png" ));
QAction * a = menu- > addAction(newIcon, tr("&New" ), this , & TextEdit:: fileNew);
tb- > addAction(a);
a- > setPriority(QAction :: LowPriority);
a- > setShortcut(QKeySequence :: New);
const QIcon openIcon = QIcon :: fromTheme("document-open" , QIcon (rsrcPath + "/fileopen.png" ));
a = menu- > addAction(openIcon, tr("&Open..." ), this , & TextEdit:: fileOpen);
a- > setShortcut(QKeySequence :: Open);
tb- > addAction(a);
menu- > addSeparator();
const QIcon saveIcon = QIcon :: fromTheme("document-save" , QIcon (rsrcPath + "/filesave.png" ));
actionSave = menu- > addAction(saveIcon, tr("&Save" ), this , & TextEdit:: fileSave);
actionSave- > setShortcut(QKeySequence :: Save);
actionSave- > setEnabled(false );
tb- > addAction(actionSave);
a = menu- > addAction(tr("Save &As..." ), this , & TextEdit:: fileSaveAs);
a- > setPriority(QAction :: LowPriority);
menu- > addSeparator();
#ifndef QT_NO_PRINTER
const QIcon printIcon = QIcon :: fromTheme("document-print" , QIcon (rsrcPath + "/fileprint.png" ));
a = menu- > addAction(printIcon, tr("&Print..." ), this , & TextEdit:: filePrint);
a- > setPriority(QAction :: LowPriority);
a- > setShortcut(QKeySequence :: Print);
tb- > addAction(a);
const QIcon filePrintIcon = QIcon :: fromTheme("fileprint" , QIcon (rsrcPath + "/fileprint.png" ));
menu- > addAction(filePrintIcon, tr("Print Preview..." ), this , & TextEdit:: filePrintPreview);
const QIcon exportPdfIcon = QIcon :: fromTheme("exportpdf" , QIcon (rsrcPath + "/exportpdf.png" ));
a = menu- > addAction(exportPdfIcon, tr("&Export PDF..." ), this , & TextEdit:: filePrintPdf);
a- > setPriority(QAction :: LowPriority);
a- > setShortcut(Qt :: CTRL + Qt :: Key_D);
tb- > addAction(a);
menu- > addSeparator();
#endif
a = menu- > addAction(tr("&Quit" ), this , & QWidget :: close);
a- > setShortcut(Qt :: CTRL + Qt :: Key_Q);
}
void TextEdit:: setupEditActions()
{
QToolBar * tb = addToolBar(tr("Edit Actions" ));
QMenu * menu = menuBar()- > addMenu(tr("&Edit" ));
const QIcon undoIcon = QIcon :: fromTheme("edit-undo" , QIcon (rsrcPath + "/editundo.png" ));
actionUndo = menu- > addAction(undoIcon, tr("&Undo" ), textEdit, & QTextEdit :: undo);
actionUndo- > setShortcut(QKeySequence :: Undo);
tb- > addAction(actionUndo);
const QIcon redoIcon = QIcon :: fromTheme("edit-redo" , QIcon (rsrcPath + "/editredo.png" ));
actionRedo = menu- > addAction(redoIcon, tr("&Redo" ), textEdit, & QTextEdit :: redo);
actionRedo- > setPriority(QAction :: LowPriority);
actionRedo- > setShortcut(QKeySequence :: Redo);
tb- > addAction(actionRedo);
menu- > addSeparator();
#ifndef QT_NO_CLIPBOARD
const QIcon cutIcon = QIcon :: fromTheme("edit-cut" , QIcon (rsrcPath + "/editcut.png" ));
actionCut = menu- > addAction(cutIcon, tr("Cu&t" ), textEdit, & QTextEdit :: cut);
actionCut- > setPriority(QAction :: LowPriority);
actionCut- > setShortcut(QKeySequence :: Cut);
tb- > addAction(actionCut);
const QIcon copyIcon = QIcon :: fromTheme("edit-copy" , QIcon (rsrcPath + "/editcopy.png" ));
actionCopy = menu- > addAction(copyIcon, tr("&Copy" ), textEdit, & QTextEdit :: copy);
actionCopy- > setPriority(QAction :: LowPriority);
actionCopy- > setShortcut(QKeySequence :: Copy);
tb- > addAction(actionCopy);
const QIcon pasteIcon = QIcon :: fromTheme("edit-paste" , QIcon (rsrcPath + "/editpaste.png" ));
actionPaste = menu- > addAction(pasteIcon, tr("&Paste" ), textEdit, & QTextEdit :: paste);
actionPaste- > setPriority(QAction :: LowPriority);
actionPaste- > setShortcut(QKeySequence :: Paste);
tb- > addAction(actionPaste);
if (const QMimeData * md = QApplication :: clipboard()- > mimeData())
actionPaste- > setEnabled(md- > hasText());
#endif
}
void TextEdit:: setupTextActions()
{
QToolBar * tb = addToolBar(tr("Format Actions" ));
QMenu * menu = menuBar()- > addMenu(tr("F&ormat" ));
const QIcon boldIcon = QIcon :: fromTheme("format-text-bold" , QIcon (rsrcPath + "/textbold.png" ));
actionTextBold = menu- > addAction(boldIcon, tr("&Bold" ), this , & TextEdit:: textBold);
actionTextBold- > setShortcut(Qt :: CTRL + Qt :: Key_B);
actionTextBold- > setPriority(QAction :: LowPriority);
QFont bold;
bold. setBold(true );
actionTextBold- > setFont(bold);
tb- > addAction(actionTextBold);
actionTextBold- > setCheckable(true );
const QIcon italicIcon = QIcon :: fromTheme("format-text-italic" , QIcon (rsrcPath + "/textitalic.png" ));
actionTextItalic = menu- > addAction(italicIcon, tr("&Italic" ), this , & TextEdit:: textItalic);
actionTextItalic- > setPriority(QAction :: LowPriority);
actionTextItalic- > setShortcut(Qt :: CTRL + Qt :: Key_I);
QFont italic;
italic. setItalic(true );
actionTextItalic- > setFont(italic);
tb- > addAction(actionTextItalic);
actionTextItalic- > setCheckable(true );
const QIcon underlineIcon = QIcon :: fromTheme("format-text-underline" , QIcon (rsrcPath + "/textunder.png" ));
actionTextUnderline = menu- > addAction(underlineIcon, tr("&Underline" ), this , & TextEdit:: textUnderline);
actionTextUnderline- > setShortcut(Qt :: CTRL + Qt :: Key_U);
actionTextUnderline- > setPriority(QAction :: LowPriority);
QFont underline;
underline. setUnderline(true );
actionTextUnderline- > setFont(underline);
tb- > addAction(actionTextUnderline);
actionTextUnderline- > setCheckable(true );
menu- > addSeparator();
const QIcon leftIcon = QIcon :: fromTheme("format-justify-left" , QIcon (rsrcPath + "/textleft.png" ));
actionAlignLeft = new QAction (leftIcon, tr("&Left" ), this );
actionAlignLeft- > setShortcut(Qt :: CTRL + Qt :: Key_L);
actionAlignLeft- > setCheckable(true );
actionAlignLeft- > setPriority(QAction :: LowPriority);
const QIcon centerIcon = QIcon :: fromTheme("format-justify-center" , QIcon (rsrcPath + "/textcenter.png" ));
actionAlignCenter = new QAction (centerIcon, tr("C&enter" ), this );
actionAlignCenter- > setShortcut(Qt :: CTRL + Qt :: Key_E);
actionAlignCenter- > setCheckable(true );
actionAlignCenter- > setPriority(QAction :: LowPriority);
const QIcon rightIcon = QIcon :: fromTheme("format-justify-right" , QIcon (rsrcPath + "/textright.png" ));
actionAlignRight = new QAction (rightIcon, tr("&Right" ), this );
actionAlignRight- > setShortcut(Qt :: CTRL + Qt :: Key_R);
actionAlignRight- > setCheckable(true );
actionAlignRight- > setPriority(QAction :: LowPriority);
const QIcon fillIcon = QIcon :: fromTheme("format-justify-fill" , QIcon (rsrcPath + "/textjustify.png" ));
actionAlignJustify = new QAction (fillIcon, tr("&Justify" ), this );
actionAlignJustify- > setShortcut(Qt :: CTRL + Qt :: Key_J);
actionAlignJustify- > setCheckable(true );
actionAlignJustify- > setPriority(QAction :: LowPriority);
// Make sure the alignLeft is always left of the alignRight
QActionGroup * alignGroup = new QActionGroup (this );
connect(alignGroup, & QActionGroup :: triggered, this , & TextEdit:: textAlign);
if (QApplication :: isLeftToRight()) {
alignGroup- > addAction(actionAlignLeft);
alignGroup- > addAction(actionAlignCenter);
alignGroup- > addAction(actionAlignRight);
} else {
alignGroup- > addAction(actionAlignRight);
alignGroup- > addAction(actionAlignCenter);
alignGroup- > addAction(actionAlignLeft);
}
alignGroup- > addAction(actionAlignJustify);
tb- > addActions(alignGroup- > actions());
menu- > addActions(alignGroup- > actions());
menu- > addSeparator();
QPixmap pix(16 , 16 );
pix. fill(Qt :: black);
actionTextColor = menu- > addAction(pix, tr("&Color..." ), this , & TextEdit:: textColor);
tb- > addAction(actionTextColor);
tb = addToolBar(tr("Format Actions" ));
tb- > setAllowedAreas(Qt :: TopToolBarArea | Qt :: BottomToolBarArea);
addToolBarBreak(Qt :: TopToolBarArea);
addToolBar(tb);
comboStyle = new QComboBox (tb);
tb- > addWidget(comboStyle);
comboStyle- > addItem("Standard" );
comboStyle- > addItem("Bullet List (Disc)" );
comboStyle- > addItem("Bullet List (Circle)" );
comboStyle- > addItem("Bullet List (Square)" );
comboStyle- > addItem("Ordered List (Decimal)" );
comboStyle- > addItem("Ordered List (Alpha lower)" );
comboStyle- > addItem("Ordered List (Alpha upper)" );
comboStyle- > addItem("Ordered List (Roman lower)" );
comboStyle- > addItem("Ordered List (Roman upper)" );
comboStyle- > addItem("Heading 1" );
comboStyle- > addItem("Heading 2" );
comboStyle- > addItem("Heading 3" );
comboStyle- > addItem("Heading 4" );
comboStyle- > addItem("Heading 5" );
comboStyle- > addItem("Heading 6" );
connect(comboStyle, QOverload < int > :: of(& QComboBox :: activated), this , & TextEdit:: textStyle);
comboFont = new QFontComboBox (tb);
tb- > addWidget(comboFont);
connect(comboFont, QOverload < const QString & > :: of(& QComboBox :: activated), this , & TextEdit:: textFamily);
comboSize = new QComboBox (tb);
comboSize- > setObjectName("comboSize" );
tb- > addWidget(comboSize);
comboSize- > setEditable(true );
const QList < int > standardSizes = QFontDatabase :: standardSizes();
foreach (int size, standardSizes)
comboSize- > addItem(QString :: number(size));
comboSize- > setCurrentIndex(standardSizes. indexOf(QApplication :: font(). pointSize()));
connect(comboSize, QOverload < const QString & > :: of(& QComboBox :: activated), this , & TextEdit:: textSize);
}
bool TextEdit:: load(const QString & f)
{
if (! QFile :: exists(f))
return false ;
QFile file(f);
if (! file. open(QFile :: ReadOnly))
return false ;
QByteArray data = file. readAll();
QTextCodec * codec = Qt :: codecForHtml(data);
QString str = codec- > toUnicode(data);
if (Qt :: mightBeRichText(str)) {
textEdit- > setHtml(str);
} else {
str = QString :: fromLocal8Bit(data);
textEdit- > setPlainText(str);
}
setCurrentFileName(f);
return true ;
}
bool TextEdit:: maybeSave()
{
if (! textEdit- > document()- > isModified())
return true ;
const QMessageBox :: StandardButton ret =
QMessageBox :: warning(this , QCoreApplication :: applicationName(),
tr("The document has been modified.\n"
"Do you want to save your changes?" ),
QMessageBox :: Save | QMessageBox :: Discard | QMessageBox :: Cancel);
if (ret = = QMessageBox :: Save)
return fileSave();
else if (ret = = QMessageBox :: Cancel)
return false ;
return true ;
}
void TextEdit:: setCurrentFileName(const QString & fileName)
{
this - > fileName = fileName;
textEdit- > document()- > setModified(false );
QString shownName;
if (fileName. isEmpty())
shownName = "untitled.txt" ;
else
shownName = QFileInfo (fileName). fileName();
setWindowTitle(tr("%1[*] - %2" ). arg(shownName, QCoreApplication :: applicationName()));
setWindowModified(false );
}
void TextEdit:: fileNew()
{
if (maybeSave()) {
textEdit- > clear();
setCurrentFileName(QString ());
}
}
void TextEdit:: fileOpen()
{
QFileDialog fileDialog(this , tr("Open File..." ));
fileDialog. setAcceptMode(QFileDialog :: AcceptOpen);
fileDialog. setFileMode(QFileDialog :: ExistingFile);
fileDialog. setMimeTypeFilters(QStringList () < < "text/html" < < "text/plain" );
if (fileDialog. exec() ! = QDialog :: Accepted)
return ;
const QString fn = fileDialog. selectedFiles(). first();
if (load(fn))
statusBar()- > showMessage(tr("Opened \"%1\"" ). arg(QDir :: toNativeSeparators(fn)));
else
statusBar()- > showMessage(tr("Could not open \"%1\"" ). arg(QDir :: toNativeSeparators(fn)));
}
bool TextEdit:: fileSave()
{
if (fileName. isEmpty())
return fileSaveAs();
if (fileName. startsWith(QStringLiteral (":/" )))
return fileSaveAs();
QTextDocumentWriter writer(fileName);
bool success = writer. write(textEdit- > document());
if (success) {
textEdit- > document()- > setModified(false );
statusBar()- > showMessage(tr("Wrote \"%1\"" ). arg(QDir :: toNativeSeparators(fileName)));
} else {
statusBar()- > showMessage(tr("Could not write to file \"%1\"" )
. arg(QDir :: toNativeSeparators(fileName)));
}
return success;
}
bool TextEdit:: fileSaveAs()
{
QFileDialog fileDialog(this , tr("Save as..." ));
fileDialog. setAcceptMode(QFileDialog :: AcceptSave);
QStringList mimeTypes;
mimeTypes < < "application/vnd.oasis.opendocument.text" < < "text/html" < < "text/plain" ;
fileDialog. setMimeTypeFilters(mimeTypes);
fileDialog. setDefaultSuffix("odt" );
if (fileDialog. exec() ! = QDialog :: Accepted)
return false ;
const QString fn = fileDialog. selectedFiles(). first();
setCurrentFileName(fn);
return fileSave();
}
void TextEdit:: filePrint()
{
#if QT_CONFIG(printdialog)
QPrinter printer(QPrinter :: HighResolution);
QPrintDialog * dlg = new QPrintDialog (& printer, this );
if (textEdit- > textCursor(). hasSelection())
dlg- > addEnabledOption(QAbstractPrintDialog :: PrintSelection);
dlg- > setWindowTitle(tr("Print Document" ));
if (dlg- > exec() = = QDialog :: Accepted)
textEdit- > print(& printer);
delete dlg;
#endif
}
void TextEdit:: filePrintPreview()
{
#if QT_CONFIG(printpreviewdialog)
QPrinter printer(QPrinter :: HighResolution);
QPrintPreviewDialog preview(& printer, this );
connect(& preview, & QPrintPreviewDialog :: paintRequested, this , & TextEdit:: printPreview);
preview. exec();
#endif
}
void TextEdit:: printPreview(QPrinter * printer)
{
#ifdef QT_NO_PRINTER
Q_UNUSED(printer);
#else
textEdit- > print(printer);
#endif
}
void TextEdit:: filePrintPdf()
{
#ifndef QT_NO_PRINTER
QFileDialog fileDialog(this , tr("Export PDF" ));
fileDialog. setAcceptMode(QFileDialog :: AcceptSave);
fileDialog. setMimeTypeFilters(QStringList ("application/pdf" ));
fileDialog. setDefaultSuffix("pdf" );
if (fileDialog. exec() ! = QDialog :: Accepted)
return ;
QString fileName = fileDialog. selectedFiles(). first();
QPrinter printer(QPrinter :: HighResolution);
printer. setOutputFormat(QPrinter :: PdfFormat);
printer. setOutputFileName(fileName);
textEdit- > document()- > print(& printer);
statusBar()- > showMessage(tr("Exported \"%1\"" )
. arg(QDir :: toNativeSeparators(fileName)));
#endif
}
void TextEdit:: textBold()
{
QTextCharFormat fmt;
fmt. setFontWeight(actionTextBold- > isChecked() ? QFont :: Bold : QFont :: Normal);
mergeFormatOnWordOrSelection(fmt);
}
void TextEdit:: textUnderline()
{
QTextCharFormat fmt;
fmt. setFontUnderline(actionTextUnderline- > isChecked());
mergeFormatOnWordOrSelection(fmt);
}
void TextEdit:: textItalic()
{
QTextCharFormat fmt;
fmt. setFontItalic(actionTextItalic- > isChecked());
mergeFormatOnWordOrSelection(fmt);
}
void TextEdit:: textFamily(const QString & f)
{
QTextCharFormat fmt;
fmt. setFontFamily(f);
mergeFormatOnWordOrSelection(fmt);
}
void TextEdit:: textSize(const QString & p)
{
qreal pointSize = p. toFloat();
if (p. toFloat() > 0 ) {
QTextCharFormat fmt;
fmt. setFontPointSize(pointSize);
mergeFormatOnWordOrSelection(fmt);
}
}
void TextEdit:: textStyle(int styleIndex)
{
QTextCursor cursor = textEdit- > textCursor();
QTextListFormat :: Style style = QTextListFormat :: ListStyleUndefined;
switch (styleIndex) {
case 1 :
style = QTextListFormat :: ListDisc;
break ;
case 2 :
style = QTextListFormat :: ListCircle;
break ;
case 3 :
style = QTextListFormat :: ListSquare;
break ;
case 4 :
style = QTextListFormat :: ListDecimal;
break ;
case 5 :
style = QTextListFormat :: ListLowerAlpha;
break ;
case 6 :
style = QTextListFormat :: ListUpperAlpha;
break ;
case 7 :
style = QTextListFormat :: ListLowerRoman;
break ;
case 8 :
style = QTextListFormat :: ListUpperRoman;
break ;
default :
break ;
}
cursor. beginEditBlock();
QTextBlockFormat blockFmt = cursor. blockFormat();
if (style = = QTextListFormat :: ListStyleUndefined) {
blockFmt. setObjectIndex(- 1 );
int headingLevel = styleIndex > = 9 ? styleIndex - 9 + 1 : 0 ; // H1 to H6, or Standard
blockFmt. setHeadingLevel(headingLevel);
cursor. setBlockFormat(blockFmt);
int sizeAdjustment = headingLevel ? 4 - headingLevel : 0 ; // H1 to H6: +3 to -2
QTextCharFormat fmt;
fmt. setFontWeight(headingLevel ? QFont :: Bold : QFont :: Normal);
fmt. setProperty(QTextFormat :: FontSizeAdjustment, sizeAdjustment);
cursor. select(QTextCursor :: LineUnderCursor);
cursor. mergeCharFormat(fmt);
textEdit- > mergeCurrentCharFormat(fmt);
} else {
QTextListFormat listFmt;
if (cursor. currentList()) {
listFmt = cursor. currentList()- > format();
} else {
listFmt. setIndent(blockFmt. indent() + 1 );
blockFmt. setIndent(0 );
cursor. setBlockFormat(blockFmt);
}
listFmt. setStyle(style);
cursor. createList(listFmt);
}
cursor. endEditBlock();
}
void TextEdit:: textColor()
{
QColor col = QColorDialog :: getColor(textEdit- > textColor(), this );
if (! col. isValid())
return ;
QTextCharFormat fmt;
fmt. setForeground(col);
mergeFormatOnWordOrSelection(fmt);
colorChanged(col);
}
void TextEdit:: textAlign(QAction * a)
{
if (a = = actionAlignLeft)
textEdit- > setAlignment(Qt :: AlignLeft | Qt :: AlignAbsolute);
else if (a = = actionAlignCenter)
textEdit- > setAlignment(Qt :: AlignHCenter);
else if (a = = actionAlignRight)
textEdit- > setAlignment(Qt :: AlignRight | Qt :: AlignAbsolute);
else if (a = = actionAlignJustify)
textEdit- > setAlignment(Qt :: AlignJustify);
}
void TextEdit:: currentCharFormatChanged(const QTextCharFormat & format)
{
fontChanged(format. font());
colorChanged(format. foreground(). color());
}
void TextEdit:: cursorPositionChanged()
{
alignmentChanged(textEdit- > alignment());
QTextList * list = textEdit- > textCursor(). currentList();
if (list) {
switch (list- > format(). style()) {
case QTextListFormat :: ListDisc:
comboStyle- > setCurrentIndex(1 );
break ;
case QTextListFormat :: ListCircle:
comboStyle- > setCurrentIndex(2 );
break ;
case QTextListFormat :: ListSquare:
comboStyle- > setCurrentIndex(3 );
break ;
case QTextListFormat :: ListDecimal:
comboStyle- > setCurrentIndex(4 );
break ;
case QTextListFormat :: ListLowerAlpha:
comboStyle- > setCurrentIndex(5 );
break ;
case QTextListFormat :: ListUpperAlpha:
comboStyle- > setCurrentIndex(6 );
break ;
case QTextListFormat :: ListLowerRoman:
comboStyle- > setCurrentIndex(7 );
break ;
case QTextListFormat :: ListUpperRoman:
comboStyle- > setCurrentIndex(8 );
break ;
default :
comboStyle- > setCurrentIndex(- 1 );
break ;
}
} else {
int headingLevel = textEdit- > textCursor(). blockFormat(). headingLevel();
comboStyle- > setCurrentIndex(headingLevel ? headingLevel + 8 : 0 );
}
}
void TextEdit:: clipboardDataChanged()
{
#ifndef QT_NO_CLIPBOARD
if (const QMimeData * md = QApplication :: clipboard()- > mimeData())
actionPaste- > setEnabled(md- > hasText());
#endif
}
void TextEdit:: about()
{
QMessageBox :: about(this , tr("About" ), tr("This example demonstrates Qt's "
"rich text editing facilities in action, providing an example "
"document for you to experiment with." ));
}
void TextEdit:: mergeFormatOnWordOrSelection(const QTextCharFormat & format)
{
QTextCursor cursor = textEdit- > textCursor();
if (! cursor. hasSelection())
cursor. select(QTextCursor :: WordUnderCursor);
cursor. mergeCharFormat(format);
textEdit- > mergeCurrentCharFormat(format);
}
void TextEdit:: fontChanged(const QFont & f)
{
comboFont- > setCurrentIndex(comboFont- > findText(QFontInfo (f). family()));
comboSize- > setCurrentIndex(comboSize- > findText(QString :: number(f. pointSize())));
actionTextBold- > setChecked(f. bold());
actionTextItalic- > setChecked(f. italic());
actionTextUnderline- > setChecked(f. underline());
}
void TextEdit:: colorChanged(const QColor & c)
{
QPixmap pix(16 , 16 );
pix. fill(c);
actionTextColor- > setIcon(pix);
}
void TextEdit:: alignmentChanged(Qt :: Alignment a)
{
if (a & Qt :: AlignLeft)
actionAlignLeft- > setChecked(true );
else if (a & Qt :: AlignHCenter)
actionAlignCenter- > setChecked(true );
else if (a & Qt :: AlignRight)
actionAlignRight- > setChecked(true );
else if (a & Qt :: AlignJustify)
actionAlignJustify- > setChecked(true );
}