Warning, file /office/calligra/libs/text/KoTextDebug.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).
0001 /* This file is part of the KDE project 0002 * Copyright (C) 2008 Girish Ramakrishnan <girish@forwardbias.in> 0003 * Copyright (C) 2009 Elvis Stansvik <elvstone@gmail.com> 0004 * 0005 * This library is free software; you can redistribute it and/or 0006 * modify it under the terms of the GNU Library General Public 0007 * License as published by the Free Software Foundation; either 0008 * version 2 of the License, or (at your option) any later version. 0009 * 0010 * This library is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 0013 * Library General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU Library General Public License 0016 * along with this library; see the file COPYING.LIB. If not, write to 0017 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 0018 * Boston, MA 02110-1301, USA. 0019 */ 0020 0021 #include "KoTextDebug.h" 0022 0023 #include <QTextDocument> 0024 #include <QTextDocumentFragment> 0025 #include <QTextFrame> 0026 #include <QTextBlock> 0027 #include <QTextTable> 0028 #include <QTextFragment> 0029 #include <QTextList> 0030 #include <QTextStream> 0031 #include <QTextCursor> 0032 0033 #include "styles/KoParagraphStyle.h" 0034 #include "styles/KoCharacterStyle.h" 0035 #include "styles/KoListStyle.h" 0036 #include "styles/KoTableStyle.h" 0037 #include "styles/KoTableCellStyle.h" 0038 #include "styles/KoStyleManager.h" 0039 #include "KoTextDocument.h" 0040 #include "KoTextBlockData.h" 0041 #include <KoInlineTextObjectManager.h> 0042 #include <KoInlineNote.h> 0043 #include <KoImageData.h> 0044 0045 #define PARAGRAPH_BORDER_DEBUG 0046 0047 int KoTextDebug::depth = 0; 0048 const int KoTextDebug::INDENT = 2; 0049 const QTextDocument *KoTextDebug::document = 0; 0050 0051 #define dumpIndent(T) { for (int i=0; i<T; ++i) out << ' '; } 0052 #define dumpList(T) { foreach (const QString &x, T) out << x << ' '; } 0053 0054 Q_DECLARE_METATYPE(QVector<KoText::Tab>) 0055 0056 static QString fontProperties(const QTextCharFormat &textFormat) 0057 { 0058 QMap<int, QVariant> properties = textFormat.properties(); 0059 QStringList fontProps; 0060 // add only font properties here 0061 foreach(int id, properties.keys()) { 0062 switch (id) { 0063 case QTextFormat::FontFamily: 0064 fontProps.append(properties[id].toString()); 0065 break; 0066 case QTextFormat::FontPointSize: 0067 fontProps.append(QString("%1pt").arg(properties[id].toDouble())); 0068 break; 0069 case QTextFormat::FontSizeAdjustment: 0070 fontProps.append(QString("%1adj").arg(properties[id].toDouble())); 0071 break; 0072 case QTextFormat::FontWeight: 0073 fontProps.append(QString("weight %1").arg(properties[id].toInt())); 0074 break; 0075 case QTextFormat::FontItalic: 0076 fontProps.append(properties[id].toBool() ? "italic" : "non-italic"); 0077 break; 0078 case QTextFormat::FontPixelSize: 0079 fontProps.append(QString("%1px").arg(properties[id].toDouble())); 0080 break; 0081 case QTextFormat::FontFixedPitch: 0082 fontProps.append(properties[id].toBool() ? "fixedpitch" : "varpitch"); 0083 break; 0084 case QTextFormat::FontCapitalization: 0085 fontProps.append(QString("caps %1").arg(properties[id].toInt())); 0086 break; 0087 case KoCharacterStyle::FontCharset: 0088 fontProps.append(properties[id].toString()); 0089 break; 0090 case QTextFormat::FontStyleHint: 0091 fontProps.append(QString::number(properties[id].toInt())); 0092 break; 0093 case QTextFormat::FontKerning: 0094 fontProps.append(QString("kerning %1").arg(properties[id].toInt())); 0095 break; 0096 default: 0097 break; 0098 } 0099 } 0100 return fontProps.join(","); 0101 } 0102 0103 void KoTextDebug::dumpDocument(const QTextDocument *doc, QTextStream &out) 0104 { 0105 Q_ASSERT(doc); 0106 document = doc; 0107 out << QString("<document defaultfont=\"%1\">").arg(doc->defaultFont().toString()); 0108 dumpFrame(document->rootFrame(), out); 0109 out << "</document>"; 0110 document = 0; 0111 } 0112 0113 QString KoTextDebug::textAttributes(const KoCharacterStyle &style) 0114 { 0115 QTextCharFormat format; 0116 style.applyStyle(format); 0117 return textAttributes(format); 0118 } 0119 0120 QString KoTextDebug::inlineObjectAttributes(const QTextCharFormat &textFormat) 0121 { 0122 QString attrs; 0123 0124 if (textFormat.objectType() == QTextFormat::UserObject + 1) { 0125 KoInlineTextObjectManager *inlineObjectManager = KoTextDocument(document).inlineTextObjectManager(); 0126 KoInlineObject *inlineObject = inlineObjectManager->inlineTextObject(textFormat); 0127 if (KoInlineNote *note = dynamic_cast<KoInlineNote *>(inlineObject)) { 0128 attrs.append(QString(" id=\"%1\"").arg(note->id())); 0129 if (note->type() == KoInlineNote::Footnote) { 0130 attrs.append(" type=\"footnote\""); 0131 } else if (note->type() == KoInlineNote::Endnote) { 0132 attrs.append(" type=\"endnote\""); 0133 } 0134 attrs.append(QString(" label=\"%1\"").arg(note->label())); 0135 } else { 0136 attrs.append(" type=\"inlineobject\">"); 0137 } 0138 } 0139 0140 return attrs; 0141 } 0142 0143 QString KoTextDebug::textAttributes(const QTextCharFormat &textFormat) 0144 { 0145 QString attrs; 0146 0147 QTextImageFormat imageFormat = textFormat.toImageFormat(); 0148 0149 if (imageFormat.isValid()) { 0150 attrs.append(" type=\"image\">"); 0151 return attrs; 0152 } 0153 0154 KoStyleManager *styleManager = document ? KoTextDocument(document).styleManager() : 0; 0155 if (styleManager && textFormat.hasProperty(KoCharacterStyle::StyleId)) { 0156 int id = textFormat.intProperty(KoCharacterStyle::StyleId); 0157 KoCharacterStyle *characterStyle = styleManager->characterStyle(id); 0158 attrs.append(" characterStyle=\"id:").append(QString::number(id)); 0159 if (characterStyle) 0160 attrs.append(" name:").append(characterStyle->name()); 0161 attrs.append("\""); 0162 } 0163 0164 QMap<int, QVariant> properties = textFormat.properties(); 0165 attrs.append(" type=\"char\""); 0166 QString fontProps = fontProperties(textFormat); 0167 if (!fontProps.isEmpty()) 0168 attrs.append(QString(" font=\"%1\"").arg(fontProps)); 0169 0170 if (textFormat.isAnchor()) { 0171 attrs.append(QString(" achorHref=\"%1\"").arg(textFormat.anchorHref())); 0172 attrs.append(QString(" achorName=\"%1\"").arg(textFormat.anchorName())); 0173 } 0174 0175 foreach(int id, properties.keys()) { 0176 QString key, value; 0177 switch (id) { 0178 case QTextFormat::TextOutline: { 0179 key = "outline"; 0180 QPen pen = qvariant_cast<QPen>(properties[id]); 0181 if (pen.style() == Qt::NoPen) 0182 value = "false"; 0183 else 0184 value = pen.color().name(); 0185 break; 0186 } 0187 case KoCharacterStyle::UnderlineStyle: 0188 key = "underlinestyle"; 0189 value = QString::number(properties[id].toInt()); 0190 break; 0191 case QTextFormat::TextUnderlineColor: 0192 key = "underlinecolor"; 0193 value = qvariant_cast<QColor>(properties[id]).name(); 0194 break; 0195 case KoCharacterStyle::UnderlineType: 0196 key = "underlinetype"; 0197 value = QString::number(properties[id].toInt()); 0198 break; 0199 case KoCharacterStyle::UnderlineMode: 0200 key = "underlinemode"; 0201 value = QString::number(properties[id].toInt()); 0202 break; 0203 case KoCharacterStyle::UnderlineWeight: 0204 key = "underlineweight"; 0205 value = QString::number(properties[id].toInt()); 0206 break; 0207 case KoCharacterStyle::UnderlineWidth: 0208 key = "underlinewidth"; 0209 value = QString::number(properties[id].toDouble()); 0210 break; 0211 case KoCharacterStyle::StrikeOutStyle: 0212 key = "strikeoutstyle"; 0213 value = QString::number(properties[id].toInt()); 0214 break; 0215 case KoCharacterStyle::StrikeOutColor: 0216 key = "strikeoutcolor"; 0217 value = qvariant_cast<QColor>(properties[id]).name(); 0218 break; 0219 case KoCharacterStyle::StrikeOutType: 0220 key = "strikeouttype"; 0221 value = QString::number(properties[id].toInt()); 0222 break; 0223 case KoCharacterStyle::StrikeOutMode: 0224 key = "strikeoutmode"; 0225 value = QString::number(properties[id].toInt()); 0226 break; 0227 case KoCharacterStyle::StrikeOutWeight: 0228 key = "strikeoutweight"; 0229 value = QString::number(properties[id].toInt()); 0230 break; 0231 case KoCharacterStyle::StrikeOutWidth: 0232 key = "strikeoutwidth"; 0233 value = QString::number(properties[id].toDouble()); 0234 break; 0235 case QTextFormat::ForegroundBrush: 0236 key = "foreground"; 0237 value = qvariant_cast<QBrush>(properties[id]).color().name(); // beware! 0238 break; 0239 case QTextFormat::BackgroundBrush: 0240 key = "background"; 0241 value = qvariant_cast<QBrush>(properties[id]).color().name(); // beware! 0242 break; 0243 case QTextFormat::BlockAlignment: 0244 key = "align"; 0245 value = QString::number(properties[id].toInt()); 0246 break; 0247 case QTextFormat::TextIndent: 0248 key = "textindent"; 0249 value = QString::number(properties[id].toInt()); 0250 break; 0251 case QTextFormat::BlockIndent: 0252 key = "indent"; 0253 value = QString::number(properties[id].toInt()); 0254 break; 0255 case KoCharacterStyle::Country: 0256 key = "country"; 0257 value = properties[id].toString(); 0258 break; 0259 case KoCharacterStyle::Language: 0260 key = "language"; 0261 value = properties[id].toString(); 0262 break; 0263 case KoCharacterStyle::HasHyphenation: 0264 key = "hyphenation"; 0265 value = properties[id].toBool(); 0266 break; 0267 case KoCharacterStyle::StrikeOutText: 0268 key = "strikeout-text"; 0269 value = properties[id].toString(); 0270 break; 0271 case KoCharacterStyle::FontCharset: 0272 key = "font-charset"; 0273 value = properties[id].toString(); 0274 break; 0275 case KoCharacterStyle::TextRotationAngle: 0276 key = "rotation-angle"; 0277 value = QString::number(properties[id].toInt()); 0278 break; 0279 case KoCharacterStyle::TextRotationScale: 0280 key = "text-rotation-scale"; 0281 value = properties[id].toInt() == KoCharacterStyle::Fixed ? "Fixed" : "LineHeight"; 0282 break; 0283 case KoCharacterStyle::TextScale: 0284 key = "text-scale"; 0285 value = QString::number(properties[id].toInt()); 0286 break; 0287 case KoCharacterStyle::InlineRdf: 0288 key = "inline-rdf"; 0289 value = QString::number(properties[id].toInt()); 0290 break; 0291 default: 0292 key = "unknown"+QString::number(id); 0293 value = QString::number(properties[id].toInt()); 0294 break; 0295 } 0296 if (!key.isEmpty()) 0297 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0298 } 0299 return attrs; 0300 } 0301 0302 QString KoTextDebug::paraAttributes(const KoParagraphStyle &style) 0303 { 0304 QTextBlockFormat format; 0305 style.applyStyle(format); 0306 return paraAttributes(format); 0307 } 0308 0309 QString KoTextDebug::paraAttributes(const QTextBlockFormat &blockFormat) 0310 { 0311 QString attrs; 0312 KoStyleManager *styleManager = document ? KoTextDocument(document).styleManager() : 0; 0313 if (styleManager && blockFormat.hasProperty(KoParagraphStyle::StyleId)) { 0314 int id = blockFormat.intProperty(KoParagraphStyle::StyleId); 0315 KoParagraphStyle *paragraphStyle = styleManager->paragraphStyle(id); 0316 attrs.append(" paragraphStyle=\"id:").append(QString::number(id)); 0317 if (paragraphStyle) 0318 attrs.append(" name:").append(paragraphStyle->name()); 0319 attrs.append("\""); 0320 } 0321 0322 QMap<int, QVariant> properties = blockFormat.properties(); 0323 foreach(int id, properties.keys()) { 0324 QString key, value; 0325 switch (id) { 0326 // the following are 'todo' 0327 case KoParagraphStyle::PercentLineHeight: 0328 case KoParagraphStyle::FixedLineHeight: 0329 case KoParagraphStyle::MinimumLineHeight: 0330 case KoParagraphStyle::LineSpacing: 0331 case KoParagraphStyle::LineSpacingFromFont: 0332 case KoParagraphStyle::AlignLastLine: 0333 case KoParagraphStyle::WidowThreshold: 0334 case KoParagraphStyle::OrphanThreshold: 0335 case KoParagraphStyle::DropCapsTextStyle: 0336 case KoParagraphStyle::FollowDocBaseline: 0337 case KoParagraphStyle::HasLeftBorder: 0338 case KoParagraphStyle::HasTopBorder: 0339 case KoParagraphStyle::HasRightBorder: 0340 case KoParagraphStyle::HasBottomBorder: 0341 case KoParagraphStyle::BorderLineWidth: 0342 case KoParagraphStyle::SecondBorderLineWidth: 0343 case KoParagraphStyle::DistanceToSecondBorder: 0344 case KoParagraphStyle::LeftPadding: 0345 case KoParagraphStyle::TopPadding: 0346 case KoParagraphStyle::RightPadding: 0347 case KoParagraphStyle::BottomPadding: 0348 case KoParagraphStyle::LeftBorderColor: 0349 case KoParagraphStyle::TopInnerBorderWidth: 0350 case KoParagraphStyle::TopBorderSpacing: 0351 case KoParagraphStyle::TopBorderStyle: 0352 case KoParagraphStyle::TopBorderColor: 0353 case KoParagraphStyle::RightInnerBorderWidth: 0354 case KoParagraphStyle::RightBorderSpacing: 0355 case KoParagraphStyle::RightBorderStyle: 0356 case KoParagraphStyle::RightBorderColor: 0357 case KoParagraphStyle::BottomInnerBorderWidth: 0358 case KoParagraphStyle::BottomBorderSpacing: 0359 case KoParagraphStyle::BottomBorderStyle: 0360 case KoParagraphStyle::BottomBorderColor: 0361 case KoParagraphStyle::ListStyleId: 0362 case KoParagraphStyle::ListStartValue: 0363 case KoParagraphStyle::RestartListNumbering: 0364 case KoParagraphStyle::TextProgressionDirection: 0365 case KoParagraphStyle::MasterPageName: 0366 case KoParagraphStyle::OutlineLevel: 0367 break; 0368 case KoParagraphStyle::AutoTextIndent: 0369 key = "autotextindent"; 0370 value = properties[id].toBool() ? "true" : "false" ; 0371 break; 0372 #ifdef PARAGRAPH_BORDER_DEBUG // because it tends to get annoyingly long :) 0373 case KoParagraphStyle::LeftBorderWidth: 0374 key = "border-width-left"; 0375 value = QString::number(properties[id].toDouble()) ; 0376 break; 0377 case KoParagraphStyle::TopBorderWidth: 0378 key = "border-width-top"; 0379 value = QString::number(properties[id].toDouble()) ; 0380 break; 0381 case KoParagraphStyle::RightBorderWidth: 0382 key = "border-width-right"; 0383 value = QString::number(properties[id].toDouble()) ; 0384 break; 0385 case KoParagraphStyle::BottomBorderWidth: 0386 key = "border-width-bottom"; 0387 value = QString::number(properties[id].toDouble()) ; 0388 break; 0389 case KoParagraphStyle::LeftBorderStyle: 0390 key = "border-style-left"; 0391 value = QString::number(properties[id].toDouble()) ; 0392 break; 0393 case KoParagraphStyle::LeftBorderSpacing: 0394 key = "inner-border-spacing-left"; 0395 value = QString::number(properties[id].toDouble()) ; 0396 break; 0397 case KoParagraphStyle::LeftInnerBorderWidth: 0398 key = "inner-border-width-left"; 0399 value = QString::number(properties[id].toDouble()) ; 0400 break; 0401 #endif 0402 case KoParagraphStyle::TabStopDistance: 0403 key = "tab-stop-distance"; 0404 value = QString::number(properties[id].toDouble()); 0405 break; 0406 case KoParagraphStyle::TabPositions: 0407 key = "tab-stops"; 0408 value.clear(); 0409 foreach(const QVariant & qvtab, qvariant_cast<QList<QVariant> >(properties[id])) { 0410 KoText::Tab tab = qvtab.value<KoText::Tab>(); 0411 value.append("{"); 0412 value.append(" pos:").append(QString::number(tab.position)); 0413 value.append(" type:").append(QString::number(tab.type)); 0414 if (! tab.delimiter.isNull()) 0415 value.append(" delim:").append(QString(tab.delimiter)); 0416 value.append(" leadertype:").append(QString::number(tab.leaderType)); 0417 value.append(" leaderstyle:").append(QString::number(tab.leaderStyle)); 0418 value.append(" leaderweight:").append(QString::number(tab.leaderWeight)); 0419 value.append(" leaderwidth:").append(QString().setNum(tab.leaderWidth)); 0420 value.append(" leadercolor:").append(tab.leaderColor.name()); 0421 if (! tab.leaderText.isEmpty()) 0422 value.append(" leadertext:").append(QString(tab.leaderText)); 0423 value.append("}, "); 0424 } 0425 break; 0426 case KoParagraphStyle::DropCaps: 0427 key = "drop-caps"; 0428 value = QString::number(properties[id].toBool()); 0429 break; 0430 case KoParagraphStyle::DropCapsLines: 0431 key = "drop-caps-lines"; 0432 value = QString::number(properties[id].toInt()); 0433 break; 0434 case KoParagraphStyle::DropCapsLength: 0435 key = "drop-caps-length"; 0436 value = QString::number(properties[id].toInt()); 0437 break; 0438 case KoParagraphStyle::DropCapsDistance: 0439 key = "drop-caps-distance"; 0440 value = QString::number(properties[id].toDouble()); 0441 break; 0442 case QTextFormat::BlockBottomMargin: 0443 value = QString::number(properties[id].toDouble()); 0444 if (value != "0") 0445 key = "block-bottom-margin"; 0446 break; 0447 case QTextFormat::BlockTopMargin: 0448 value = QString::number(properties[id].toDouble()); 0449 if (value != "0") 0450 key = "block-top-margin"; 0451 break; 0452 case QTextFormat::BlockLeftMargin: 0453 value = QString::number(properties[id].toDouble()); 0454 if (value != "0") 0455 key = "block-left-margin"; 0456 break; 0457 case QTextFormat::BlockRightMargin: 0458 value = QString::number(properties[id].toDouble()); 0459 if (value != "0") 0460 key = "block-right-margin"; 0461 break; 0462 case KoParagraphStyle::UnnumberedListItem: 0463 key = "unnumbered-list-item"; 0464 value = QString::number(properties[id].toBool()); 0465 break; 0466 case KoParagraphStyle::IsListHeader: 0467 key = "list-header"; 0468 value = '1'; 0469 break; 0470 case KoParagraphStyle::ListLevel: 0471 key = "list-level"; 0472 value = QString::number(properties[id].toInt()); 0473 break; 0474 default: 0475 break; 0476 } 0477 if (!key.isEmpty()) 0478 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0479 } 0480 return attrs; 0481 } 0482 0483 QString KoTextDebug::listAttributes(const QTextListFormat &listFormat) 0484 { 0485 QString attrs; 0486 KoStyleManager *styleManager = document ? KoTextDocument(document).styleManager() : 0; 0487 if (styleManager && listFormat.hasProperty(KoListStyle::StyleId)) { 0488 int id = listFormat.intProperty(KoListStyle::StyleId); 0489 KoListStyle *listStyle = styleManager->listStyle(id); 0490 attrs.append(" listStyle=\"id:").append(QString::number(id)); 0491 if (listStyle) 0492 attrs.append(" name:").append(listStyle->name()); 0493 attrs.append("\""); 0494 } 0495 0496 QMap<int, QVariant> properties = listFormat.properties(); 0497 foreach(int id, properties.keys()) { 0498 QString key, value; 0499 switch (id) { 0500 case QTextListFormat::ListStyle: 0501 key = "type"; 0502 value = QString::number(properties[id].toInt()); 0503 break; 0504 case QTextListFormat::ListIndent: 0505 key = "indent"; 0506 value = QString::number(properties[id].toDouble()); 0507 break; 0508 case KoListStyle::ListItemPrefix: 0509 key = "prefix"; 0510 value = properties[id].toString(); 0511 break; 0512 case KoListStyle::ListItemSuffix: 0513 key = "suffix"; 0514 value = properties[id].toString(); 0515 break; 0516 case KoListStyle::StartValue: 0517 key = "start-value"; 0518 value = QString::number(properties[id].toInt()); 0519 break; 0520 case KoListStyle::Level: 0521 key = "level"; 0522 value = QString::number(properties[id].toInt()); 0523 break; 0524 case KoListStyle::DisplayLevel: 0525 key = "display-level"; 0526 value = QString::number(properties[id].toInt()); 0527 break; 0528 case KoListStyle::Alignment: 0529 key = "alignment"; 0530 value = QString::number(properties[id].toInt()); 0531 break; 0532 case KoListStyle::RelativeBulletSize: 0533 key = "bullet-size"; 0534 value = QString::number(properties[id].toInt()); 0535 break; 0536 case KoListStyle::BulletCharacter: 0537 key = "bullet-char"; 0538 value = properties[id].toString(); 0539 break; 0540 case KoListStyle::LetterSynchronization: 0541 key = "letter-sync"; 0542 value = QString::number(properties[id].toInt()); 0543 break; 0544 case KoListStyle::StyleId: 0545 key = "styleid"; 0546 value = QString::number(properties[id].toInt()); 0547 break; 0548 case KoListStyle::MinimumWidth: 0549 key = "minimum-width"; 0550 value = QString::number(properties[id].toDouble()); 0551 break; 0552 case KoListStyle::ListId: 0553 key = "list-id"; 0554 value = QString::number(properties[id].toInt()); 0555 break; 0556 case KoListStyle::IsOutline: 0557 key = "is-outline"; 0558 value = properties[id].toBool(); 0559 break; 0560 case KoListStyle::Indent: 0561 key = "indent"; 0562 value = QString::number(properties[id].toInt()); 0563 break; 0564 case KoListStyle::MinimumDistance: 0565 key = "minimum-distance"; 0566 value = QString::number(properties[id].toDouble()); 0567 break; 0568 case KoListStyle::Width: 0569 key = "width"; 0570 value = QString::number(properties[id].toDouble()); 0571 break; 0572 case KoListStyle::Height: 0573 key = "height"; 0574 value = QString::number(properties[id].toDouble()); 0575 break; 0576 case KoListStyle::BulletImage: 0577 key = "bullet-image"; 0578 value = QString::number((quintptr)(properties[id].value<KoImageData*>())); 0579 break; 0580 case KoListStyle::Margin: 0581 key="margin-left"; 0582 value =QString::number(properties[id].toInt()); 0583 break; 0584 case KoListStyle::TextIndent: 0585 key="text-indent"; 0586 value =QString::number(properties[id].toInt()); 0587 break; 0588 case KoListStyle::AlignmentMode: 0589 key="label-alignment"; 0590 value=QString(properties[id].toBool()? "true":"false"); 0591 break; 0592 case KoListStyle::LabelFollowedBy: 0593 key="label-followed-by"; 0594 value =QString::number(properties[id].toInt()); 0595 break; 0596 case KoListStyle::TabStopPosition: 0597 key="tab-stop-position"; 0598 value =QString::number(properties[id].toInt()); 0599 break; 0600 default: 0601 break; 0602 } 0603 if (!key.isEmpty()) 0604 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0605 } 0606 return attrs; 0607 } 0608 0609 QString KoTextDebug::tableAttributes(const KoTableStyle &tableStyle) 0610 { 0611 QTextTableFormat format; 0612 tableStyle.applyStyle(format); 0613 return tableAttributes(format); 0614 } 0615 0616 QString KoTextDebug::tableAttributes(const QTextTableFormat &tableFormat) 0617 { 0618 QString attrs; 0619 KoStyleManager *styleManager = document ? KoTextDocument(document).styleManager() : 0; 0620 if (styleManager) { 0621 int id = tableFormat.intProperty(KoTableStyle::StyleId); 0622 KoTableStyle *tableStyle = styleManager->tableStyle(id); 0623 attrs.append(" tableStyle=\"id:").append(QString::number(id)); 0624 if (tableStyle) 0625 attrs.append(" name:").append(tableStyle->name()); 0626 attrs.append("\""); 0627 } 0628 0629 QMap<int, QVariant> properties = tableFormat.properties(); 0630 foreach(int id, properties.keys()) { 0631 QString key, value; 0632 switch (id) { 0633 case QTextTableFormat::TableColumnWidthConstraints: 0634 case QTextFormat::BackgroundBrush: 0635 key = "background"; 0636 value = qvariant_cast<QBrush>(properties[id]).color().name(); // beware! 0637 break; 0638 case QTextFormat::BlockAlignment: 0639 key = "alignment"; 0640 switch (properties[id].toInt()) { 0641 case Qt::AlignLeft: 0642 value = "left"; 0643 break; 0644 case Qt::AlignRight: 0645 value = "right"; 0646 break; 0647 case Qt::AlignHCenter: 0648 value = "center"; 0649 break; 0650 case Qt::AlignJustify: 0651 value = "justify"; 0652 break; 0653 default: 0654 value.clear(); 0655 break; 0656 } 0657 break; 0658 case KoTableStyle::KeepWithNext: 0659 key = "keep-with-next"; 0660 value = properties[id].toBool() ? "true" : "false"; 0661 break; 0662 case KoTableStyle::BreakBefore: 0663 key = "break-before"; 0664 value = properties[id].toBool() ? "true" : "false"; 0665 break; 0666 case KoTableStyle::BreakAfter: 0667 key = "break-after"; 0668 value = properties[id].toBool() ? "true" : "false"; 0669 break; 0670 case KoTableStyle::MayBreakBetweenRows: 0671 key = "may-break-between-rows"; 0672 value = properties[id].toBool() ? "true" : "false"; 0673 break; 0674 case KoTableStyle::MasterPageName: 0675 key = "master-page-name"; 0676 value = properties[id].toString(); 0677 break; 0678 case QTextTableFormat::TableColumns: 0679 key = "columns"; 0680 value = QString::number(properties[id].toInt()); 0681 break; 0682 case QTextTableFormat::TableCellSpacing: 0683 key = "cell-spacing"; 0684 value = QString::number(properties[id].toDouble()); 0685 break; 0686 case QTextTableFormat::TableHeaderRowCount: 0687 key = "header-row-count"; 0688 value = QString::number(properties[id].toInt()); 0689 break; 0690 default: 0691 break; 0692 } 0693 if (!key.isEmpty()) 0694 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0695 } 0696 return attrs; 0697 } 0698 0699 QString KoTextDebug::frameAttributes(const QTextFrameFormat &frameFormat) 0700 { 0701 QString attrs; 0702 0703 QMap<int, QVariant> properties = frameFormat.properties(); 0704 foreach(int id, properties.keys()) { 0705 QString key, value; 0706 switch (id) { 0707 case QTextFrameFormat::FrameBorderBrush: 0708 break; 0709 case QTextFrameFormat::FrameBorderStyle: 0710 key = "border-style"; 0711 // determine border style. 0712 switch (properties[id].toInt()) { 0713 case QTextFrameFormat::BorderStyle_None: 0714 value = "None"; 0715 break; 0716 case QTextFrameFormat::BorderStyle_Dotted: 0717 value = "Dotted"; 0718 break; 0719 case QTextFrameFormat::BorderStyle_Dashed: 0720 value = "Dashed"; 0721 break; 0722 case QTextFrameFormat::BorderStyle_Solid: 0723 value = "Solid"; 0724 break; 0725 case QTextFrameFormat::BorderStyle_Double: 0726 value = "Double"; 0727 break; 0728 case QTextFrameFormat::BorderStyle_DotDash: 0729 value = "DotDash"; 0730 break; 0731 case QTextFrameFormat::BorderStyle_DotDotDash: 0732 value = "DotDotDash"; 0733 break; 0734 case QTextFrameFormat::BorderStyle_Groove: 0735 value = "Groove"; 0736 break; 0737 case QTextFrameFormat::BorderStyle_Ridge: 0738 value = "Ridge"; 0739 break; 0740 case QTextFrameFormat::BorderStyle_Inset: 0741 value = "Inset"; 0742 break; 0743 case QTextFrameFormat::BorderStyle_Outset: 0744 value = "Outset"; 0745 break; 0746 default: 0747 value = "Unknown"; 0748 break; 0749 } 0750 break; 0751 case QTextFrameFormat::FrameBorder: 0752 key = "border"; 0753 value = QString::number(properties[id].toDouble()); 0754 break; 0755 case QTextFrameFormat::FrameMargin: 0756 key = "margin"; 0757 value = QString::number(properties[id].toDouble()); 0758 break; 0759 case QTextFrameFormat::FramePadding: 0760 key = "padding"; 0761 value = QString::number(properties[id].toDouble()); 0762 break; 0763 case QTextFrameFormat::FrameWidth: 0764 key = "width"; 0765 value = QString::number(properties[id].toDouble()); 0766 break; 0767 case QTextFrameFormat::FrameHeight: 0768 key = "height"; 0769 value = QString::number(properties[id].toDouble()); 0770 break; 0771 case QTextFrameFormat::FrameTopMargin: 0772 key = "top-margin"; 0773 value = QString::number(properties[id].toDouble()); 0774 break; 0775 case QTextFrameFormat::FrameBottomMargin: 0776 key = "bottom-margin"; 0777 value = QString::number(properties[id].toDouble()); 0778 break; 0779 case QTextFrameFormat::FrameLeftMargin: 0780 key = "left-margin"; 0781 value = QString::number(properties[id].toDouble()); 0782 break; 0783 case QTextFrameFormat::FrameRightMargin: 0784 key = "right-margin"; 0785 value = QString::number(properties[id].toDouble()); 0786 break; 0787 default: 0788 break; 0789 } 0790 if (!key.isEmpty()) 0791 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0792 } 0793 return attrs; 0794 } 0795 0796 QString KoTextDebug::tableCellAttributes(const KoTableCellStyle &tableCellStyle) 0797 { 0798 QTextTableCellFormat format; 0799 tableCellStyle.applyStyle(format); 0800 return tableCellAttributes(format); 0801 } 0802 0803 QString KoTextDebug::tableCellAttributes(const QTextTableCellFormat &tableCellFormat) 0804 { 0805 QString attrs; 0806 KoStyleManager *styleManager = document ? KoTextDocument(document).styleManager() : 0; 0807 if (styleManager) { 0808 int id = tableCellFormat.intProperty(KoTableCellStyle::StyleId); 0809 KoTableCellStyle *tableCellStyle = styleManager->tableCellStyle(id); 0810 attrs.append(" tableCellStyle=\"id:").append(QString::number(id)); 0811 if (tableCellStyle) 0812 attrs.append(" name:").append(tableCellStyle->name()); 0813 attrs.append("\""); 0814 } 0815 0816 QMap<int, QVariant> properties = tableCellFormat.properties(); 0817 foreach(int id, properties.keys()) { 0818 QString key, value; 0819 switch (id) { 0820 case QTextTableCellFormat::TableCellRowSpan: 0821 key = "row-span"; 0822 value = QString::number(properties[id].toInt()); 0823 break; 0824 case QTextTableCellFormat::TableCellColumnSpan: 0825 key = "column-span"; 0826 value = QString::number(properties[id].toInt()); 0827 break; 0828 case QTextFormat::TableCellTopPadding: 0829 key = "top-padding"; 0830 value = QString::number(properties[id].toDouble()); 0831 break; 0832 case QTextFormat::TableCellBottomPadding: 0833 key = "bottom-padding"; 0834 value = QString::number(properties[id].toDouble()); 0835 break; 0836 case QTextFormat::TableCellLeftPadding: 0837 key = "left-padding"; 0838 value = QString::number(properties[id].toDouble()); 0839 break; 0840 case QTextFormat::TableCellRightPadding: 0841 key = "right-padding"; 0842 value = QString::number(properties[id].toDouble()); 0843 break; 0844 case KoTableCellStyle::MasterPageName: 0845 key = "master-page-name"; 0846 value = properties[id].toString(); 0847 break; 0848 default: 0849 break; 0850 } 0851 if (!key.isEmpty()) 0852 attrs.append(" ").append(key).append("=\"").append(value).append("\""); 0853 } 0854 return attrs; 0855 } 0856 0857 void KoTextDebug::dumpFrame(const QTextFrame *frame, QTextStream &out) 0858 { 0859 depth += INDENT; 0860 0861 dumpIndent(depth); 0862 out << "<frame" << frameAttributes(frame->frameFormat()) << '>' << endl; 0863 0864 QTextFrame::iterator iterator = frame->begin(); 0865 0866 for (; !iterator.atEnd() && !iterator.atEnd(); ++iterator) { 0867 QTextFrame *childFrame = iterator.currentFrame(); 0868 QTextBlock textBlock = iterator.currentBlock(); 0869 0870 if (childFrame) { 0871 QTextTable *table = qobject_cast<QTextTable *>(childFrame); 0872 if (table) { 0873 dumpTable(table, out); 0874 } else { 0875 dumpFrame(frame, out); 0876 } 0877 } else if (textBlock.isValid()) { 0878 dumpBlock(textBlock, out); 0879 } 0880 } 0881 0882 dumpIndent(depth); 0883 out << "</frame>" << endl; 0884 depth -= INDENT; 0885 } 0886 0887 void KoTextDebug::dumpBlock(const QTextBlock &block, QTextStream &out) 0888 { 0889 depth += INDENT; 0890 0891 QString attrs; 0892 attrs.append(paraAttributes(block.blockFormat())); 0893 //attrs.append(" blockcharformat=\"").append(textAttributes(QTextCursor(block).blockCharFormat())).append('\"'); 0894 attrs.append(textAttributes(QTextCursor(block).blockCharFormat())); 0895 0896 QTextList *list = block.textList(); 0897 if (list) { 0898 attrs.append(" list=\"item:").append(QString::number(list->itemNumber(block) + 1)).append('/') 0899 .append(QString::number(list->count())); 0900 attrs.append('"'); 0901 attrs.append(listAttributes(list->format())); 0902 } 0903 0904 dumpIndent(depth); 0905 out << "<block" << attrs << '>' << endl; 0906 0907 QTextBlock::Iterator iterator = block.begin(); 0908 for (; !iterator.atEnd() && !iterator.atEnd(); ++iterator) { 0909 QTextFragment fragment = iterator.fragment(); 0910 if (fragment.isValid()) { 0911 dumpFragment(fragment, out); 0912 } 0913 } 0914 dumpIndent(depth); 0915 out << "</block>" << endl; 0916 depth -= INDENT; 0917 if (block.next().isValid()) 0918 out << ' '; 0919 } 0920 0921 void KoTextDebug::dumpTable(const QTextTable *table, QTextStream &out) 0922 { 0923 depth += INDENT; 0924 0925 QString attrs; 0926 attrs.append(tableAttributes(table->format())); 0927 attrs.append(frameAttributes(table->frameFormat())); // include frame attributes too. 0928 0929 dumpIndent(depth); 0930 out << "<table" << attrs << '>' << endl; 0931 0932 // loop through all the cells in the table and dump the cells. 0933 for (int row = 0; row < table->rows(); ++row) { 0934 for (int column = 0; column < table->columns(); ++column) { 0935 dumpTableCell(table->cellAt(row, column), out); 0936 } 0937 } 0938 0939 dumpIndent(depth); 0940 out << "</table>" << endl; 0941 depth -= INDENT; 0942 } 0943 0944 void KoTextDebug::dumpTableCell(const QTextTableCell &cell, QTextStream &out) 0945 { 0946 depth += INDENT; 0947 0948 QString attrs; 0949 attrs.append(textAttributes(cell.format())); 0950 attrs.append(tableCellAttributes(cell.format().toTableCellFormat())); 0951 0952 dumpIndent(depth); 0953 out << "<cell" << attrs << '>' << endl; 0954 0955 // iterate through the cell content. 0956 QTextFrame::iterator cellIter = cell.begin(); 0957 while (!cellIter.atEnd()) { 0958 if (cellIter.currentFrame() != 0) { 0959 // content is a frame or table. 0960 dumpFrame(cellIter.currentFrame(), out); 0961 } else { 0962 // content is a block. 0963 dumpBlock(cellIter.currentBlock(), out); 0964 } 0965 ++cellIter; 0966 } 0967 0968 dumpIndent(depth); 0969 out << "</cell>\n"; 0970 0971 depth -= INDENT; 0972 } 0973 0974 void KoTextDebug::dumpFragment(const QTextFragment &fragment, QTextStream &out) 0975 { 0976 depth += INDENT; 0977 0978 QTextCharFormat charFormat = fragment.charFormat(); 0979 KoInlineObject *inlineObject = KoTextDocument(document).inlineTextObjectManager()->inlineTextObject(charFormat); 0980 if (inlineObject) { 0981 QString cf = inlineObjectAttributes(charFormat); 0982 0983 dumpIndent(depth); 0984 out << "<fragment" << cf << ">\n"; 0985 } else { 0986 QString cf = textAttributes(charFormat); 0987 0988 dumpIndent(depth); 0989 out << "<fragment" << cf << ">\n"; 0990 dumpIndent(depth + INDENT); 0991 out << '|' << fragment.text() << "|\n"; 0992 dumpIndent(depth); 0993 out << "</fragment>\n"; 0994 } 0995 0996 depth -= INDENT; 0997 } 0998