void QEditor::updateStyles() { //kdDebug(9032) << "QEditor::updateStyles()" << endl; int tabwidth = tabStop(); QSourceColorizer* colorizer = dynamic_cast<QSourceColorizer*>( getDocument()->preProcessor() ); if( colorizer ){ setFont( colorizer->format( 0 )->font() ); setTabStopWidth( colorizer->format(0)->width('x') * tabwidth ); getDocument()->setTabStops( colorizer->format(0)->width('x') * tabwidth ); } Q3TextEdit::updateStyles(); }
void KoListLevelProperties::loadOdf(KoShapeLoadingContext& scontext, const KoXmlElement& style) { KoOdfLoadingContext &context = scontext.odfLoadingContext(); // The text:level attribute specifies the level of the number list // style. It can be used on all list-level styles. const int level = qMax(1, style.attributeNS(KoXmlNS::text, "level", QString()).toInt()); // The text:display-levels attribute specifies the number of // levels whose numbers are displayed at the current level. const QString displayLevel = style.attributeNS(KoXmlNS::text, "display-levels", QString()); const QString styleName = style.attributeNS(KoXmlNS::text, "style-name", QString()); KoCharacterStyle *cs = 0; if (!styleName.isEmpty()) { // kDebug(32500) << "Should use the style =>" << styleName << "<="; KoSharedLoadingData *sharedData = scontext.sharedData(KOTEXT_SHARED_LOADING_ID); KoTextSharedLoadingData *textSharedData = 0; if (sharedData) { textSharedData = dynamic_cast<KoTextSharedLoadingData *>(sharedData); } if (textSharedData) { cs = textSharedData->characterStyle(styleName, context.useStylesAutoStyles()); if (!cs) { kWarning(32500) << "Missing KoCharacterStyle!"; } else { // kDebug(32500) << "==> cs.name:" << cs->name(); // kDebug(32500) << "==> cs.styleId:" << cs->styleId(); setCharacterStyleId(cs->styleId()); } } } if (style.localName() == "list-level-style-bullet") { // list with bullets // special case bullets: //qDebug() << QChar(0x2202) << QChar(0x25CF) << QChar(0xF0B7) << QChar(0xE00C) //<< QChar(0xE00A) << QChar(0x27A2)<< QChar(0x2794) << QChar(0x2714) << QChar(0x2d) << QChar(0x2717); //1.6: KoParagCounter::loadOasisListStyle QString bulletChar = style.attributeNS(KoXmlNS::text, "bullet-char", QString()); // kDebug(32500) << "style.localName()=" << style.localName() << "level=" << level << "displayLevel=" << displayLevel << "bulletChar=" << bulletChar; if (bulletChar.isEmpty()) { // list without any visible bullets setStyle(KoListStyle::CustomCharItem); setBulletCharacter(QChar()); } else { // try to determinate the bullet we should use switch (bulletChar[0].unicode()) { case 0x2022: // bullet, a small disc -> circle setStyle(KoListStyle::Bullet); break; case 0x25CF: // black circle, large disc -> disc setStyle(KoListStyle::BlackCircle); break; case 0x25CB: //white circle, no fill setStyle(KoListStyle::CircleItem); break; case 0x25C6: // losange => rhombus setStyle(KoListStyle::RhombusItem); break; case 0x25A0: // square. Not in OASIS (reserved Unicode area!), but used in both OOo and kotext. setStyle(KoListStyle::SquareItem); break; case 0x27A2: // two-colors right-pointing triangle setStyle(KoListStyle::RightArrowHeadItem); break; case 0x2794: // arrow to right setStyle(KoListStyle::RightArrowItem); break; case 0x2714: // checkmark setStyle(KoListStyle::HeavyCheckMarkItem); break; case 0x2d: // minus setStyle(KoListStyle::CustomCharItem); break; case 0x2717: // cross setStyle(KoListStyle::BallotXItem); break; default: QChar customBulletChar = bulletChar[0]; kDebug(32500) << "Unhandled bullet code 0x" << QString::number((uint)customBulletChar.unicode(), 16) << bulletChar; kDebug(32500) << "Should use the style =>" << style.attributeNS(KoXmlNS::text, "style-name", QString()) << "<="; setStyle(KoListStyle::CustomCharItem); /* QString customBulletFont; // often StarSymbol when it comes from OO; doesn't matter, Qt finds it in another font if needed. if ( listStyleProperties.hasAttributeNS( KoXmlNS::style, "font-name" ) ) { customBulletFont = listStyleProperties.attributeNS( KoXmlNS::style, "font-name", QString() ); kDebug(32500) <<"customBulletFont style:font-name =" << listStyleProperties.attributeNS( KoXmlNS::style,"font-name", QString() ); } else if ( listStyleTextProperties.hasAttributeNS( KoXmlNS::fo, "font-family" ) ) { customBulletFont = listStyleTextProperties.attributeNS( KoXmlNS::fo, "font-family", QString() ); kDebug(32500) <<"customBulletFont fo:font-family =" << listStyleTextProperties.attributeNS( KoXmlNS::fo,"font-family", QString() ); } // ## TODO in fact we're supposed to read it from the style pointed to by text:style-name */ // setStyle(KoListStyle::BoxItem); //fallback break; } // switch setBulletCharacter(bulletChar[0]); } QString size = style.attributeNS(KoXmlNS::text, "bullet-relative-size", QString()); if (!size.isEmpty()) { setRelativeBulletSize(size.remove('%').toInt()); } } else if (style.localName() == "list-level-style-number" || style.localName() == "outline-level-style") { // it's a numbered list if (style.localName() == "outline-level-style") { setOutlineList(true); } setRelativeBulletSize(100); //arbitrary value for numbered list KoOdfNumberDefinition numberDefinition; numberDefinition.loadOdf(style); switch(numberDefinition.formatSpecification()) { case KoOdfNumberDefinition::Empty: setStyle(KoListStyle::None); break; case KoOdfNumberDefinition::AlphabeticLowerCase: setStyle(KoListStyle::AlphaLowerItem); break; case KoOdfNumberDefinition::AlphabeticUpperCase: setStyle(KoListStyle::UpperAlphaItem); break; case KoOdfNumberDefinition::RomanLowerCase: setStyle(KoListStyle::RomanLowerItem); break; case KoOdfNumberDefinition::RomanUpperCase: setStyle(KoListStyle::UpperRomanItem); break; case KoOdfNumberDefinition::ArabicAlphabet: setStyle(KoListStyle::ArabicAlphabet); break; case KoOdfNumberDefinition::Thai: setStyle(KoListStyle::Thai); break; case KoOdfNumberDefinition::Abjad: setStyle(KoListStyle::Abjad); break; case KoOdfNumberDefinition::AbjadMinor: setStyle(KoListStyle::AbjadMinor); break; case KoOdfNumberDefinition::Tibetan: setStyle(KoListStyle::Tibetan); break; case KoOdfNumberDefinition::Telugu: setStyle(KoListStyle::Telugu); break; case KoOdfNumberDefinition::Tamil: setStyle(KoListStyle::Tamil); break; case KoOdfNumberDefinition::Oriya: setStyle(KoListStyle::Oriya); break; case KoOdfNumberDefinition::Malayalam: setStyle(KoListStyle::Malayalam); break; case KoOdfNumberDefinition::Kannada: setStyle(KoListStyle::Kannada); break; case KoOdfNumberDefinition::Gurumukhi: setStyle(KoListStyle::Gurumukhi); break; case KoOdfNumberDefinition::Gujarati: setStyle(KoListStyle::Gujarati); break; case KoOdfNumberDefinition::Bengali: setStyle(KoListStyle::Bengali); break; case KoOdfNumberDefinition::Numeric: default: setStyle(KoListStyle::DecimalItem); } if (!numberDefinition.prefix().isNull()) { setListItemPrefix(numberDefinition.prefix()); } if (!numberDefinition.suffix().isNull()) { setListItemSuffix(numberDefinition.suffix()); } const QString startValue = style.attributeNS(KoXmlNS::text, "start-value", QString("1")); setStartValue(startValue.toInt()); } else if (style.localName() == "list-level-style-image") { // list with image setStyle(KoListStyle::ImageItem); KoImageCollection *imageCollection = scontext.imageCollection(); const QString href = style.attribute("href"); if(imageCollection) { if (!href.isEmpty()) { KoStore *store = context.store(); setBulletImage(imageCollection->createImageData(href, store)); } else { // check if we have an office:binary data element containing the image data const KoXmlElement &binaryData(KoXml::namedItemNS(style, KoXmlNS::office, "binary-data")); if (!binaryData.isNull()) { QImage image; if (image.loadFromData(QByteArray::fromBase64(binaryData.text().toLatin1()))) { setBulletImage(imageCollection->createImageData(image)); } } } } } else { // if not defined, we have do nothing // kDebug(32500) << "stylename else:" << style.localName() << "level=" << level << "displayLevel=" << displayLevel; setStyle(KoListStyle::DecimalItem); setListItemSuffix("."); } setLevel(level); if (!displayLevel.isEmpty()) setDisplayLevel(displayLevel.toInt()); KoXmlElement property; forEachElement(property, style) { if (property.namespaceURI() != KoXmlNS::style) continue; const QString localName = property.localName(); if (localName == "list-level-properties") { QString mode(property.attributeNS(KoXmlNS::text, "list-level-position-and-space-mode")); if (mode == "label-alignment") { QString textAlign(property.attributeNS(KoXmlNS::fo, "text-align")); setAlignment(textAlign.isEmpty() ? Qt::AlignLeft : KoText::alignmentFromString(textAlign)); KoXmlElement p; forEachElement(p, property) { if (p.namespaceURI() == KoXmlNS::style && p.localName() == "list-level-label-alignment") { // The <style:list-level-label-alignment> element and the fo:text-align attribute are used to define // the position and spacing of the list label and the list item. The values of the attributes for // text:space-before, text:min-label-width and text:min-label-distance are assumed to be 0. setAlignmentMode(true); QString textindent(p.attributeNS(KoXmlNS::fo, "text-indent")); QString marginleft(p.attributeNS(KoXmlNS::fo, "margin-left")); qreal ti = textindent.isEmpty() ? 0 : KoUnit::parseValue(textindent); qreal ml = marginleft.isEmpty() ? 0 : KoUnit::parseValue(marginleft); setTextIndent(ti); setMargin(ml); QString labelFollowedBy(p.attributeNS(KoXmlNS::text, "label-followed-by","space")); if(labelFollowedBy.compare("listtab",Qt::CaseInsensitive)==0) { setLabelFollowedBy(KoListStyle::ListTab); // list tab position is evaluated only if label is followed by listtab // the it is only evaluated if there is a list-tab-stop-position specified // if not specified use the fo:margin-left: QString tabStop(p.attributeNS(KoXmlNS::text, "list-tab-stop-position")); if (!tabStop.isEmpty()) { qreal tabStopPos = KoUnit::parseValue(tabStop); setTabStopPosition(qMax<qreal>(0.0, tabStopPos)); } }else if(labelFollowedBy.compare("nothing",Qt::CaseInsensitive)==0) { setLabelFollowedBy(KoListStyle::Nothing); }else { setLabelFollowedBy(KoListStyle::Space); } setMinimumWidth(0); setMinimumDistance(0); //TODO support ODF 18.829 text:label-followed-by and 18.832 text:list-tab-stop-position } } } if(alignmentMode()!=true ){ // default is mode == "label-width-and-position" // The text:space-before, text:min-label-width, text:minimum-label-distance and fo:text-align attributes // are used to define the position and spacing of the list label and the list item. setAlignmentMode(false); QString spaceBefore(property.attributeNS(KoXmlNS::text, "space-before")); if (!spaceBefore.isEmpty()) setIndent(KoUnit::parseValue(spaceBefore)); QString minLableWidth(property.attributeNS(KoXmlNS::text, "min-label-width")); if (!minLableWidth.isEmpty()) setMinimumWidth(KoUnit::parseValue(minLableWidth)); QString textAlign(property.attributeNS(KoXmlNS::fo, "text-align")); if (!textAlign.isEmpty()) setAlignment(KoText::alignmentFromString(textAlign)); QString minLableDistance(property.attributeNS(KoXmlNS::text, "min-label-distance")); if (!minLableDistance.isEmpty()) setMinimumDistance(KoUnit::parseValue(minLableDistance)); } QString width(property.attributeNS(KoXmlNS::fo, "width")); if (!width.isEmpty()) setWidth(KoUnit::parseValue(width)); QString height(property.attributeNS(KoXmlNS::fo, "height")); if (!height.isEmpty()) setHeight(KoUnit::parseValue(height)); } else if (localName == "text-properties") {
bool StyleReader::startElement(const QString&, const QString&, const QString &name, const QXmlAttributes &attrs) { if (name == "style:default-style") defaultStyle(attrs); else if (name == "style:paragraph-properties" || name == "style:text-properties" || name == "style:list-level-properties") styleProperties(attrs); else if (name == "style:style") styleStyle(attrs); else if (name == "style:tab-stop") tabStop(attrs); else if (name == "text:list-style") { for (int i = 0; i < attrs.count(); ++i) if (attrs.localName(i) == "style:name") currentList = attrs.value(i); currentListStyle = new ListStyle(currentList); inList = true; } else if (((name == "text:list-level-style-bullet") || (name == "text:list-level-style-number") || (name == "text:list-level-style-image")) && (inList)) { BulletType bstyle = Bullet; QString prefix = ""; QString suffix = ""; QString bullet = "-"; uint ulevel = 0; uint displayLevels = 1; uint startAt = 0; QString level = ""; for (int i = 0; i < attrs.count(); ++i) { if (attrs.localName(i) == "text:level") { ulevel = QString(attrs.value(i)).toUInt(); gtStyle *plist; if (attrs.value(i) == "1") { plist = listParents[currentList]; } else { int level = (attrs.value(i)).toInt(); --level; plist = styles[QString(currentList + "_%1").arg(level)]; } gtParagraphStyle *pstyle; if (plist == NULL) { if (styles.contains("default-style")) plist = new gtStyle(*(styles["default-style"])); else { gtParagraphStyle* pstyle = new gtParagraphStyle(*(writer->getDefaultStyle())); pstyle->setDefaultStyle(true); plist = dynamic_cast<gtStyle*>(pstyle); } } if (plist->target() == "paragraph") { pstyle = dynamic_cast<gtParagraphStyle*>(plist); assert(pstyle != NULL); gtParagraphStyle* tmp = new gtParagraphStyle(*pstyle); currentStyle = tmp; } else { gtParagraphStyle* tmp = new gtParagraphStyle(*plist); currentStyle = tmp; } currentStyle->setName(currentList + "_" + attrs.value(i)); } else if (attrs.localName(i) == "style:num-prefix") prefix = attrs.value(i); else if (attrs.localName(i) == "style:num-suffix") suffix = attrs.value(i); else if (attrs.localName(i) == "text:bullet-char") bullet = attrs.value(i); else if (attrs.localName(i) == "style:num-format") { QString tmp = attrs.value(i); if (tmp == "i") bstyle = LowerRoman; else if (tmp == "I") bstyle = UpperRoman; else if (tmp == "a") bstyle = LowerAlpha; else if (tmp == "A") bstyle = UpperAlpha; else if (tmp == "1") bstyle = Number; } else if (attrs.localName(i) == "text:start-value") { startAt = QString(attrs.value(i)).toUInt(); if (startAt > 0) --startAt; } else if (attrs.localName(i) == "text:display-levels") { displayLevels = QString(attrs.value(i)).toUInt(); if (displayLevels == 0) displayLevels = 1; } } if (bstyle == Bullet) { prefix = ""; suffix = ""; } ListLevel *llevel = new ListLevel(ulevel, bstyle, prefix, suffix, bullet, displayLevels, startAt); currentListStyle->addLevel(ulevel, llevel); readProperties = true; gtParagraphStyle* s = dynamic_cast<gtParagraphStyle*>(currentStyle); assert(s != NULL); if (bstyle == Bullet || bstyle == Graphic) { s->setBullet(true, bullet); } else { Q_ASSERT(((int) bstyle > 0) && ((int) bstyle < 6)); s->setNum(true, (int) bstyle -1, ulevel, startAt+1, prefix, suffix); } } else if ((name == "style:drop-cap") && (readProperties)) { if (currentStyle->target() == "paragraph") { for (int i = 0; i < attrs.count(); ++i) { if (attrs.localName(i) == "style:lines") { bool ok = false; QString sd = attrs.value(i); int dh = sd.toInt(&ok); if (ok) { gtParagraphStyle* s = dynamic_cast<gtParagraphStyle*>(currentStyle); assert(s != NULL); s->setDropCapHeight(dh); s->setDropCap(true); } } } } } else if (name == "style:font-face") { QString key = ""; QString family = ""; QString style = ""; for (int i = 0; i < attrs.count(); ++i) { if (attrs.localName(i) == "style:name") key = attrs.value(i); else if (attrs.localName(i) == "svg:font-family") { family = attrs.value(i); family = family.remove("'"); } else if (attrs.localName(i) == "style:font-style-name") style += attrs.value(i) + " "; } QString name = family + " " + style; name = name.simplified(); fonts[key] = name; } return true; }