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.
758 lines
24 KiB
758 lines
24 KiB
/* This file is part of the KDE project
|
|
Copyright (c) 2003 Rob Buis <buis@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 "oodrawimport.h"
|
|
|
|
#include <math.h>
|
|
|
|
#include <tqdatetime.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqdir.h>
|
|
|
|
#include <kzip.h>
|
|
#include <karchive.h>
|
|
#include <kdebug.h>
|
|
#include <KoUnit.h>
|
|
#include <KoPageLayout.h>
|
|
#include <KoDocumentInfo.h>
|
|
#include <KoDocument.h>
|
|
#include <ooutils.h>
|
|
#include <KoDom.h>
|
|
|
|
#include <kgenericfactory.h>
|
|
#include <KoFilterChain.h>
|
|
#include <KoGlobal.h>
|
|
|
|
#include <shapes/vellipse.h>
|
|
#include <shapes/vrectangle.h>
|
|
#include <shapes/vpolygon.h>
|
|
|
|
#include <core/vfill.h>
|
|
#include <core/vgroup.h>
|
|
|
|
typedef KGenericFactory<OoDrawImport, KoFilter> OoDrawImportFactory;
|
|
K_EXPORT_COMPONENT_FACTORY( liboodrawimport, OoDrawImportFactory( "kofficefilters" ) )
|
|
|
|
|
|
OoDrawImport::OoDrawImport( KoFilter *, const char *, const TQStringList & )
|
|
: KoFilter(),
|
|
m_styles( 23, true ),
|
|
m_styleStack( ooNS::style, ooNS::fo )
|
|
{
|
|
m_styles.setAutoDelete( true );
|
|
}
|
|
|
|
OoDrawImport::~OoDrawImport()
|
|
{
|
|
}
|
|
|
|
KoFilter::ConversionStatus OoDrawImport::convert( TQCString const & from, TQCString const & to )
|
|
{
|
|
kdDebug() << "Entering Oodraw Import filter: " << from << " - " << to << endl;
|
|
|
|
if( from != "application/vnd.sun.xml.draw" || to != "application/x-karbon" )
|
|
{
|
|
kdWarning() << "Invalid mimetypes " << from << " " << to << endl;
|
|
return KoFilter::NotImplemented;
|
|
}
|
|
|
|
m_zip = new KZip( m_chain->inputFile() );
|
|
|
|
if ( !m_zip->open( IO_ReadOnly ) )
|
|
{
|
|
kdError(30518) << "Couldn't open the requested file "<< m_chain->inputFile() << endl;
|
|
delete m_zip;
|
|
return KoFilter::FileNotFound;
|
|
}
|
|
|
|
KoFilter::ConversionStatus preStatus = openFile();
|
|
|
|
if( preStatus != KoFilter::OK )
|
|
{
|
|
m_zip->close();
|
|
delete m_zip;
|
|
return preStatus;
|
|
}
|
|
/*TQDomDocument docinfo;
|
|
createDocumentInfo( docinfo );
|
|
|
|
// store document info
|
|
KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
|
|
if( out )
|
|
{
|
|
TQCString info = docinfo.toCString();
|
|
//kdDebug() << " info :" << info << endl;
|
|
// WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end.
|
|
out->writeBlock( info , info.length() );
|
|
}*/
|
|
TQDomDocument docinfo;
|
|
createDocumentInfo( docinfo );
|
|
// store document info
|
|
KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
|
|
if( out )
|
|
{
|
|
TQCString info = docinfo.toCString();
|
|
//kdDebug(30518) << " info :" << info << endl;
|
|
// WARNING: we cannot use KoStore::write(const TQByteArray&) because it gives an extra NULL character at the end.
|
|
out->writeBlock( info , info.length() );
|
|
}
|
|
|
|
convert();
|
|
TQDomDocument outdoc = m_document.saveXML();
|
|
// add paper info, we always need custom for svg (Rob)
|
|
TQDomElement paper = outdoc.createElement( "PAPER" );
|
|
outdoc.documentElement().appendChild( paper );
|
|
paper.setAttribute( "format", PG_CUSTOM );
|
|
paper.setAttribute( "width", m_document.width() );
|
|
paper.setAttribute( "height", m_document.height() );
|
|
|
|
// store document content
|
|
out = m_chain->storageFile( "maindoc.xml", KoStore::Write );
|
|
if( out )
|
|
{
|
|
TQCString content = outdoc.toCString();
|
|
kdDebug() << " content :" << content << endl;
|
|
out->writeBlock( content , content.length() );
|
|
}
|
|
m_zip->close();
|
|
delete m_zip;
|
|
|
|
kdDebug() << "######################## OoDrawImport::convert done ####################" << endl;
|
|
|
|
return KoFilter::OK;
|
|
}
|
|
|
|
// Very related to OoWriterImport::createDocumentInfo
|
|
void OoDrawImport::createDocumentInfo( TQDomDocument &docinfo )
|
|
{
|
|
docinfo = KoDocument::createDomDocument( "document-info" /*DTD name*/, "document-info" /*tag name*/, "1.1" );
|
|
|
|
OoUtils::createDocumentInfo(m_meta, docinfo);
|
|
//kdDebug(30518) << " meta-info :" << m_meta.toCString() << endl;
|
|
}
|
|
|
|
|
|
// Very related to OoWriterImport::openFile()
|
|
KoFilter::ConversionStatus OoDrawImport::openFile()
|
|
{
|
|
KoFilter::ConversionStatus status = loadAndParse( "content.xml", m_content );
|
|
if ( status != KoFilter::OK )
|
|
{
|
|
kdError(30518) << "Content.xml could not be parsed correctly! Aborting!" << endl;
|
|
return status;
|
|
}
|
|
|
|
// We do not stop if the following calls fail.
|
|
TQDomDocument styles;
|
|
loadAndParse( "styles.xml", styles );
|
|
loadAndParse( "meta.xml", m_meta );
|
|
loadAndParse( "settings.xml", m_settings );
|
|
|
|
emit sigProgress( 10 );
|
|
createStyleMap( styles );
|
|
|
|
return KoFilter::OK;
|
|
}
|
|
|
|
void OoDrawImport::convert()
|
|
{
|
|
m_document.saveAsPath( false );
|
|
|
|
TQDomElement content = m_content.documentElement();
|
|
|
|
// content.xml contains some automatic-styles that we need to store
|
|
TQDomNode automaticStyles = KoDom::namedItemNS( content, ooNS::office, "automatic-styles" );
|
|
if( !automaticStyles.isNull() )
|
|
insertStyles( automaticStyles.toElement() );
|
|
|
|
TQDomNode body = KoDom::namedItemNS( content, ooNS::office, "body" );
|
|
if( body.isNull() )
|
|
return;
|
|
|
|
// we take the settings of the first slide for the whole document.
|
|
TQDomElement drawPage = KoDom::namedItemNS( body, ooNS::draw, "page" );
|
|
if( drawPage.isNull() ) // no pages? give up.
|
|
return;
|
|
|
|
TQDomElement *master = m_styles[drawPage.attributeNS( ooNS::draw, "master-page-name", TQString() )];
|
|
TQDomElement *style = m_styles[master->attributeNS( ooNS::style, "page-master-name", TQString() )];
|
|
TQDomElement properties = KoDom::namedItemNS( *style, ooNS::style, "properties" ).toElement();
|
|
|
|
if( properties.isNull() )
|
|
{
|
|
m_document.setWidth( 550.0 );
|
|
m_document.setHeight( 841.0 );
|
|
}
|
|
else
|
|
{
|
|
m_document.setWidth( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-width", TQString() ) ) );
|
|
m_document.setHeight( KoUnit::parseValue(properties.attributeNS( ooNS::fo, "page-height", TQString() ) ) );
|
|
}
|
|
|
|
// parse all pages
|
|
for( TQDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() )
|
|
{
|
|
TQDomElement dp = drawPage.toElement();
|
|
m_styleStack.clear(); // remove all styles
|
|
fillStyleStack( dp );
|
|
//m_styleStack.setPageMark();
|
|
|
|
// set the pagetitle
|
|
//TQDomElement titleElement = doc.createElement( "Title" );
|
|
//titleElement.setAttribute( "title", dp.attributeNS( "name" ) );
|
|
//pageTitleElement.appendChild( titleElement );
|
|
|
|
parseGroup( 0L, dp );
|
|
}
|
|
}
|
|
|
|
|
|
KoFilter::ConversionStatus OoDrawImport::loadAndParse(const TQString& filename, TQDomDocument& doc)
|
|
{
|
|
return OoUtils::loadAndParse( filename, doc, m_zip);
|
|
}
|
|
|
|
void
|
|
OoDrawImport::parseGroup( VGroup *parent, const TQDomElement& parentobject )
|
|
{
|
|
// parse all objects
|
|
for( TQDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() )
|
|
{
|
|
TQDomElement o = object.toElement();
|
|
if( o.namespaceURI() != ooNS::draw ) continue;
|
|
TQString name = o.localName();
|
|
TQString drawID = o.attributeNS( ooNS::draw, "id", TQString() );
|
|
VObject *obj = 0L;
|
|
|
|
if( name == "g" ) // polyline
|
|
{
|
|
storeObjectStyles( o );
|
|
VGroup *group = new VGroup( parent );
|
|
appendPen( *group );
|
|
appendBrush( *group );
|
|
obj = group;
|
|
parseGroup( group, o );
|
|
}
|
|
else if( name == "rect" ) // rectangle
|
|
{
|
|
storeObjectStyles( o );
|
|
double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) );
|
|
double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) );
|
|
double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) );
|
|
double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) );
|
|
int corner = static_cast<int>( KoUnit::parseValue( o.attributeNS( ooNS::draw, "corner-radius", TQString() ) ) );
|
|
VRectangle *rect = new VRectangle( parent, KoPoint( x, y ), w, h, corner );
|
|
appendPen( *rect );
|
|
appendBrush( *rect );
|
|
obj = rect;
|
|
}
|
|
else if( name == "circle" || name == "ellipse" )
|
|
{
|
|
storeObjectStyles( o );
|
|
double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) );
|
|
double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) );
|
|
double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) );
|
|
double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) ) - h;
|
|
double start = o.attributeNS( ooNS::draw, "start-angle", TQString() ).toDouble();
|
|
double end = o.attributeNS( ooNS::draw, "end-angle", TQString() ).toDouble();
|
|
TQString kind = o.attributeNS( ooNS::draw, "kind", TQString() );
|
|
VEllipse::VEllipseType type = VEllipse::full;
|
|
if( !kind.isEmpty() )
|
|
{
|
|
if( kind == "section" )
|
|
type = VEllipse::cut;
|
|
else if( kind == "cut" )
|
|
type = VEllipse::section;
|
|
else if( kind == "arc" )
|
|
type = VEllipse::arc;
|
|
}
|
|
VEllipse *ellipse = new VEllipse( parent, KoPoint( x, y ), w, h, type, start, end );
|
|
appendPen( *ellipse );
|
|
// arc has no brush
|
|
if( kind != "arc" )
|
|
appendBrush( *ellipse );
|
|
obj = ellipse;
|
|
}
|
|
else if( name == "line" ) // line
|
|
{
|
|
storeObjectStyles( o );
|
|
VPath *line = new VPath( parent );
|
|
double x1 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x1", TQString() ) );
|
|
double y1 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y1", TQString() ) ) );
|
|
double x2 = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x2", TQString() ) );
|
|
double y2 = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y2", TQString() ) ) );
|
|
line->moveTo( KoPoint( x1, y1 ) );
|
|
line->lineTo( KoPoint( x2, y2 ) );
|
|
appendPen( *line );
|
|
appendBrush( *line );
|
|
obj = line;
|
|
}
|
|
else if( name == "polyline" ) // polyline
|
|
{
|
|
storeObjectStyles( o );
|
|
VPath *polyline = new VPath( parent );
|
|
appendPoints( *polyline, o);
|
|
appendPen( *polyline );
|
|
appendBrush( *polyline );
|
|
obj = polyline;
|
|
}
|
|
else if( name == "polygon" ) // polygon
|
|
{
|
|
storeObjectStyles( o );
|
|
//VPolygon *polygon = new VPolygon( parent );
|
|
//polygon->load( o );
|
|
VPath *polygon = new VPath( parent );
|
|
appendPoints( *polygon, o );
|
|
appendPen( *polygon );
|
|
appendBrush( *polygon );
|
|
obj = polygon;
|
|
}
|
|
else if( name == "path" ) // path
|
|
{
|
|
storeObjectStyles( o );
|
|
VPath *path = new VPath( parent );
|
|
path->loadSvgPath( o.attributeNS( ooNS::svg, "d", TQString() ) );
|
|
KoRect rect = parseViewBox( o );
|
|
double x = KoUnit::parseValue( o.attributeNS( ooNS::svg, "x", TQString() ) );
|
|
double y = ymirror( KoUnit::parseValue( o.attributeNS( ooNS::svg, "y", TQString() ) ) );
|
|
double w = KoUnit::parseValue( o.attributeNS( ooNS::svg, "width", TQString() ) );
|
|
double h = KoUnit::parseValue( o.attributeNS( ooNS::svg, "height", TQString() ) );
|
|
TQWMatrix mat;
|
|
mat.translate( x, y );
|
|
mat.scale( w / rect.width(), -h / rect.height() );
|
|
path->transform( mat );
|
|
appendPen( *path );
|
|
appendBrush( *path );
|
|
obj = path;
|
|
}
|
|
/*else if( name == "draw:image" ) // image
|
|
{
|
|
storeObjectStyles( o );
|
|
e = doc.createElement( "OBJECT" );
|
|
e.setAttribute( "type", 0 );
|
|
appendImage( doc, e, pictureElement, o );
|
|
}*/
|
|
else
|
|
{
|
|
kdDebug() << "Unsupported object '" << name << "'" << endl;
|
|
continue;
|
|
}
|
|
if( parent && obj )
|
|
parent->append( obj );
|
|
else if( obj )
|
|
m_document.append( obj );
|
|
}
|
|
}
|
|
|
|
void
|
|
OoDrawImport::appendPen( VObject &obj )
|
|
{
|
|
if( m_styleStack.hasAttributeNS( ooNS::draw, "stroke" ) )
|
|
{
|
|
VStroke stroke;
|
|
|
|
if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "none" )
|
|
stroke.setType( VStroke::none );
|
|
else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "solid" )
|
|
stroke.setType( VStroke::solid );
|
|
else if( m_styleStack.attributeNS( ooNS::draw, "stroke" ) == "dash" )
|
|
{
|
|
TQValueList<float> dashes;
|
|
stroke.setType( VStroke::solid );
|
|
TQString style = m_styleStack.attributeNS( ooNS::draw, "stroke-dash" );
|
|
if( style == "Ultrafine Dashed" ||
|
|
style == "Fine Dashed (var)" || style == "Dashed (var)" )
|
|
stroke.dashPattern().setArray( dashes << 2 << 2 );
|
|
else if( style == "Fine Dashed" )
|
|
stroke.dashPattern().setArray( dashes << 10 << 10 );
|
|
else if( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" ||
|
|
style == "Line with Fine Dots" )
|
|
stroke.dashPattern().setArray( dashes << 2 << 10 );
|
|
else if( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" )
|
|
stroke.dashPattern().setArray( dashes << 3 << 3 );
|
|
else if( style == "2 Dots 1 Dash" )
|
|
stroke.dashPattern().setArray( dashes << 2 << 1 );
|
|
}
|
|
if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-width" ) )
|
|
{
|
|
double lwidth = KoUnit::parseValue( m_styleStack.attributeNS( ooNS::svg, "stroke-width" ) );
|
|
if( lwidth == 0 )
|
|
lwidth = 1.0;
|
|
stroke.setLineWidth( lwidth );
|
|
}
|
|
if( m_styleStack.hasAttributeNS( ooNS::svg, "stroke-color" ) )
|
|
{
|
|
VColor c;
|
|
parseColor( c, m_styleStack.attributeNS( ooNS::svg, "stroke-color" ) );
|
|
stroke.setColor( c );
|
|
}
|
|
|
|
obj.setStroke( stroke );
|
|
}
|
|
}
|
|
|
|
void
|
|
OoDrawImport::appendBrush( VObject &obj )
|
|
{
|
|
if( m_styleStack.hasAttributeNS( ooNS::draw, "fill" ) )
|
|
{
|
|
const TQString fill = m_styleStack.attributeNS( ooNS::draw, "fill" );
|
|
VFill f;
|
|
|
|
if( fill == "solid" )
|
|
{
|
|
f.setType( VFill::solid );
|
|
if( m_styleStack.hasAttributeNS( ooNS::draw, "fill-color" ) )
|
|
{
|
|
VColor c;
|
|
parseColor( c, m_styleStack.attributeNS( ooNS::draw, "fill-color" ) );
|
|
f.setColor( c );
|
|
}
|
|
}
|
|
else if( fill == "gradient" )
|
|
{
|
|
VGradient gradient;
|
|
gradient.clearStops();
|
|
gradient.setRepeatMethod( VGradient::none );
|
|
TQString style = m_styleStack.attributeNS( ooNS::draw, "fill-gradient-name" );
|
|
|
|
TQDomElement* draw = m_draws[style];
|
|
if( draw )
|
|
{
|
|
double border = 0.0;
|
|
if( draw->hasAttributeNS( ooNS::draw, "border" ) )
|
|
border += draw->attributeNS( ooNS::draw, "border", TQString() ).remove( '%' ).toDouble() / 100.0;
|
|
VColor c;
|
|
parseColor( c, draw->attributeNS( ooNS::draw, "start-color", TQString() ) );
|
|
gradient.addStop( c, border, 0.5 );
|
|
parseColor( c, draw->attributeNS( ooNS::draw, "end-color", TQString() ) );
|
|
gradient.addStop( c, 1.0, 0.5 );
|
|
|
|
TQString type = draw->attributeNS( ooNS::draw, "style", TQString() );
|
|
if( type == "linear" || type == "axial" )
|
|
{
|
|
gradient.setType( VGradient::linear );
|
|
int angle = draw->attributeNS( ooNS::draw, "angle", TQString() ).toInt() / 10;
|
|
|
|
// make sure the angle is between 0 and 359
|
|
angle = abs( angle );
|
|
angle -= ( (int) ( angle / 360 ) ) * 360;
|
|
|
|
// What we are trying to do here is to find out if the given
|
|
// angle belongs to a horizontal, vertical or diagonal gradient.
|
|
int lower, upper, nearAngle = 0;
|
|
for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
|
|
{
|
|
if( upper >= angle )
|
|
{
|
|
int distanceToUpper = abs( angle - upper );
|
|
int distanceToLower = abs( angle - lower );
|
|
nearAngle = distanceToUpper > distanceToLower ? lower : upper;
|
|
break;
|
|
}
|
|
}
|
|
KoRect rect = obj.boundingBox();
|
|
KoPoint origin, vector;
|
|
// nearAngle should now be one of: 0, 45, 90, 135, 180...
|
|
kdDebug() << "nearAngle: " << nearAngle << endl;
|
|
if( nearAngle == 0 || nearAngle == 180 )
|
|
{
|
|
origin.setX( rect.x() + rect.width() );
|
|
origin.setY( rect.y() + rect.height());
|
|
vector.setX( rect.x() + rect.width() );
|
|
vector.setY( rect.y() );
|
|
}
|
|
else if( nearAngle == 90 || nearAngle == 270 )
|
|
{
|
|
origin.setX( rect.x() );
|
|
origin.setY( rect.y() + rect.height() );
|
|
vector.setX( rect.x() + rect.width() );
|
|
vector.setY( rect.y() + rect.height() );
|
|
}
|
|
else if( nearAngle == 45 || nearAngle == 225 )
|
|
{
|
|
origin.setX( rect.x() );
|
|
origin.setY( rect.y() );
|
|
vector.setX( rect.x() + rect.width() );
|
|
vector.setY( rect.y() + rect.height() );
|
|
}
|
|
else if( nearAngle == 135 || nearAngle == 315 )
|
|
{
|
|
origin.setX( rect.x() + rect.width() );
|
|
origin.setY( rect.y() + rect.height() );
|
|
vector.setX( rect.x() );
|
|
vector.setY( rect.y() );
|
|
}
|
|
|
|
gradient.setOrigin( origin );
|
|
gradient.setVector( vector );
|
|
}
|
|
else if( type == "radial" || type == "ellipsoid" )
|
|
{
|
|
gradient.setType( VGradient::radial );
|
|
//else if( type == "square" || type == "rectangular" )
|
|
//gradient.setAttribute( "type", 6 ); // rectangle
|
|
//else if( type == "axial" )
|
|
//gradient.setAttribute( "type", 7 ); // pipecross
|
|
|
|
// Hard to map between x- and y-center settings of oodraw
|
|
// and (un-)balanced settings of kpresenter. Let's try it.
|
|
double x, y;
|
|
if( draw->hasAttributeNS( ooNS::draw, "cx" ) )
|
|
x = draw->attributeNS( ooNS::draw, "cx", TQString() ).remove( '%' ).toDouble() / 100.0;
|
|
else
|
|
x = 0.5;
|
|
|
|
if( draw->hasAttributeNS( ooNS::draw, "cy" ) )
|
|
y = draw->attributeNS( ooNS::draw, "cy", TQString() ).remove( '%' ).toDouble() / 100.0;
|
|
else
|
|
y = 0.5;
|
|
|
|
KoRect rect = obj.boundingBox();
|
|
gradient.setOrigin( KoPoint( rect.x() + x * rect.width(),
|
|
rect.y() + y * rect.height() ) );
|
|
gradient.setFocalPoint( KoPoint( rect.x() + x * rect.width(),
|
|
rect.y() + y * rect.height() ) );
|
|
gradient.setVector( KoPoint( rect.x() + rect.width(),
|
|
rect.y() + y * rect.height() ) );
|
|
}
|
|
f.gradient() = gradient;
|
|
f.setType( VFill::grad );
|
|
}
|
|
}
|
|
obj.setFill( f );
|
|
}
|
|
/*else if( fill == "hatch" )
|
|
{
|
|
TQDomElement brush = doc.createElement( "BRUSH" );
|
|
TQString style = m_styleStack.attributeNS( "fill-hatch-name" );
|
|
if( style == "Black 0 Degrees" )
|
|
brush.setAttribute( "style", 9 );
|
|
else if( style == "Black 90 Degrees" )
|
|
brush.setAttribute( "style", 10 );
|
|
else if( style == "Red Crossed 0 Degrees" || style == "Blue Crossed 0 Degrees" )
|
|
brush.setAttribute( "style", 11 );
|
|
else if( style == "Black 45 Degrees" || style == "Black 45 Degrees Wide" )
|
|
brush.setAttribute( "style", 12 );
|
|
else if( style == "Black -45 Degrees" )
|
|
brush.setAttribute( "style", 13 );
|
|
else if( style == "Red Crossed 45 Degrees" || style == "Blue Crossed 45 Degrees" )
|
|
brush.setAttribute( "style", 14 );
|
|
|
|
TQDomElement* draw = m_draws[style];
|
|
if( draw && draw->hasAttributeNS( "color" ) )
|
|
brush.setAttribute( "color", draw->attributeNS( "color" ) );
|
|
e.appendChild( brush );
|
|
}*/
|
|
}
|
|
|
|
void
|
|
OoDrawImport::createStyleMap( TQDomDocument &docstyles )
|
|
{
|
|
TQDomElement styles = docstyles.documentElement();
|
|
if( styles.isNull() )
|
|
return;
|
|
|
|
TQDomNode fixedStyles = KoDom::namedItemNS( styles, ooNS::office, "styles" );
|
|
if( !fixedStyles.isNull() )
|
|
{
|
|
insertDraws( fixedStyles.toElement() );
|
|
insertStyles( fixedStyles.toElement() );
|
|
}
|
|
TQDomNode automaticStyles = KoDom::namedItemNS( styles, ooNS::office, "automatic-styles" );
|
|
if( !automaticStyles.isNull() )
|
|
insertStyles( automaticStyles.toElement() );
|
|
|
|
TQDomNode masterStyles = KoDom::namedItemNS( styles, ooNS::office, "master-styles" );
|
|
if( !masterStyles.isNull() )
|
|
insertStyles( masterStyles.toElement() );
|
|
}
|
|
|
|
void
|
|
OoDrawImport::insertDraws( const TQDomElement& styles )
|
|
{
|
|
for( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
|
|
{
|
|
TQDomElement e = n.toElement();
|
|
|
|
if( !e.hasAttributeNS( ooNS::draw, "name" ) )
|
|
continue;
|
|
|
|
TQString name = e.attributeNS( ooNS::draw, "name", TQString() );
|
|
m_draws.insert( name, new TQDomElement( e ) );
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
OoDrawImport::insertStyles( const TQDomElement& styles )
|
|
{
|
|
for ( TQDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
|
|
{
|
|
TQDomElement e = n.toElement();
|
|
|
|
if( !e.hasAttributeNS( ooNS::style, "name" ) )
|
|
continue;
|
|
|
|
TQString name = e.attributeNS( ooNS::style, "name", TQString() );
|
|
m_styles.insert( name, new TQDomElement( e ) );
|
|
//kdDebug() << "Style: '" << name << "' loaded " << endl;
|
|
}
|
|
}
|
|
|
|
void
|
|
OoDrawImport::fillStyleStack( const TQDomElement& object )
|
|
{
|
|
// find all styles associated with an object and push them on the stack
|
|
if( object.hasAttributeNS( ooNS::presentation, "style-name" ) )
|
|
addStyles( m_styles[object.attributeNS( ooNS::presentation, "style-name", TQString() )] );
|
|
|
|
if( object.hasAttributeNS( ooNS::draw, "style-name" ) )
|
|
addStyles( m_styles[object.attributeNS( ooNS::draw, "style-name", TQString() )] );
|
|
|
|
if( object.hasAttributeNS( ooNS::draw, "text-style-name" ) )
|
|
addStyles( m_styles[object.attributeNS( ooNS::draw, "text-style-name", TQString() )] );
|
|
|
|
if( object.hasAttributeNS( ooNS::text, "style-name" ) )
|
|
addStyles( m_styles[object.attributeNS( ooNS::text, "style-name", TQString() )] );
|
|
}
|
|
|
|
void
|
|
OoDrawImport::addStyles( const TQDomElement* style )
|
|
{
|
|
// this function is necessary as parent styles can have parents themself
|
|
if( style->hasAttributeNS( ooNS::style, "parent-style-name" ) )
|
|
addStyles( m_styles[style->attributeNS( ooNS::style, "parent-style-name", TQString() )] );
|
|
|
|
m_styleStack.push( *style );
|
|
}
|
|
|
|
void
|
|
OoDrawImport::storeObjectStyles( const TQDomElement& object )
|
|
{
|
|
//m_styleStack.clearPageMark(); // remove styles of previous object
|
|
fillStyleStack( object );
|
|
//m_styleStack.setObjectMark();
|
|
}
|
|
|
|
KoRect
|
|
OoDrawImport::parseViewBox( const TQDomElement& object )
|
|
{
|
|
KoRect rect;
|
|
if( !object.attributeNS( ooNS::svg, "viewBox", TQString() ).isEmpty() )
|
|
{
|
|
// allow for viewbox def with ',' or whitespace
|
|
TQString viewbox( object.attributeNS( ooNS::svg, "viewBox", TQString() ) );
|
|
TQStringList points = TQStringList::split( ' ', viewbox.replace( ',', ' ').simplifyWhiteSpace() );
|
|
|
|
rect.setX( points[0].toFloat() );
|
|
rect.setY( points[1].toFloat() );
|
|
rect.setWidth( points[2].toFloat() );
|
|
rect.setHeight( points[3].toFloat() );
|
|
}
|
|
return rect;
|
|
}
|
|
|
|
void
|
|
OoDrawImport::appendPoints(VPath &path, const TQDomElement& object)
|
|
{
|
|
double x = KoUnit::parseValue( object.attributeNS( ooNS::svg, "x", TQString() ) );
|
|
double y = KoUnit::parseValue( object.attributeNS( ooNS::svg, "y", TQString() ) );
|
|
double w = KoUnit::parseValue( object.attributeNS( ooNS::svg, "width", TQString() ) );
|
|
double h = KoUnit::parseValue( object.attributeNS( ooNS::svg, "height", TQString() ) );
|
|
|
|
KoRect rect = parseViewBox( object );
|
|
rect.setX( rect.x() + x );
|
|
rect.setY( rect.y() + y );
|
|
|
|
TQStringList ptList = TQStringList::split( ' ', object.attributeNS( ooNS::draw, "points", TQString() ) );
|
|
|
|
TQString pt_x, pt_y;
|
|
double tmp_x, tmp_y;
|
|
KoPoint point;
|
|
bool bFirst = true;
|
|
for( TQStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it )
|
|
{
|
|
tmp_x = rect.x() + ( (*it).section( ',', 0, 0 ).toInt() * w ) / rect.width();
|
|
tmp_y = rect.y() + ( (*it).section( ',', 1, 1 ).toInt() * h ) / rect.height();
|
|
|
|
point.setX( tmp_x );
|
|
point.setY( ymirror( tmp_y ) );
|
|
if( bFirst )
|
|
{
|
|
path.moveTo( point );
|
|
bFirst = false;
|
|
}
|
|
else
|
|
path.lineTo( point );
|
|
}
|
|
}
|
|
|
|
void
|
|
OoDrawImport::parseColor( VColor &color, const TQString &s )
|
|
{
|
|
if( s.startsWith( "rgb(" ) )
|
|
{
|
|
TQString parse = s.stripWhiteSpace();
|
|
TQStringList colors = TQStringList::split( ',', parse );
|
|
TQString r = colors[0].right( ( colors[0].length() - 4 ) );
|
|
TQString g = colors[1];
|
|
TQString b = colors[2].left( ( colors[2].length() - 1 ) );
|
|
|
|
if( r.contains( "%" ) )
|
|
{
|
|
r = r.left( r.length() - 1 );
|
|
r = TQString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) );
|
|
}
|
|
|
|
if( g.contains( "%" ) )
|
|
{
|
|
g = g.left( g.length() - 1 );
|
|
g = TQString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) );
|
|
}
|
|
|
|
if( b.contains( "%" ) )
|
|
{
|
|
b = b.left( b.length() - 1 );
|
|
b = TQString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) );
|
|
}
|
|
|
|
TQColor c( r.toInt(), g.toInt(), b.toInt() );
|
|
color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
|
|
}
|
|
else
|
|
{
|
|
TQString rgbColor = s.stripWhiteSpace();
|
|
TQColor c;
|
|
if( rgbColor.startsWith( "#" ) )
|
|
c.setNamedColor( rgbColor );
|
|
//else
|
|
// c = parseColor( rgbColor );
|
|
color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
|
|
}
|
|
}
|
|
|
|
double
|
|
OoDrawImport::ymirror( double y )
|
|
{
|
|
return m_document.height() - y;
|
|
}
|
|
|
|
#include "oodrawimport.moc"
|