kpimtextedit/richtextbuilders
ktexthtmlbuilder.cpp
00001 /* 00002 This file is part of KDE. 00003 00004 Copyright (c) 2008 Stephen Kelly <steveire@gmail.com> 00005 00006 This library is free software; you can redistribute it and/or modify it 00007 under the terms of the GNU Library General Public License as published by 00008 the Free Software Foundation; either version 2 of the License, or (at your 00009 option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, but WITHOUT 00012 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 00013 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public 00014 License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to the 00018 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 00019 02110-1301, USA. 00020 */ 00021 00022 #include "ktexthtmlbuilder.h" 00023 00024 #include <QTextDocument> 00025 #include <QList> 00026 00027 class KTextHTMLBuilderPrivate 00028 { 00029 public: 00030 KTextHTMLBuilderPrivate(KTextHTMLBuilder *b) : q_ptr(b) { 00031 00032 } 00033 00034 QList<QTextListFormat::Style> currentListItemStyles; 00035 QString m_text; 00036 00037 KTextHTMLBuilder *q_ptr; 00038 00039 Q_DECLARE_PUBLIC(KTextHTMLBuilder) 00040 00041 }; 00042 00043 KTextHTMLBuilder::KTextHTMLBuilder() : d_ptr(new KTextHTMLBuilderPrivate(this)) 00044 { 00045 00046 } 00047 00048 KTextHTMLBuilder::~KTextHTMLBuilder() 00049 { 00050 delete d_ptr; 00051 } 00052 00053 void KTextHTMLBuilder::beginStrong() 00054 { 00055 Q_D(KTextHTMLBuilder);; 00056 d->m_text.append("<strong>"); 00057 } 00058 00059 void KTextHTMLBuilder::endStrong() 00060 { 00061 Q_D(KTextHTMLBuilder); 00062 d->m_text.append("</strong>"); 00063 } 00064 00065 void KTextHTMLBuilder::beginEmph() 00066 { 00067 Q_D(KTextHTMLBuilder); 00068 d->m_text.append("<em>"); 00069 } 00070 00071 void KTextHTMLBuilder::endEmph() 00072 { 00073 Q_D(KTextHTMLBuilder); 00074 d->m_text.append("</em>"); 00075 } 00076 00077 void KTextHTMLBuilder::beginUnderline() 00078 { 00079 Q_D(KTextHTMLBuilder); 00080 d->m_text.append("<u>"); 00081 } 00082 00083 void KTextHTMLBuilder::endUnderline() 00084 { 00085 Q_D(KTextHTMLBuilder); 00086 d->m_text.append("</u>"); 00087 } 00088 00089 void KTextHTMLBuilder::beginStrikeout() 00090 { 00091 Q_D(KTextHTMLBuilder); 00092 d->m_text.append("<s>"); 00093 } 00094 00095 void KTextHTMLBuilder::endStrikeout() 00096 { 00097 Q_D(KTextHTMLBuilder); 00098 d->m_text.append("</s>"); 00099 } 00100 00101 void KTextHTMLBuilder::beginForeground(const QBrush &brush) 00102 { 00103 Q_D(KTextHTMLBuilder); 00104 d->m_text.append(QString("<span style=\"color:%1;\">").arg(brush.color().name())); 00105 } 00106 00107 void KTextHTMLBuilder::endForeground() 00108 { 00109 Q_D(KTextHTMLBuilder); 00110 d->m_text.append("</span>"); 00111 } 00112 00113 void KTextHTMLBuilder::beginBackground(const QBrush &brush) 00114 { 00115 Q_D(KTextHTMLBuilder); 00116 d->m_text.append(QString("<span style=\"background-color:%1;\">").arg(brush.color().name())); 00117 } 00118 00119 void KTextHTMLBuilder::endBackground() 00120 { 00121 Q_D(KTextHTMLBuilder); 00122 d->m_text.append("</span>"); 00123 } 00124 00125 void KTextHTMLBuilder::beginAnchor(const QString &href, const QString &name) 00126 { 00127 Q_D(KTextHTMLBuilder); 00128 if (!href.isEmpty()) { 00129 if (!name.isEmpty()) { 00130 d->m_text.append(QString("<a href=\"%1\" name=\"%2\">").arg(href).arg(name)); 00131 } else { 00132 d->m_text.append(QString("<a href=\"%1\">").arg(href)); 00133 } 00134 } else { 00135 if (!name.isEmpty()) { 00136 d->m_text.append(QString("<a name=\"%1\">").arg(name)); 00137 } 00138 } 00139 } 00140 00141 void KTextHTMLBuilder::endAnchor() 00142 { 00143 Q_D(KTextHTMLBuilder); 00144 d->m_text.append("</a>"); 00145 } 00146 00147 void KTextHTMLBuilder::beginFontFamily(const QString &family) 00148 { 00149 Q_D(KTextHTMLBuilder); 00150 d->m_text.append(QString("<span style=\"font-family:%1;\">").arg(family)); 00151 } 00152 00153 void KTextHTMLBuilder::endFontFamily() 00154 { 00155 Q_D(KTextHTMLBuilder); 00156 d->m_text.append("</span>"); 00157 } 00158 00159 void KTextHTMLBuilder::beginFontPointSize(int size) 00160 { 00161 Q_D(KTextHTMLBuilder); 00162 d->m_text.append(QString("<span style=\"font-size:%1pt;\">").arg(QString::number(size))); 00163 } 00164 00165 void KTextHTMLBuilder::endFontPointSize() 00166 { 00167 Q_D(KTextHTMLBuilder); 00168 d->m_text.append("</span>"); 00169 } 00170 00171 void KTextHTMLBuilder::beginParagraph(Qt::Alignment al, qreal topMargin, qreal bottomMargin, qreal leftMargin, qreal rightMargin) 00172 { 00173 Q_D(KTextHTMLBuilder); 00174 // Don't put paragraph tags inside li tags. Qt bug reported. 00175 // if (currentListItemStyles.size() != 0) 00176 // { 00177 QString styleString; 00178 if (topMargin != 0) { 00179 styleString.append(QString("margin-top:%1;").arg(topMargin)); 00180 } 00181 if (bottomMargin != 0) { 00182 styleString.append(QString("margin-bottom:%1;").arg(bottomMargin)); 00183 } 00184 if (leftMargin != 0) { 00185 styleString.append(QString("margin-left:%1;").arg(leftMargin)); 00186 } 00187 if (rightMargin != 0) { 00188 styleString.append(QString("margin-right:%1;").arg(rightMargin)); 00189 } 00190 00191 // Using == doesn't work here. 00192 // Using bitwise comparison because an alignment can contain a vertical and a horizontal part. 00193 if (al & Qt::AlignRight) { 00194 d->m_text.append("<p align=\"right\" "); 00195 } else if (al & Qt::AlignHCenter) { 00196 d->m_text.append("<p align=\"center\" "); 00197 } else if (al & Qt::AlignJustify) { 00198 d->m_text.append("<p align=\"justify\" "); 00199 } else if (al & Qt::AlignLeft) { 00200 d->m_text.append("<p"); 00201 } else { 00202 d->m_text.append("<p"); 00203 } 00204 00205 if (!styleString.isEmpty()) { 00206 d->m_text.append(" \"" + styleString + "\""); 00207 } 00208 d->m_text.append(">"); 00209 // } 00210 } 00211 00212 void KTextHTMLBuilder::beginHeader(int level) 00213 { 00214 Q_D(KTextHTMLBuilder); 00215 switch (level) { 00216 case 1: 00217 d->m_text.append("<h1>"); 00218 break; 00219 case 2: 00220 d->m_text.append("<h2>"); 00221 break; 00222 case 3: 00223 d->m_text.append("<h3>"); 00224 break; 00225 case 4: 00226 d->m_text.append("<h4>"); 00227 break; 00228 case 5: 00229 d->m_text.append("<h5>"); 00230 break; 00231 case 6: 00232 d->m_text.append("<h6>"); 00233 break; 00234 default: 00235 break; 00236 } 00237 } 00238 00239 void KTextHTMLBuilder::endHeader(int level) 00240 { 00241 Q_D(KTextHTMLBuilder); 00242 switch (level) { 00243 case 1: 00244 d->m_text.append("</h1>"); 00245 break; 00246 case 2: 00247 d->m_text.append("</h2>"); 00248 break; 00249 case 3: 00250 d->m_text.append("</h3>"); 00251 break; 00252 case 4: 00253 d->m_text.append("</h4>"); 00254 break; 00255 case 5: 00256 d->m_text.append("</h5>"); 00257 break; 00258 case 6: 00259 d->m_text.append("</h6>"); 00260 break; 00261 default: 00262 break; 00263 } 00264 } 00265 00266 void KTextHTMLBuilder::endParagraph() 00267 { 00268 Q_D(KTextHTMLBuilder); 00269 d->m_text.append("</p>\n"); 00270 } 00271 00272 void KTextHTMLBuilder::addNewline() 00273 { 00274 Q_D(KTextHTMLBuilder); 00275 d->m_text.append("<br />\n"); 00276 } 00277 00278 void KTextHTMLBuilder::insertHorizontalRule(int width) 00279 { 00280 Q_D(KTextHTMLBuilder); 00281 if (width != -1) { 00282 d->m_text.append(QString("<hr width=\"%1\" />\n").arg(width)); 00283 } 00284 d->m_text.append("<hr />\n"); 00285 } 00286 00287 void KTextHTMLBuilder::insertImage(const QString &src, qreal width, qreal height) 00288 { 00289 Q_D(KTextHTMLBuilder); 00290 d->m_text.append(QString("<img src=\"%1\" ").arg(src)); 00291 if (width != 0) d->m_text.append(QString("width=\"%2\" ").arg(width)); 00292 if (height != 0) d->m_text.append(QString("height=\"%2\" ").arg(height)); 00293 d->m_text.append("/>"); 00294 } 00295 00296 void KTextHTMLBuilder::beginList(QTextListFormat::Style type) 00297 { 00298 Q_D(KTextHTMLBuilder); 00299 d->currentListItemStyles.append(type); 00300 switch (type) { 00301 case QTextListFormat::ListDisc: 00302 d->m_text.append("<ul type=\"disc\">\n"); 00303 break; 00304 case QTextListFormat::ListCircle: 00305 d->m_text.append("\n<ul type=\"circle\">\n"); 00306 break; 00307 case QTextListFormat::ListSquare: 00308 d->m_text.append("\n<ul type=\"square\">\n"); 00309 break; 00310 case QTextListFormat::ListDecimal: 00311 d->m_text.append("\n<ol type=\"1\">\n"); 00312 break; 00313 case QTextListFormat::ListLowerAlpha: 00314 d->m_text.append("\n<ol type=\"a\">\n"); 00315 break; 00316 case QTextListFormat::ListUpperAlpha: 00317 d->m_text.append("\n<ol type=\"A\">\n"); 00318 break; 00319 default: 00320 break; 00321 } 00322 } 00323 void KTextHTMLBuilder::endList() 00324 { 00325 Q_D(KTextHTMLBuilder); 00326 switch (d->currentListItemStyles.last()) { 00327 case QTextListFormat::ListDisc: 00328 case QTextListFormat::ListCircle: 00329 case QTextListFormat::ListSquare: 00330 d->m_text.append("</ul>\n"); 00331 break; 00332 case QTextListFormat::ListDecimal: 00333 case QTextListFormat::ListLowerAlpha: 00334 case QTextListFormat::ListUpperAlpha: 00335 d->m_text.append("</ol>\n"); 00336 break; 00337 default: 00338 break; 00339 } 00340 d->currentListItemStyles.removeLast(); 00341 } 00342 void KTextHTMLBuilder::beginListItem() 00343 { 00344 Q_D(KTextHTMLBuilder); 00345 d->m_text.append("<li>"); 00346 } 00347 00348 void KTextHTMLBuilder::endListItem() 00349 { 00350 Q_D(KTextHTMLBuilder); 00351 d->m_text.append("</li>\n"); 00352 } 00353 00354 void KTextHTMLBuilder::beginSuperscript() 00355 { 00356 Q_D(KTextHTMLBuilder); 00357 d->m_text.append("<sup>"); 00358 } 00359 00360 void KTextHTMLBuilder::endSuperscript() 00361 { 00362 Q_D(KTextHTMLBuilder); 00363 d->m_text.append("</sup>"); 00364 } 00365 00366 void KTextHTMLBuilder::beginSubscript() 00367 { 00368 Q_D(KTextHTMLBuilder); 00369 d->m_text.append("<sub>"); 00370 } 00371 00372 void KTextHTMLBuilder::endSubscript() 00373 { 00374 Q_D(KTextHTMLBuilder); 00375 d->m_text.append("</sub>"); 00376 } 00377 00378 00379 void KTextHTMLBuilder::beginTable(qreal cellpadding, qreal cellspacing, const QString &width) 00380 { 00381 Q_D(KTextHTMLBuilder); 00382 d->m_text.append(QString("<table cellpadding=\"%1\" cellspacing=\"%2\" width=\"%3\" border=\"1\">") 00383 .arg(cellpadding) 00384 .arg(cellspacing) 00385 .arg(width)); 00386 } 00387 00388 void KTextHTMLBuilder::beginTableRow() 00389 { 00390 Q_D(KTextHTMLBuilder); 00391 d->m_text.append("<tr>"); 00392 } 00393 00394 void KTextHTMLBuilder::beginTableHeaderCell(const QString &width, int colspan, int rowspan) 00395 { 00396 Q_D(KTextHTMLBuilder); 00397 d->m_text.append(QString("<th width=\"%1\" colspan=\"%2\" rowspan=\"%3\">").arg(width).arg(colspan).arg(rowspan)); 00398 } 00399 00400 void KTextHTMLBuilder::beginTableCell(const QString &width, int colspan, int rowspan) 00401 { 00402 Q_D(KTextHTMLBuilder); 00403 d->m_text.append(QString("<td width=\"%1\" colspan=\"%2\" rowspan=\"%3\">").arg(width).arg(colspan).arg(rowspan)); 00404 } 00405 00406 void KTextHTMLBuilder::endTable() 00407 { 00408 Q_D(KTextHTMLBuilder); 00409 d->m_text.append("</table>"); 00410 } 00411 00412 void KTextHTMLBuilder::endTableRow() 00413 { 00414 Q_D(KTextHTMLBuilder); 00415 d->m_text.append("</tr>"); 00416 } 00417 00418 void KTextHTMLBuilder::endTableHeaderCell() 00419 { 00420 Q_D(KTextHTMLBuilder); 00421 d->m_text.append("</th>"); 00422 } 00423 00424 void KTextHTMLBuilder::endTableCell() 00425 { 00426 Q_D(KTextHTMLBuilder); 00427 d->m_text.append("</td>"); 00428 } 00429 00430 00431 void KTextHTMLBuilder::appendLiteralText(const QString &text) 00432 { 00433 Q_D(KTextHTMLBuilder); 00434 d->m_text.append(Qt::escape(text)); 00435 } 00436 00437 00438 QString& KTextHTMLBuilder::getResult() 00439 { 00440 Q_D(KTextHTMLBuilder); 00441 return d->m_text; 00442 }