diff --git a/kpimtextedit/richtextbuilders/CMakeLists.txt b/kpimtextedit/richtextbuilders/CMakeLists.txt index 367b5eb52..bc9423c5b 100644 --- a/kpimtextedit/richtextbuilders/CMakeLists.txt +++ b/kpimtextedit/richtextbuilders/CMakeLists.txt @@ -1,20 +1,23 @@ PROJECT( krichtexteditor ) FIND_PACKAGE(KDE4 REQUIRED) INCLUDE_DIRECTORIES( ${KDE4_INCLUDES} ${CMAKE_CURRENT_BINARY_DIR} ) SET(krichtexteditorSources main.cpp krichtexteditor.cpp markupdirector.cpp + htmlbuilder.cpp + plaintextmarkupbuilder.cpp + mediawikimarkupbuilder.cpp ) KDE4_ADD_EXECUTABLE(krichtexteditor ${krichtexteditorSources} ) TARGET_LINK_LIBRARIES(krichtexteditor ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ) install(TARGETS krichtexteditor DESTINATION ${BIN_INSTALL_DIR}) install(FILES krichtexteditorui.rc DESTINATION ${DATA_INSTALL_DIR}/krichtexteditor) diff --git a/kpimtextedit/richtextbuilders/abstractmarkupbuilder.h b/kpimtextedit/richtextbuilders/abstractmarkupbuilder.h index 86c4b9d98..591c1e870 100755 --- a/kpimtextedit/richtextbuilders/abstractmarkupbuilder.h +++ b/kpimtextedit/richtextbuilders/abstractmarkupbuilder.h @@ -1,207 +1,293 @@ /* This file is part of KDE. Copyright (c) 2008 Stephen Kelly This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ // Any class for which you cannot create instances is an abstract class. #ifndef ABSTRACTMARKUPBUILDER_H #define ABSTRACTMARKUPBUILDER_H #include #include #include +#include /** @brief The AbstractMarkupBuilder class serves as a base class for creating marked up plain text output. The AbstractMarkupBuilder is used by the MarkupDirector to create marked up output such as html or markdown. Subclasses can reimplement whichever methods they choose. None of the methods are pure virtual and all default to an empty function to allow a clean fall-through. The exception is appendLiteralText, which appends its argument to the text being built. -See PlainTextMarkupBuilder and HTMLBuilder for example imlpementations. +See PlainTextMarkupBuilder and HTMLBuilder for example implementations. @note For maintenance, if an extra tag is needed which is not provided by the virtual methods, the ExtraElement can be used. eg, @code builder->beginExtraElement(AbstractMarkupBuilder::DivTag); // ... builder->endExtraElement(AbstractMarkupBuilder::DivTag); @endcode @todo Move this to kdelibs when tested. @author Stephen Kelly @since 4.2 */ class AbstractMarkupBuilder { public: /** For future compatibility. This enum can be used to insert extra tags not supported by the virtual methods. */ enum ExtraElement { UserElement = 100 }; - + /** Destructor */ virtual ~AbstractMarkupBuilder() {} /** Begin a bold element in the markup */ virtual void beginStrong() { } + /** Close the bold element in the markup */ virtual void endStrong() { } + /** Begin an emphasised element in the markup */ virtual void beginEmph() { } + /** Close the emphasised element in the markup */ virtual void endEmph() { } + /** Begin an underlined element in the markup */ virtual void beginUnderline() { } + /** Close the underlined element in the markup */ virtual void endUnderline() { } + /** Begin a striked out element in the markup */ virtual void beginStrikeout() { } + /** Close the striked out element in the markup */ virtual void endStrikeout() { } + /** Begin a decorarated foreground element in the markup (A text color) */ - virtual void beginForeground(const QBrush &) { } + virtual void beginForeground(const QBrush &brush) { Q_UNUSED(brush); } + /** Close the decorarated foreground element in the markup */ virtual void endForeground() { } + /** Begin a decorarated background element in the markup (A text background color) */ - virtual void beginBackground(const QBrush &) { } + virtual void beginBackground(const QBrush &brush) { Q_UNUSED(brush); } + /** Close the decorarated background element in the markup */ virtual void endBackground() { } - /** Begin a url anchor element in the markup - @param The href of the link. + + /** Begin a url anchor element in the markup + @param href The href of the anchor. + @param name The name of the anchor. + */ + virtual void beginNamedLinkedAnchor(const QString &href, const QString &name) { + Q_UNUSED(href); + Q_UNUSED(name); + } + + /** Begin a url anchor element in the markup + @param name The name of the anchor. */ - virtual void beginAnchor(const QString &) { } + virtual void beginNamedAnchor(const QString &name) { + Q_UNUSED(name); + } + + /** Begin a url anchor element in the markup + @param href The href of the anchor. + */ + virtual void beginLinkedAnchor(const QString &href) { + Q_UNUSED(href); + } /** Close the anchor element */ virtual void endAnchor() { } - /** Begin a new font familiy element in the markup - @param The name of the font familiy to begin. + /** Begin a new font familiy element in the markup + @param family The name of the font family to begin. */ - virtual void beginFontFamily(const QString &) { } + virtual void beginFontFamily(const QString &family) { + Q_UNUSED(family); + } /** End font family element */ virtual void endFontFamily() { } - + /** Begin a new font point size element in the markup - @param the point size to begin. + @param int The point size to begin. */ - virtual void beginFontPointSize( int ) { } + virtual void beginFontPointSize( int size) { + Q_UNUSED(size); + } /** End font point size element */ virtual void endFontPointSize() { } -// /** Begin a new paragraph in the markup -// @param The alignment of the new paragraph. -// */ -// virtual void beginParagraph(Qt::Alignment) { } - /** Begin a new paragraph in the markup - @param The alignment of the new paragraph. - @param The top margin of the new paragraph. - @param The bottom margin of the new paragraph. - */ - virtual void beginParagraph(Qt::Alignment, qreal, qreal) { } - - virtual void beginParagraph(Qt::Alignment) { } - + @param a The alignment of the new paragraph. + @param top The top margin of the new paragraph. + @param bottom The bottom margin of the new paragraph. + @param left The left margin of the new paragraph. + @param right The right margin of the new paragraph. + */ + virtual void beginParagraph(Qt::Alignment a, qreal top, qreal bottom, qreal left, qreal right) { + Q_UNUSED(a); + Q_UNUSED(top); + Q_UNUSED(bottom); + Q_UNUSED(left); + Q_UNUSED(right); + } + + /** Close the paragraph in the markup. */ virtual void endParagraph() { } /** Add a newline to the markup. */ virtual void addNewline() { } /** Insert a horizontal rule into the markup. - @warning This is never called by the MarkupDirector as there is no way to know if a QTextDocument contains a horizontal rule. - Just a placeholder until a workaround is written. */ - virtual void insertHorizontalRule() { } - + virtual void insertHorizontalRule(int width = -1) { + Q_UNUSED(width); + } + /** Insert a new image element into the markup. - @param The url of the image - @param The width of the image - @param The height of the image. + @param url The url of the image + @param width The width of the image + @param height The height of the image. */ - virtual void insertImage(const QString &, qreal, qreal) { } + virtual void insertImage(const QString &url, qreal width, qreal height) { + Q_UNUSED(url); + Q_UNUSED(width); + Q_UNUSED(height); + } /** Begin a new list element in the markup. A list element contains list items, and may contain other lists. - @param The style of list to create. + @param style The style of list to create. */ - virtual void beginList(QTextListFormat::Style) { } - + virtual void beginList(QTextListFormat::Style style) { + Q_UNUSED(style); + } + /** Close the list. */ virtual void endList() { } + /** Begin a new list item in the markup */ virtual void beginListItem() { } + /** End the list item */ virtual void endListItem() { } /** Begin a superscript element */ virtual void beginSuperscript() { } /** End superscript element */ virtual void endSuperscript() { } - + /** Begin a subscript element */ virtual void beginSubscript() { } - + /** End subscript element */ virtual void endSubscript() { } - virtual void beginTable(qreal, qreal, const QString &) { } + + virtual void beginTable(qreal, qreal, const QString &) { + + } + virtual void beginTableRow() { } - virtual void beginTableHeaderCell(QString, int, int) { } - virtual void beginTableCell(QString, int, int) { } + + virtual void beginTableHeaderCell(QString, int, int) { + + } + + virtual void beginTableCell(QString, int, int) { + + } virtual void endTable() { } + virtual void endTableRow() { } + virtual void endTableHeaderCell() { } + virtual void endTableCell() { } - /** Begin an extra identified element. Override this to support more elements in the future. */ - virtual void beginExtraElement(int, QVariantList) { } + virtual void beginHeader1() { } + virtual void beginHeader2() { } + virtual void beginHeader3() { } + virtual void beginHeader4() { } + virtual void beginHeader5() { } + virtual void beginHeader6() { } + + virtual void endHeader1() { } + virtual void endHeader2() { } + virtual void endHeader3() { } + virtual void endHeader4() { } + virtual void endHeader5() { } + virtual void endHeader6() { } - /** End extra tag. */ - virtual void endExtraElement(int) { } + + /** Begin an extra identified element. Override this to support more elements + in the future in a BC way. + + @param type The type of element to create + @param args Arguments for the element. + */ + virtual void beginExtraElement(int type, QVariantList args) { + Q_UNUSED(type); + Q_UNUSED(args); + } + + /** End extra tag. + + @param type The type of the tag to end. + */ + virtual void endExtraElement(int type) { + Q_UNUSED(type); + } /** Append the plain text @p text to the markup. - + @param The text to append. */ - virtual void appendLiteralText(const QString &text ) = 0; + virtual void appendLiteralText(const QString &text ) = 0; /** Return the fully marked up result of the building process. This may contain metadata etc, such as a head element in html. - + @return The fully marked up text. */ virtual QString& getResult() = 0; }; #endif diff --git a/kpimtextedit/richtextbuilders/bbcodebuilder.cpp b/kpimtextedit/richtextbuilders/bbcodebuilder.cpp new file mode 100644 index 000000000..46bddc46c --- /dev/null +++ b/kpimtextedit/richtextbuilders/bbcodebuilder.cpp @@ -0,0 +1,140 @@ +/* + This file is part of KDE. + + Copyright (c) 2008 Stephen Kelly + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + + +#include "bbcodebuilder.h" +#include + +BBCodeBuilder::BBCodeBuilder() { + + currentAlignment = Qt::AlignLeft; //Default value +} + +void BBCodeBuilder::beginStrong() { m_text.append("[B]"); } +void BBCodeBuilder::endStrong() { m_text.append("[/B]"); } +void BBCodeBuilder::beginEmph() { m_text.append("[I]"); } +void BBCodeBuilder::endEmph() { m_text.append("[/I]"); } +void BBCodeBuilder::beginUnderline() { m_text.append("[U]"); } +void BBCodeBuilder::endUnderline() { m_text.append("[/U]"); } +void BBCodeBuilder::beginStrikeout() { m_text.append("[S]"); } +void BBCodeBuilder::endStrikeout() { m_text.append("[/S]"); } +void BBCodeBuilder::beginForeground(const QBrush &brush) { m_text.append(QString("[COLOR=%1]").arg(brush.color().name())); } +void BBCodeBuilder::endForeground() { m_text.append("[/COLOR]"); } + +// Background colour not supported by BBCode. + +void BBCodeBuilder::beginAnchor(const QString &href) { m_text.append(QString("[URL=%1]").arg(href)); } +void BBCodeBuilder::endAnchor() { m_text.append("[/URL]"); } + +// Font family not supported by BBCode. + +void BBCodeBuilder::beginFontPointSize(int size) { m_text.append(QString("[SIZE=%1]").arg(QString::number(size))); } +void BBCodeBuilder::endFontPointSize() { m_text.append("[/SIZE]"); } + +void BBCodeBuilder::beginParagraph(Qt::Alignment a, qreal top, qreal bottom, qreal left, qreal right) { + Q_UNUSED(top); + Q_UNUSED(bottom); + Q_UNUSED(left); + Q_UNUSED(right); + if (a & Qt::AlignRight){ + m_text.append("\n[Right]"); + } + else if (a & Qt::AlignHCenter){ + m_text.append("\n[CENTER]"); + } + // LEFT is also supported in BBCode, but ignored. + currentAlignment = a; +} +void BBCodeBuilder::endParagraph() { + if (currentAlignment & Qt::AlignRight){ + m_text.append("\n[/Right]\n"); + } + else if (currentAlignment & Qt::AlignHCenter){ + m_text.append("\n[/CENTER]\n"); + } + else{ + m_text.append("\n"); + } + currentAlignment = Qt::AlignLeft; + +} +void BBCodeBuilder::addNewline() { m_text.append("\n"); } + +void BBCodeBuilder::insertImage(const QString &src, qreal width, qreal height) { + Q_UNUSED(width); + Q_UNUSED(height); + m_text.append(QString("[IMG]%1[/IMG]").arg(src)); +} + +void BBCodeBuilder::beginList(QTextListFormat::Style type) { + switch(type){ + case QTextListFormat::ListDisc: + case QTextListFormat::ListCircle: + case QTextListFormat::ListSquare: + m_text.append("[LIST]\n"); // Unordered lists are all disc type in BBCode. + break; + case QTextListFormat::ListDecimal: + m_text.append("[LIST=1]\n"); + break; + case QTextListFormat::ListLowerAlpha: + m_text.append("[LIST=a]\n"); + break; + case QTextListFormat::ListUpperAlpha: + m_text.append("[LIST=A]\n"); + break; + default: + break; + } +} + +void BBCodeBuilder::endList() { m_text.append("[/LIST]\n"); } + + +void BBCodeBuilder::beginListItem() { m_text.append("[*] "); } + +void BBCodeBuilder::beginSuperscript() { m_text.append("[SUP]"); } + +void BBCodeBuilder::endSuperscript() { m_text.append("[/SUP]"); } + +void BBCodeBuilder::beginSubscript() { m_text.append("[SUB]"); } + +void BBCodeBuilder::endSubscript() { m_text.append("[/SUB]"); } + + +void BBCodeBuilder::beginTable(qreal, qreal, const QString &) { m_text.append("[TABLE]\n"); } + +void BBCodeBuilder::beginTableRow() { m_text.append("[/TABLE]"); } + + +void BBCodeBuilder::appendLiteralText(const QString &text) { m_text.append(escape(text)); } + +const QString BBCodeBuilder::escape(const QString &s) +{ + if (s.contains("[")) + { + return QString("[NOPARSE]" + s + "[/NOPARSE]" ); + } + return s; +} + +virtual QString& BBCodeBuilder::getResult() { return m_text; } + diff --git a/kpimtextedit/richtextbuilders/bbcodebuilder.h b/kpimtextedit/richtextbuilders/bbcodebuilder.h new file mode 100755 index 000000000..42fb3004b --- /dev/null +++ b/kpimtextedit/richtextbuilders/bbcodebuilder.h @@ -0,0 +1,102 @@ +/* + This file is part of KDE. + + Copyright (c) 2008 Stephen Kelly + + This library is free software; you can redistribute it and/or modify it + under the terms of the GNU Library General Public License as published by + the Free Software Foundation; either version 2 of the License, or (at your + option) any later version. + + This library is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public + License for more details. + + You should have received a copy of the GNU Library General Public License + along with this library; see the file COPYING.LIB. If not, write to the + Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + 02110-1301, USA. +*/ + + + +#include "abstractmarkupbuilder.h" +#include + +/** +Creates BBCode from a QTextDocument +*/ +class BBCodeBuilder : public AbstractMarkupBuilder +{ +public: + + /** +Creates a new BBCodeBuilder. + */ + BBCodeBuilder(); + + virtual void beginStrong(); + virtual void endStrong(); + virtual void beginEmph(); + virtual void endEmph(); + virtual void beginUnderline(); + virtual void endUnderline(); + virtual void beginStrikeout(); + virtual void endStrikeout(); + virtual void beginForeground(const QBrush &brush); + virtual void endForeground(); + + // Background colour not supported by BBCode. + + virtual void beginAnchor(const QString &href); + virtual void endAnchor(); + + // Font family not supported by BBCode. + + virtual void beginFontPointSize(int size); + virtual void endFontPointSize(); + + virtual void beginParagraph(Qt::Alignment a, qreal top, qreal bottom, qreal left, qreal right); + + virtual void endParagraph(); + virtual void addNewline(); + + virtual void insertImage(const QString &src, qreal width, qreal height); + + virtual void beginList(QTextListFormat::Style type); + + virtual void endList(); + + + virtual void beginListItem(); + + virtual void beginSuperscript(); + + virtual void endSuperscript(); + + virtual void beginSubscript(); + + virtual void endSubscript(); + + + virtual void beginTable(qreal, qreal, const QString &); + + virtual void beginTableRow(); + + + virtual void appendLiteralText(const QString &text); + + const QString escape(const QString &s); + + virtual QString& getResult(); + +private: + QList currentListItemStyles; + + QString m_text; + + Qt::Alignment currentAlignment; + +}; + diff --git a/kpimtextedit/richtextbuilders/htmlbuilder.cpp b/kpimtextedit/richtextbuilders/htmlbuilder.cpp new file mode 100644 index 000000000..27d7a840f --- /dev/null +++ b/kpimtextedit/richtextbuilders/htmlbuilder.cpp @@ -0,0 +1,317 @@ + +#include "htmlbuilder.h" + +#include + +HTMLBuilder::HTMLBuilder() +{ + +} + +HTMLBuilder::~HTMLBuilder() +{ + +} + +void HTMLBuilder::beginStrong() +{ + m_text.append(""); +} + +void HTMLBuilder::endStrong() +{ + m_text.append(""); +} + +void HTMLBuilder::beginEmph() +{ + m_text.append(""); +} + +void HTMLBuilder::endEmph() +{ + m_text.append(""); +} + +void HTMLBuilder::beginUnderline() +{ + m_text.append(""); +} + +void HTMLBuilder::endUnderline() +{ + m_text.append(""); +} + +void HTMLBuilder::beginStrikeout() +{ + m_text.append(""); +} + +void HTMLBuilder::endStrikeout() +{ + m_text.append(""); +} + +void HTMLBuilder::beginForeground(const QBrush &brush) +{ + m_text.append(QString("").arg(brush.color().name())); +} + +void HTMLBuilder::endForeground() +{ + m_text.append(""); +} + +void HTMLBuilder::beginBackground(const QBrush &brush) +{ + m_text.append(QString("").arg(brush.color().name())); +} + +void HTMLBuilder::endBackground() +{ + m_text.append(""); +} + +void HTMLBuilder::endAnchor() +{ + m_text.append(""); +} + +void HTMLBuilder::beginFontFamily(const QString &family) +{ + m_text.append(QString("").arg(family)); +} + +void HTMLBuilder::endFontFamily() { + m_text.append(""); +} + +void HTMLBuilder::beginFontPointSize(int size) { + m_text.append(QString("").arg(QString::number(size))); +} + +void HTMLBuilder::endFontPointSize() { + m_text.append(""); +} + +void HTMLBuilder::beginParagraph(Qt::Alignment al, qreal topMargin, qreal bottomMargin, qreal leftMargin, qreal rightMargin) +{ + // Don't put paragraph tags inside li tags. Qt bug reported. +// if (currentListItemStyles.size() != 0) +// { + QString styleString; + if ( topMargin != 0 ) { styleString.append( QString( "margin-top:%1;" ).arg( topMargin ) ); } + if ( bottomMargin != 0 ) { styleString.append( QString( "margin-bottom:%1;" ).arg( bottomMargin ) ); } + if ( leftMargin != 0 ) { styleString.append( QString( "margin-left:%1;" ).arg( leftMargin ) ); } + if ( rightMargin != 0 ) { styleString.append( QString( "margin-right:%1;" ).arg( rightMargin ) ); } + + // Using == doesn't work here. + // Using bitwise comparison because an alignment can contain a vertical and a horizontal part. + if (al & Qt::AlignRight){ + m_text.append( "

" ); +// } +} + +void HTMLBuilder::beginHeader1() { + m_text.append("

"); +} + +void HTMLBuilder::beginHeader2() { + m_text.append("

"); +} + +void HTMLBuilder::beginHeader3() { + m_text.append("

"); +} + +void HTMLBuilder::beginHeader4() { + m_text.append("

"); +} + +void HTMLBuilder::beginHeader5() { + m_text.append("

"); +} + +void HTMLBuilder::beginHeader6() { + m_text.append("
"); +} + +void HTMLBuilder::endHeader1() { + m_text.append("
"); +} + +void HTMLBuilder::endHeader2() { + m_text.append(""); +} + +void HTMLBuilder::endHeader3() { + m_text.append(""); +} + +void HTMLBuilder::endHeader4() { + m_text.append(""); +} + +void HTMLBuilder::endHeader5() { + m_text.append(""); +} + +void HTMLBuilder::endHeader6() { + m_text.append(""); +} + +void HTMLBuilder::endParagraph() { + m_text.append("\n

\n"); +} + +void HTMLBuilder::addNewline() { + m_text.append("
\n"); +} + +void HTMLBuilder::insertHorizontalRule( int width ) +{ + if( width != -1 ) + { + m_text.append( QString( "
\n" ).arg(width) ); + } + m_text.append( "
\n" ); +} + +void HTMLBuilder::insertImage(const QString &src, qreal width, qreal height) +{ + m_text.append(QString("").arg(src).arg(width).arg(height)); +} + +void HTMLBuilder::beginList(QTextListFormat::Style type) { + currentListItemStyles.append(type); + switch(type){ + case QTextListFormat::ListDisc: + m_text.append("\n