You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
422 lines
15 KiB
422 lines
15 KiB
/* 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);
|
|
}
|