summaryrefslogtreecommitdiffstats
path: root/filters/kword/abiword/ImportFormatting.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'filters/kword/abiword/ImportFormatting.cpp')
-rw-r--r--filters/kword/abiword/ImportFormatting.cpp421
1 files changed, 421 insertions, 0 deletions
diff --git a/filters/kword/abiword/ImportFormatting.cpp b/filters/kword/abiword/ImportFormatting.cpp
new file mode 100644
index 000000000..7c45f07a0
--- /dev/null
+++ b/filters/kword/abiword/ImportFormatting.cpp
@@ -0,0 +1,421 @@
+/* This file is part of the KDE project
+ Copyright (C) 2001, 2002, 2004 Nicolas GOUTTE <goutte@kde.org>
+
+ 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 <kdebug.h>
+
+#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 <FORMAT>
+ }
+
+ if (stackItem->fontSize>0)
+ {
+ element=mainDocument.createElement("SIZE");
+ element.setAttribute("value",stackItem->fontSize);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+ }
+
+ element=mainDocument.createElement("ITALIC");
+ element.setAttribute("value",stackItem->italic?1:0);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+
+ element=mainDocument.createElement("WEIGHT");
+ element.setAttribute("value",stackItem->bold?75:50);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+
+ element=mainDocument.createElement("UNDERLINE");
+ element.setAttribute("value",stackItem->underline?1:0);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+
+ element=mainDocument.createElement("STRIKEOUT");
+ element.setAttribute("value",stackItem->strikeout?1:0);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+
+ if ((stackItem->textPosition>=0) && (stackItem->textPosition<=2))
+ {
+ element=mainDocument.createElement("VERTALIGN");
+ element.setAttribute("value",stackItem->textPosition);
+ formatElementOut.appendChild(element); //Append to <FORMAT>
+ }
+
+ 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 <FORMAT>
+ }
+
+ 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 <FORMAT>
+ }
+}
+
+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 <STYLE> (singular), not <STYLES> (plural)
+
+ StackItem stackItem;
+ TQXmlAttributes attributes; // This is just a dummy for reusing already existing functions (TODO)
+ AbiPropsMap abiPropsMap;
+
+ PopulateProperties(&stackItem, styleData.m_props, attributes, abiPropsMap, false);
+ AddLayout(strStyleName, styleElement, &stackItem, mainDocument, abiPropsMap, styleData.m_level, true);
+}