/* This file is part of the KDE project Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE 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 #include "ImportFormatting.h" #include "ImportStyle.h" StackItem::StackItem() : fontSize(0), /* No explicit font size */ pos(0), italic(false), bold(false), underline(false), strikeout(false), textPosition(0) { } StackItem::~StackItem() { } void PopulateProperties(StackItem* stackItem, const TQString& strStyleProps, const TQXmlAttributes& attributes, AbiPropsMap& abiPropsMap, const bool allowInit) // TODO: find a better name for this function { if (allowInit) { // Initialize the TQStrings with the previous values of the properties // TODO: any others needed? if (stackItem->italic) { abiPropsMap.setProperty("font-style","italic"); } if (stackItem->bold) { abiPropsMap.setProperty("font-weight","bold"); } if (stackItem->underline) { abiPropsMap.setProperty("text-decoration","underline"); } else if (stackItem->strikeout) { abiPropsMap.setProperty("text-decoration","line-through"); } } // Style goes first kdDebug(30506)<< "===== from style=\"" << strStyleProps << "\"" << endl; abiPropsMap.splitAndAddAbiProps(strStyleProps); // Treat the props attributes in the two available flavors: lower case and upper case. kdDebug(30506)<< "========== props=\"" << attributes.value("props") << "\"" << endl; abiPropsMap.splitAndAddAbiProps(attributes.value("props")); abiPropsMap.splitAndAddAbiProps(attributes.value("PROPS")); // PROPS is deprecated stackItem->italic=(abiPropsMap["font-style"].getValue()=="italic"); stackItem->bold=(abiPropsMap["font-weight"].getValue()=="bold"); TQString strDecoration=abiPropsMap["text-decoration"].getValue(); stackItem->underline=(strDecoration=="underline"); stackItem->strikeout=(strDecoration=="line-through"); TQString strTextPosition=abiPropsMap["text-position"].getValue(); if (strTextPosition=="subscript") { stackItem->textPosition=1; } else if (strTextPosition=="superscript") { stackItem->textPosition=2; } else if (!strTextPosition.isEmpty()) { // we have any other new value, assume it means normal! stackItem->textPosition=0; } TQString strColour=abiPropsMap["color"].getValue(); if (!strColour.isEmpty()) { // The colour information is *not* lead by a hash (#) stackItem->fgColor.setNamedColor("#"+strColour); } TQString strBackgroundTextColor=abiPropsMap["bgcolor"].getValue(); if (strBackgroundTextColor=="transparent") { // KWord has no idea what transparency is, so we use white stackItem->bgColor.setRgb(255,255,255); } else if(!strBackgroundTextColor.isEmpty()) { // The colour information is *not* lead by a hash (#) stackItem->bgColor.setNamedColor("#"+strBackgroundTextColor); } TQString strFontSize=abiPropsMap["font-size"].getValue(); if (!strFontSize.isEmpty()) { const int size=int(ValueWithLengthUnit(strFontSize)); if (size>0) { stackItem->fontSize=size; } } TQString strFontFamily=abiPropsMap["font-family"].getValue(); if (!strFontFamily.isEmpty() && (strFontFamily!="(null)")) { // TODO: transform the font-family in a font that we have on the system on which KWord runs. stackItem->fontName=strFontFamily; } } void AddFormat(TQDomElement& formatElementOut, StackItem* stackItem, TQDomDocument& mainDocument) { TQDomElement element; if (!stackItem->fontName.isEmpty()) { element=mainDocument.createElement("FONT"); element.setAttribute("name",stackItem->fontName); // Font name formatElementOut.appendChild(element); //Append to } if (stackItem->fontSize>0) { element=mainDocument.createElement("SIZE"); element.setAttribute("value",stackItem->fontSize); formatElementOut.appendChild(element); //Append to } element=mainDocument.createElement("ITALIC"); element.setAttribute("value",stackItem->italic?1:0); formatElementOut.appendChild(element); //Append to element=mainDocument.createElement("WEIGHT"); element.setAttribute("value",stackItem->bold?75:50); formatElementOut.appendChild(element); //Append to element=mainDocument.createElement("UNDERLINE"); element.setAttribute("value",stackItem->underline?1:0); formatElementOut.appendChild(element); //Append to element=mainDocument.createElement("STRIKEOUT"); element.setAttribute("value",stackItem->strikeout?1:0); formatElementOut.appendChild(element); //Append to if ((stackItem->textPosition>=0) && (stackItem->textPosition<=2)) { element=mainDocument.createElement("VERTALIGN"); element.setAttribute("value",stackItem->textPosition); formatElementOut.appendChild(element); //Append to } if (stackItem->fgColor.isValid()) { element=mainDocument.createElement("COLOR"); element.setAttribute("red", stackItem->fgColor.red()); element.setAttribute("green",stackItem->fgColor.green()); element.setAttribute("blue", stackItem->fgColor.blue()); formatElementOut.appendChild(element); //Append to } if (stackItem->bgColor.isValid()) { element=mainDocument.createElement("TEXTBACKGROUNDCOLOR"); element.setAttribute("red", stackItem->bgColor.red()); element.setAttribute("green",stackItem->bgColor.green()); element.setAttribute("blue", stackItem->bgColor.blue()); formatElementOut.appendChild(element); //Append to } } void AddLayout(const TQString& strStyleName, TQDomElement& layoutElement, StackItem* stackItem, TQDomDocument& mainDocument, const AbiPropsMap& abiPropsMap, const int level, const bool isStyle) { TQDomElement element; element=mainDocument.createElement("NAME"); element.setAttribute("value",strStyleName); layoutElement.appendChild(element); TQString strFollowing=abiPropsMap["followedby"].getValue(); TQDomElement followingElement=mainDocument.createElement("FOLLOWING"); followingElement.setAttribute("name",strFollowing); if ((strFollowing.isEmpty()) || (strFollowing=="Current Settings")) // "Current Settings" is only a pseudo-style! { // We have no idea what style follows if (isStyle) { // We are a style, so we need a default followingElement.setAttribute("name","Normal"); layoutElement.appendChild(followingElement); } // Else: we are a layout, so we leave the work to KWord (from the style) } else { // Following style is defined // TODO: we should be sure that this style is defined! layoutElement.appendChild(followingElement); } TQString strFlow=abiPropsMap["text-align"].getValue(); element=mainDocument.createElement("FLOW"); if ((strFlow=="left") || (strFlow=="center") || (strFlow=="right") || (strFlow=="justify")) { element.setAttribute("align",strFlow); } else { element.setAttribute("align","left"); } layoutElement.appendChild(element); int kwordDepth; int kwordNumberingType; int kwordType; TQString kwordRightText; // level is 1 based like AbiWord, any value lower than 1 means no level! if ((level<=0) || (level>=15)) { kwordDepth=0; kwordNumberingType=2; kwordType=0; } else { kwordDepth=level-1; kwordNumberingType=1; kwordType=1; // PROVISORY kwordRightText="."; } element=mainDocument.createElement("COUNTER"); element.setAttribute("type",kwordType); element.setAttribute("depth",kwordDepth); element.setAttribute("start",1); element.setAttribute("numberingtype",kwordNumberingType); element.setAttribute("lefttext",""); element.setAttribute("righttext",kwordRightText); element.setAttribute("bullet",64); element.setAttribute("bulletfont","Symbol"); element.setAttribute("customdef",""); layoutElement.appendChild(element); TQString strLeftMargin=abiPropsMap["margin-left"].getValue(); TQString strRightMargin=abiPropsMap["margin-right"].getValue(); TQString strTextIndent=abiPropsMap["text-indent"].getValue(); if ( !strLeftMargin.isEmpty() || !strRightMargin.isEmpty() || !strTextIndent.isEmpty() ) { element=mainDocument.createElement("INDENTS"); if (!strLeftMargin.isEmpty()) element.setAttribute("left",ValueWithLengthUnit(strLeftMargin)); if (!strRightMargin.isEmpty()) element.setAttribute("right",ValueWithLengthUnit(strRightMargin)); if (!strTextIndent.isEmpty()) element.setAttribute("first",ValueWithLengthUnit(strTextIndent)); layoutElement.appendChild(element); } TQString strTopMargin=abiPropsMap["margin-top"].getValue(); TQString strBottomMargin=abiPropsMap["margin-bottom"].getValue(); if (!strTopMargin.isEmpty() || !strBottomMargin.isEmpty() ) { element=mainDocument.createElement("OFFSETS"); const double margin_top=ValueWithLengthUnit(strTopMargin); const double margin_bottom=ValueWithLengthUnit(strBottomMargin); // Zero is propably a valid value! if (!strBottomMargin.isEmpty()) element.setAttribute("after",margin_bottom); if (!strTopMargin.isEmpty()) element.setAttribute("before",margin_top); layoutElement.appendChild(element); } TQString strLineHeight=abiPropsMap["line-height"].getValue(); if(!strLineHeight.isEmpty()) { element=mainDocument.createElement("LINESPACING"); double lineHeight; // Do we have a unit symbol or not? bool flag=false; lineHeight=strLineHeight.toDouble(&flag); if (flag) { if ( lineHeight == 1.0 ) { element.setAttribute( "value", "single" ); element.setAttribute( "type", "single" ); } else if (lineHeight==1.5) { element.setAttribute( "value", "oneandhalf" ); element.setAttribute( "type", "oneandhalf" ); } else if (lineHeight==2.0) { element.setAttribute( "value", "double" ); element.setAttribute( "type", "double" ); } else if ( lineHeight > 0.0 ) { element.setAttribute( "type", "multiple" ); element.setAttribute( "spacingvalue", lineHeight ); } else { kdWarning(30506) << "Unsupported line height " << lineHeight << " (Ignoring !)" << endl; } } else { // Something went wrong, so we assume that an unit is specified bool atleast = false; lineHeight = ValueWithLengthUnit( strLineHeight, &atleast ); if (lineHeight>1.0) { if ( atleast ) { kdDebug(30506) << "at-least" << endl; element.setAttribute( "type", "atleast" ); } else { element.setAttribute( "type", "exact" ); } // We have a meaningful value, so use it! //element.setAttribute( "value", lineHeight ); element.setAttribute( "spacingvalue", lineHeight ); } } layoutElement.appendChild(element); } TQString strTab=abiPropsMap["tabstops"].getValue(); if(!strTab.isEmpty()) { TQStringList listTab=TQStringList::split(",",strTab); for ( TQStringList::Iterator it = listTab.begin(); it != listTab.end(); ++it ) { TQStringList tab=TQStringList::split("/",*it); const TQChar tabType=tab[1].at(0); const TQChar tabFilling=tab[1].at(1); // Might be empty in old AbiWord files int type; if (tabType=='L') // left type=0; else if (tabType=='C') // center type=1; else if (tabType=='R') // right type=2; else if(tabType=='D') // decimal type=3; else if(tabType=='B') // bar (unsupported by KWord) type=0; else { kdWarning(30506)<<"Unknown tabulator type: " << TQString(tabType) << endl; type=0; } int filling; int width=72; // Any non-null value if (tabFilling.isNull() || tabFilling=='0') // No filling filling=0; else if (tabFilling=='1') // dot { filling=1; width=2; // TODO: which width? } else if (tabFilling=='3') // underline filling=2; else filling=0; element=mainDocument.createElement("TABULATOR"); element.setAttribute("ptpos",ValueWithLengthUnit(tab[0])); element.setAttribute("type",type); element.setAttribute("filling",filling); element.setAttribute("width",width); layoutElement.appendChild(element); } } TQDomElement formatElementOut=mainDocument.createElement("FORMAT"); layoutElement.appendChild(formatElementOut); AddFormat(formatElementOut, stackItem, mainDocument); } void AddStyle(TQDomElement& styleElement, const TQString& strStyleName, const StyleData& styleData, TQDomDocument& mainDocument) { // NOTE; styleElement is