~ubuntu-branches/ubuntu/warty/koffice/warty

« back to all changes in this revision

Viewing changes to filters/karbon/oodraw/oodrawimport.cc

  • Committer: Bazaar Package Importer
  • Author(s): Ben Burton
  • Date: 2004-05-09 11:33:00 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20040509113300-vfrdadqsvjfuhn3b
Tags: 1:1.3.1-1
* New upstream bugfix release.
* Built against newer imagemagick (closes: #246623).
* Made koffice-libs/kformula recommend/depend on latex-xft-fonts, which
  provides mathematical fonts that the formula editor can use.  Also
  patched the kformula part to make these fonts the default.
* Changed kword menu hint from "WordProcessors" to "Word processors"
  (closes: #246209).
* Spellchecker configuration is now fixed (closes: #221256, #227568).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// -*- Mode: c++-mode; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4; -*-
 
2
/* This file is part of the KDE project
 
3
   Copyright (c) 2003 Rob Buis <buis@kde.org>
 
4
 
 
5
   This library is free software; you can redistribute it and/or
 
6
   modify it under the terms of the GNU Library General Public
 
7
   License as published by the Free Software Foundation; either
 
8
   version 2 of the License, or (at your option) any later version.
 
9
 
 
10
   This library is distributed in the hope that it will be useful,
 
11
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
   Library General Public License for more details.
 
14
 
 
15
   You should have received a copy of the GNU Library General Public License
 
16
   along with this library; see the file COPYING.LIB.  If not, write to
 
17
   the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
   Boston, MA 02111-1307, USA.
 
19
*/
 
20
 
 
21
#include "oodrawimport.h"
 
22
 
 
23
#include <math.h>
 
24
 
 
25
#include <qregexp.h>
 
26
#include <qdatetime.h>
 
27
#include <qfileinfo.h>
 
28
#include <qdir.h>
 
29
 
 
30
#include <kzip.h>
 
31
#include <karchive.h>
 
32
#include <kdebug.h>
 
33
#include <koUnit.h>
 
34
#include <koDocumentInfo.h>
 
35
#include <koDocument.h>
 
36
 
 
37
#include <kgenericfactory.h>
 
38
#include <koFilterChain.h>
 
39
#include <koGlobal.h>
 
40
#include <stylestack.h>
 
41
 
 
42
#include <shapes/vellipse.h>
 
43
#include <shapes/vrectangle.h>
 
44
#include <shapes/vpolygon.h>
 
45
 
 
46
#include <core/vfill.h>
 
47
#include <core/vgroup.h>
 
48
 
 
49
typedef KGenericFactory<OoDrawImport, KoFilter> OoDrawImportFactory;
 
50
K_EXPORT_COMPONENT_FACTORY( liboodrawimport, OoDrawImportFactory( "oodrawimport" ) )
 
51
 
 
52
 
 
53
OoDrawImport::OoDrawImport( KoFilter *, const char *, const QStringList & )
 
54
    : KoFilter(),
 
55
      m_styles( 23, true )
 
56
{
 
57
        m_styles.setAutoDelete( true );
 
58
}
 
59
 
 
60
OoDrawImport::~OoDrawImport()
 
61
{
 
62
}
 
63
 
 
64
KoFilter::ConversionStatus
 
65
OoDrawImport::convert( QCString const & from, QCString const & to )
 
66
{
 
67
        kdDebug() << "Entering Oodraw Import filter: " << from << " - " << to << endl;
 
68
 
 
69
        if( from != "application/vnd.sun.xml.draw" || to != "application/x-karbon" )
 
70
        {
 
71
                kdWarning() << "Invalid mimetypes " << from << " " << to << endl;
 
72
                return KoFilter::NotImplemented;
 
73
        }
 
74
 
 
75
        KoFilter::ConversionStatus preStatus = openFile();
 
76
 
 
77
        if( preStatus != KoFilter::OK )
 
78
                return preStatus;
 
79
 
 
80
/*QDomDocument docinfo;
 
81
createDocumentInfo( docinfo );
 
82
 
 
83
// store document info
 
84
KoStoreDevice* out = m_chain->storageFile( "documentinfo.xml", KoStore::Write );
 
85
if( out )
 
86
{
 
87
QCString info = docinfo.toCString();
 
88
//kdDebug() << " info :" << info << endl;
 
89
// WARNING: we cannot use KoStore::write(const QByteArray&) because it gives an extra NULL character at the end.
 
90
out->writeBlock( info , info.length() );
 
91
}*/
 
92
 
 
93
        convert();
 
94
        QDomDocument outdoc = m_document.saveXML();
 
95
 
 
96
        // store document content
 
97
        KoStoreDevice *out = m_chain->storageFile( "maindoc.xml", KoStore::Write );
 
98
        if( out )
 
99
        {
 
100
                QCString content = outdoc.toCString();
 
101
                kdDebug() << " content :" << content << endl;
 
102
                out->writeBlock( content , content.length() );
 
103
        }
 
104
 
 
105
        kdDebug() << "######################## OoDrawImport::convert done ####################" << endl;
 
106
        return KoFilter::OK;
 
107
}
 
108
 
 
109
// Very related to OoWriterImport::openFile()
 
110
KoFilter::ConversionStatus
 
111
OoDrawImport::openFile()
 
112
{
 
113
        KoStore *store = KoStore::createStore( m_chain->inputFile(), KoStore::Read);
 
114
 
 
115
        if( !store )
 
116
        {
 
117
                kdWarning() << "Couldn't open the requested file." << endl;
 
118
                return KoFilter::FileNotFound;
 
119
        }
 
120
 
 
121
        if( !store->open( "content.xml" ) )
 
122
        {
 
123
                kdWarning() << "This file doesn't seem to be a valid OoDraw file" << endl;
 
124
                delete store;
 
125
                return KoFilter::WrongFormat;
 
126
        }
 
127
 
 
128
        QDomDocument styles;
 
129
 
 
130
        m_content.setContent( store->device() );
 
131
        store->close();
 
132
 
 
133
        //kdDebug() << "m_content.toCString() :" << m_content.toCString() << endl;
 
134
        kdDebug() << "File containing content loaded " << endl;
 
135
 
 
136
        if( store->open( "styles.xml" ) )
 
137
        {
 
138
                styles.setContent( store->device() );
 
139
                store->close();
 
140
 
 
141
                //kdDebug() << "styles.toCString() :" << styles.toCString() << endl;
 
142
                kdDebug() << "File containing styles loaded" << endl;
 
143
        }
 
144
        else
 
145
                kdWarning() << "Style definitions do not exist!" << endl;
 
146
 
 
147
        if( store->open( "meta.xml" ) )
 
148
        {
 
149
                m_meta.setContent( store->device() );
 
150
                store->close();
 
151
 
 
152
                kdDebug() << "File containing meta definitions loaded" << endl;
 
153
        }
 
154
        else
 
155
                kdWarning() << "Meta definitions do not exist!" << endl;
 
156
 
 
157
        if( store->open( "settings.xml" ) )
 
158
        {
 
159
                m_settings.setContent( store->device() );
 
160
                store->close();
 
161
 
 
162
                kdDebug() << "File containing settings loaded" << endl;
 
163
        }
 
164
        else
 
165
                kdWarning() << "Settings do not exist!" << endl;
 
166
 
 
167
        delete store;
 
168
 
 
169
        emit sigProgress( 10 );
 
170
        createStyleMap( styles );
 
171
 
 
172
        return KoFilter::OK;
 
173
}
 
174
 
 
175
void
 
176
OoDrawImport::convert()
 
177
{
 
178
        m_document.saveAsPath( false );
 
179
 
 
180
        QDomElement content = m_content.documentElement();
 
181
 
 
182
        // content.xml contains some automatic-styles that we need to store
 
183
        QDomNode automaticStyles = content.namedItem( "office:automatic-styles" );
 
184
        if( !automaticStyles.isNull() )
 
185
                insertStyles( automaticStyles.toElement() );
 
186
 
 
187
        QDomNode body = content.namedItem( "office:body" );
 
188
        if( body.isNull() )
 
189
                return;
 
190
 
 
191
        // we take the settings of the first slide for the whole document.
 
192
        QDomNode drawPage = body.namedItem( "draw:page" );
 
193
        if( drawPage.isNull() ) // no pages? give up.
 
194
                return;
 
195
 
 
196
        QDomElement dp = drawPage.toElement();
 
197
        QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
 
198
        QDomElement *style = m_styles[master->attribute( "style:page-master-name" )];
 
199
        QDomElement properties = style->namedItem( "style:properties" ).toElement();
 
200
 
 
201
        if( properties.isNull() )
 
202
        {
 
203
                m_document.setWidth( 550.0 );
 
204
                m_document.setHeight( 841.0 );
 
205
        }
 
206
        else
 
207
        {
 
208
                m_document.setWidth( KoUnit::parseValue(properties.attribute( "fo:page-width" ) ) );
 
209
                m_document.setHeight( KoUnit::parseValue(properties.attribute( "fo:page-height" ) ) );
 
210
        }
 
211
 
 
212
    // parse all pages
 
213
    for( QDomNode drawPage = body.firstChild(); !drawPage.isNull(); drawPage = drawPage.nextSibling() )
 
214
    {
 
215
        QDomElement dp = drawPage.toElement();
 
216
        m_styleStack.clear(); // remove all styles
 
217
        fillStyleStack( dp );
 
218
        //m_styleStack.setPageMark();
 
219
 
 
220
        // set the pagetitle
 
221
        //QDomElement titleElement = doc.createElement( "Title" );
 
222
        //titleElement.setAttribute( "title", dp.attribute( "draw:name" ) );
 
223
        //pageTitleElement.appendChild( titleElement );
 
224
 
 
225
        parseGroup( 0L, dp );
 
226
    }
 
227
}
 
228
 
 
229
void
 
230
OoDrawImport::parseGroup( VGroup *parent, const QDomElement& parentobject )
 
231
{
 
232
        // parse all objects
 
233
        for( QDomNode object = parentobject.firstChild(); !object.isNull(); object = object.nextSibling() )
 
234
        {
 
235
                QDomElement o = object.toElement();
 
236
                QString name = o.tagName();
 
237
                QString drawID = o.attribute("draw:id");
 
238
                VObject *obj = 0L;
 
239
 
 
240
                if( name == "draw:g" ) // polyline
 
241
                {
 
242
                        storeObjectStyles( o );
 
243
                        VGroup *group = new VGroup( parent );
 
244
                        appendPen( *group );
 
245
                        appendBrush( *group );
 
246
                        obj = group;
 
247
                        parseGroup( group, o );
 
248
                }
 
249
                else if( name == "draw:rect" ) // rectangle
 
250
                {
 
251
                        storeObjectStyles( o );
 
252
                        double x = KoUnit::parseValue( o.attribute( "svg:x" ) );
 
253
                        double y = ymirror( KoUnit::parseValue( o.attribute( "svg:y" ) ) );
 
254
                        double w = KoUnit::parseValue( o.attribute( "svg:width" ) );
 
255
                        double h = KoUnit::parseValue( o.attribute( "svg:height" ) );
 
256
                        int corner = static_cast<int>( KoUnit::parseValue( o.attribute( "draw:corner-radius" ) ) );
 
257
                        VRectangle *rect = new VRectangle( parent, KoPoint( x, y ), w, h, corner );
 
258
                        appendPen( *rect );
 
259
                        appendBrush( *rect );
 
260
                        obj = rect;
 
261
                }
 
262
                else if( name == "draw:circle" || name == "draw:ellipse" )
 
263
                {
 
264
                        storeObjectStyles( o );
 
265
                        double w = KoUnit::parseValue( o.attribute( "svg:width" ) );
 
266
                        double h = KoUnit::parseValue( o.attribute( "svg:height" ) );
 
267
                        double x = KoUnit::parseValue( o.attribute( "svg:x" ) );
 
268
                        double y = ymirror( KoUnit::parseValue( o.attribute( "svg:y" ) ) ) - h;
 
269
                        double start = o.attribute( "draw:start-angle" ).toDouble();
 
270
                        double end = o.attribute( "draw:end-angle" ).toDouble();
 
271
                        QString kind = o.attribute( "draw:kind" );
 
272
                        VEllipse::VEllipseType type = VEllipse::full;
 
273
                        if( !kind.isEmpty() )
 
274
                        {
 
275
                                if( kind == "section" )
 
276
                                        type = VEllipse::cut;
 
277
                                else if( kind == "cut" )
 
278
                                        type = VEllipse::section;
 
279
                                else if( kind == "arc" )
 
280
                                        type = VEllipse::arc;
 
281
                        }
 
282
                        VEllipse *ellipse = new VEllipse( parent, KoPoint( x, y ), w, h, type, start, end );
 
283
                        appendPen( *ellipse );
 
284
                        // arc has no brush
 
285
                        if( kind != "arc" )
 
286
                                appendBrush( *ellipse );
 
287
                        obj = ellipse;
 
288
                }
 
289
                else if( name == "draw:line" ) // line
 
290
                {
 
291
                        storeObjectStyles( o );
 
292
                        VPath *line = new VPath( parent );
 
293
                        double x1 = KoUnit::parseValue( o.attribute( "svg:x1" ) );
 
294
                        double y1 = ymirror( KoUnit::parseValue( o.attribute( "svg:y1" ) ) );
 
295
                        double x2 = KoUnit::parseValue( o.attribute( "svg:x2" ) );
 
296
                        double y2 = ymirror( KoUnit::parseValue( o.attribute( "svg:y2" ) ) );
 
297
                        line->moveTo( KoPoint( x1, y1 ) );
 
298
                        line->lineTo( KoPoint( x2, y2 ) );
 
299
                        appendPen( *line );
 
300
                        appendBrush( *line );
 
301
                        obj = line;
 
302
                }
 
303
                else if( name == "draw:polyline" ) // polyline
 
304
                {
 
305
                        storeObjectStyles( o );
 
306
                        VPath *polyline = new VPath( parent );
 
307
                        appendPoints( *polyline, o);
 
308
                        appendPen( *polyline );
 
309
                        appendBrush( *polyline );
 
310
                        obj = polyline;
 
311
                }
 
312
                else if( name == "draw:polygon" ) // polygon
 
313
                {
 
314
                        storeObjectStyles( o );
 
315
                        //VPolygon *polygon = new VPolygon( parent );
 
316
                        //polygon->load( o );
 
317
                        VPath *polygon = new VPath( parent );
 
318
                        appendPoints( *polygon, o );
 
319
                        appendPen( *polygon );
 
320
                        appendBrush( *polygon );
 
321
                        obj = polygon;
 
322
                }
 
323
                else if( name == "draw:path" ) // path
 
324
                {
 
325
                        storeObjectStyles( o );
 
326
                        VPath *path = new VPath( parent );
 
327
                        path->loadSvgPath( o.attribute( "svg:d" ) );
 
328
                        KoRect rect = parseViewBox( o );
 
329
                        double x = KoUnit::parseValue( o.attribute( "svg:x" ) );
 
330
                        double y = ymirror( KoUnit::parseValue( o.attribute( "svg:y" ) ) );
 
331
                        double w = KoUnit::parseValue( o.attribute( "svg:width" ) );
 
332
                        double h = KoUnit::parseValue( o.attribute( "svg:height" ) );
 
333
                        QWMatrix mat;
 
334
                        mat.translate( x, y );
 
335
                        mat.scale( w / rect.width(), -h / rect.height() );
 
336
                        path->transform( mat );
 
337
                        appendPen( *path );
 
338
                        appendBrush( *path );
 
339
                        obj = path;
 
340
                }
 
341
/*else if( name == "draw:image" ) // image
 
342
{
 
343
storeObjectStyles( o );
 
344
e = doc.createElement( "OBJECT" );
 
345
e.setAttribute( "type", 0 );
 
346
appendImage( doc, e, pictureElement, o );
 
347
}*/
 
348
                else
 
349
                {
 
350
                        kdDebug() << "Unsupported object '" << name << "'" << endl;
 
351
                        continue;
 
352
                }
 
353
                if( parent && obj )
 
354
                        parent->append( obj );
 
355
                else if( obj )
 
356
                        m_document.append( obj );
 
357
        }
 
358
}
 
359
 
 
360
void
 
361
OoDrawImport::appendPen( VObject &obj )
 
362
{
 
363
        if( m_styleStack.hasAttribute( "draw:stroke" ) )
 
364
        {
 
365
                VStroke stroke;
 
366
 
 
367
                if( m_styleStack.attribute( "draw:stroke" ) == "none" )
 
368
                        stroke.setType( VStroke::none );
 
369
                else if( m_styleStack.attribute( "draw:stroke" ) == "solid" )
 
370
                        stroke.setType( VStroke::solid );
 
371
                else if( m_styleStack.attribute( "draw:stroke" ) == "dash" )
 
372
                {
 
373
                        QValueList<float> dashes;
 
374
                        stroke.setType( VStroke::solid );
 
375
                        QString style = m_styleStack.attribute( "draw:stroke-dash" );
 
376
                        if( style == "Ultrafine Dashed" || 
 
377
                                style == "Fine Dashed (var)" || style == "Dashed (var)" )
 
378
                                stroke.dashPattern().setArray( dashes << 2 << 2 );
 
379
                        else if( style == "Fine Dashed" )
 
380
                                stroke.dashPattern().setArray( dashes << 10 << 10 );
 
381
                        else if( style == "Fine Dotted" || style == "Ultrafine Dotted (var)" ||
 
382
                                style == "Line with Fine Dots" )
 
383
                                stroke.dashPattern().setArray( dashes << 2 << 10 );
 
384
                        else if( style == "3 Dashes 3 Dots (var)" || style == "Ultrafine 2 Dots 3 Dashes" )
 
385
                                stroke.dashPattern().setArray( dashes << 3 << 3 );
 
386
                        else if( style == "2 Dots 1 Dash" )
 
387
                                stroke.dashPattern().setArray( dashes << 2 << 1 );
 
388
                }
 
389
                if( m_styleStack.hasAttribute( "svg:stroke-width" ) )
 
390
                {
 
391
                        double lwidth = KoUnit::parseValue( m_styleStack.attribute( "svg:stroke-width" ) );
 
392
                        if( lwidth == 0 )
 
393
                                lwidth = 1.0;
 
394
                        stroke.setLineWidth( lwidth );
 
395
                }
 
396
                if( m_styleStack.hasAttribute( "svg:stroke-color" ) )
 
397
                {
 
398
                        VColor c;
 
399
                        parseColor( c, m_styleStack.attribute( "svg:stroke-color" ) );
 
400
                        stroke.setColor( c );
 
401
                }
 
402
 
 
403
                obj.setStroke( stroke );
 
404
        }
 
405
}
 
406
 
 
407
void
 
408
OoDrawImport::appendBrush( VObject &obj )
 
409
{
 
410
        if( m_styleStack.hasAttribute( "draw:fill" ) )
 
411
        {
 
412
                const QString fill = m_styleStack.attribute( "draw:fill" );
 
413
                VFill f;
 
414
 
 
415
                if( fill == "solid" )
 
416
                {
 
417
                        f.setType( VFill::solid );
 
418
                        if( m_styleStack.hasAttribute( "draw:fill-color" ) )
 
419
                        {
 
420
                                VColor c;
 
421
                                parseColor( c, m_styleStack.attribute( "draw:fill-color" ) );
 
422
                                f.setColor( c );
 
423
                        }
 
424
                }
 
425
                else if( fill == "gradient" )
 
426
                {
 
427
                        VGradient gradient;
 
428
                        gradient.clearStops();
 
429
                        gradient.setRepeatMethod( VGradient::none );
 
430
                        QString style = m_styleStack.attribute( "draw:fill-gradient-name" );
 
431
 
 
432
                        QDomElement* draw = m_draws[style];
 
433
                        if( draw )
 
434
                        {
 
435
                                double border = 0.0;
 
436
                                if( draw->hasAttribute( "draw:border" ) )
 
437
                                        border += draw->attribute( "draw:border" ).remove( '%' ).toDouble() / 100.0;
 
438
                                VColor c;
 
439
                                parseColor( c, draw->attribute( "draw:start-color" ) );
 
440
                                gradient.addStop( c, border, 0.5 );
 
441
                                parseColor( c, draw->attribute( "draw:end-color" ) );
 
442
                                gradient.addStop( c, 1.0, 0.5 );
 
443
 
 
444
                                QString type = draw->attribute( "draw:style" );
 
445
                                if( type == "linear" || type == "axial" )
 
446
                                {
 
447
                                        gradient.setType( VGradient::linear );
 
448
                                        int angle = draw->attribute( "draw:angle" ).toInt() / 10;
 
449
 
 
450
                                        // make sure the angle is between 0 and 359
 
451
                                        angle = abs( angle );
 
452
                                        angle -= ( (int) ( angle / 360 ) ) * 360;
 
453
 
 
454
                                        // What we are trying to do here is to find out if the given
 
455
                                        // angle belongs to a horizontal, vertical or diagonal gradient.
 
456
                                        int lower, upper, nearAngle = 0;
 
457
                                        for ( lower = 0, upper = 45; upper < 360; lower += 45, upper += 45 )
 
458
                                        {
 
459
                                                if( upper >= angle )
 
460
                                                {
 
461
                                                        int distanceToUpper = abs( angle - upper );
 
462
                                                        int distanceToLower = abs( angle - lower );
 
463
                                                        nearAngle = distanceToUpper > distanceToLower ? lower : upper;
 
464
                                                        break;
 
465
                                                }
 
466
                                        }
 
467
                                        KoRect rect = obj.boundingBox();
 
468
                                        KoPoint origin, vector;
 
469
                                        // nearAngle should now be one of: 0, 45, 90, 135, 180...
 
470
                                        kdDebug() << "nearAngle: " << nearAngle << endl;
 
471
                                        if( nearAngle == 0 || nearAngle == 180 )
 
472
                                        {
 
473
                                                origin.setX( rect.x() + rect.width() );
 
474
                                                origin.setY( rect.y() + rect.height());
 
475
                                                vector.setX( rect.x() + rect.width() );
 
476
                                                vector.setY( rect.y() );
 
477
                                        }
 
478
                                        else if( nearAngle == 90 || nearAngle == 270 )
 
479
                                        {
 
480
                                                origin.setX( rect.x() );
 
481
                                                origin.setY( rect.y() + rect.height() );
 
482
                                                vector.setX( rect.x() + rect.width() );
 
483
                                                vector.setY( rect.y() + rect.height() );
 
484
                                        }
 
485
                                        else if( nearAngle == 45 || nearAngle == 225 )
 
486
                                        {
 
487
                                                origin.setX( rect.x() );
 
488
                                                origin.setY( rect.y() );
 
489
                                                vector.setX( rect.x() + rect.width() );
 
490
                                                vector.setY( rect.y() + rect.height() );
 
491
                                        }
 
492
                                        else if( nearAngle == 135 || nearAngle == 315 )
 
493
                                        {
 
494
                                                origin.setX( rect.x() + rect.width() );
 
495
                                                origin.setY( rect.y() + rect.height() );
 
496
                                                vector.setX( rect.x() );
 
497
                                                vector.setY( rect.y() );
 
498
                                        }
 
499
 
 
500
                                        gradient.setOrigin( origin );
 
501
                                        gradient.setVector( vector );
 
502
                                }
 
503
                                else if( type == "radial" || type == "ellipsoid" )
 
504
                                {
 
505
                                        gradient.setType( VGradient::radial );
 
506
//else if( type == "square" || type == "rectangular" )
 
507
//gradient.setAttribute( "type", 6 ); // rectangle
 
508
//else if( type == "axial" )
 
509
//gradient.setAttribute( "type", 7 ); // pipecross
 
510
 
 
511
                                        // Hard to map between x- and y-center settings of oodraw
 
512
                                        // and (un-)balanced settings of kpresenter. Let's try it.
 
513
                                        double x, y;
 
514
                                        if( draw->hasAttribute( "draw:cx" ) )
 
515
                                                x = draw->attribute( "draw:cx" ).remove( '%' ).toDouble() / 100.0;
 
516
                                        else
 
517
                                                x = 0.5;
 
518
 
 
519
                                        if( draw->hasAttribute( "draw:cy" ) )
 
520
                                                y = draw->attribute( "draw:cy" ).remove( '%' ).toDouble() / 100.0;
 
521
                                        else
 
522
                                                y = 0.5;
 
523
 
 
524
                                        KoRect rect = obj.boundingBox();
 
525
                                        gradient.setOrigin( KoPoint( rect.x() + x * rect.width(),
 
526
                                                                                                 rect.y() + y * rect.height() ) );
 
527
                                        gradient.setFocalPoint( KoPoint( rect.x() + x * rect.width(),
 
528
                                                                                                         rect.y() + y * rect.height() ) );
 
529
                                        gradient.setVector( KoPoint( rect.x() + rect.width(),
 
530
                                                                                                 rect.y() + y * rect.height() ) );
 
531
                                }
 
532
                                f.gradient() = gradient;
 
533
                                f.setType( VFill::grad );
 
534
                        }
 
535
                }
 
536
                obj.setFill( f );
 
537
        }
 
538
/*else if( fill == "hatch" )
 
539
{
 
540
QDomElement brush = doc.createElement( "BRUSH" );
 
541
QString style = m_styleStack.attribute( "draw:fill-hatch-name" );
 
542
if( style == "Black 0 Degrees" )
 
543
brush.setAttribute( "style", 9 );
 
544
else if( style == "Black 90 Degrees" )
 
545
brush.setAttribute( "style", 10 );
 
546
else if( style == "Red Crossed 0 Degrees" || style == "Blue Crossed 0 Degrees" )
 
547
brush.setAttribute( "style", 11 );
 
548
else if( style == "Black 45 Degrees" || style == "Black 45 Degrees Wide" )
 
549
brush.setAttribute( "style", 12 );
 
550
else if( style == "Black -45 Degrees" )
 
551
brush.setAttribute( "style", 13 );
 
552
else if( style == "Red Crossed 45 Degrees" || style == "Blue Crossed 45 Degrees" )
 
553
brush.setAttribute( "style", 14 );
 
554
 
 
555
QDomElement* draw = m_draws[style];
 
556
if( draw && draw->hasAttribute( "draw:color" ) )
 
557
brush.setAttribute( "color", draw->attribute( "draw:color" ) );
 
558
e.appendChild( brush );
 
559
}*/
 
560
}
 
561
 
 
562
void
 
563
OoDrawImport::createStyleMap( QDomDocument &docstyles )
 
564
{
 
565
        QDomElement styles = docstyles.documentElement();
 
566
        if( styles.isNull() )
 
567
                return;
 
568
 
 
569
        QDomNode fixedStyles = styles.namedItem( "office:styles" );
 
570
        if( !fixedStyles.isNull() )
 
571
        {
 
572
                insertDraws( fixedStyles.toElement() );
 
573
                insertStyles( fixedStyles.toElement() );
 
574
        }
 
575
        QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" );
 
576
        if( !automaticStyles.isNull() )
 
577
                insertStyles( automaticStyles.toElement() );
 
578
 
 
579
        QDomNode masterStyles = styles.namedItem( "office:master-styles" );
 
580
        if( !masterStyles.isNull() )
 
581
                insertStyles( masterStyles.toElement() );
 
582
}
 
583
 
 
584
void
 
585
OoDrawImport::insertDraws( const QDomElement& styles )
 
586
{
 
587
        for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
 
588
        {
 
589
                QDomElement e = n.toElement();
 
590
 
 
591
                if( !e.hasAttribute( "draw:name" ) )
 
592
                        continue;
 
593
 
 
594
                QString name = e.attribute( "draw:name" );
 
595
                m_draws.insert( name, new QDomElement( e ) );
 
596
        }
 
597
}
 
598
 
 
599
 
 
600
void
 
601
OoDrawImport::insertStyles( const QDomElement& styles )
 
602
{
 
603
        for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
 
604
        {
 
605
                QDomElement e = n.toElement();
 
606
 
 
607
                if( !e.hasAttribute( "style:name" ) )
 
608
                        continue;
 
609
 
 
610
                QString name = e.attribute( "style:name" );
 
611
                m_styles.insert( name, new QDomElement( e ) );
 
612
                //kdDebug() << "Style: '" << name << "' loaded " << endl;
 
613
        }
 
614
}
 
615
 
 
616
void
 
617
OoDrawImport::fillStyleStack( const QDomElement& object )
 
618
{
 
619
    // find all styles associated with an object and push them on the stack
 
620
    if( object.hasAttribute( "presentation:style-name" ) )
 
621
        addStyles( m_styles[object.attribute( "presentation:style-name" )] );
 
622
 
 
623
    if( object.hasAttribute( "draw:style-name" ) )
 
624
        addStyles( m_styles[object.attribute( "draw:style-name" )] );
 
625
 
 
626
    if( object.hasAttribute( "draw:text-style-name" ) )
 
627
        addStyles( m_styles[object.attribute( "draw:text-style-name" )] );
 
628
 
 
629
    if( object.hasAttribute( "text:style-name" ) )
 
630
        addStyles( m_styles[object.attribute( "text:style-name" )] );
 
631
}
 
632
 
 
633
void
 
634
OoDrawImport::addStyles( const QDomElement* style )
 
635
{
 
636
    // this function is necessary as parent styles can have parents themself
 
637
    if( style->hasAttribute( "style:parent-style-name" ) )
 
638
        addStyles( m_styles[style->attribute( "style:parent-style-name" )] );
 
639
 
 
640
    m_styleStack.push( *style );
 
641
}
 
642
 
 
643
void
 
644
OoDrawImport::storeObjectStyles( const QDomElement& object )
 
645
{
 
646
    //m_styleStack.clearPageMark(); // remove styles of previous object
 
647
    fillStyleStack( object );
 
648
    //m_styleStack.setObjectMark();
 
649
}
 
650
 
 
651
KoRect
 
652
OoDrawImport::parseViewBox( const QDomElement& object )
 
653
{
 
654
        KoRect rect;
 
655
        if( !object.attribute( "svg:viewBox" ).isEmpty() )
 
656
        {
 
657
                // allow for viewbox def with ',' or whitespace
 
658
                QString viewbox( object.attribute( "svg:viewBox" ) );
 
659
                QStringList points = QStringList::split( ' ', viewbox.replace( QRegExp(","), " ").simplifyWhiteSpace() );
 
660
 
 
661
                rect.setX( points[0].toFloat() );
 
662
                rect.setY( points[1].toFloat() );
 
663
                rect.setWidth( points[2].toFloat() );
 
664
                rect.setHeight( points[3].toFloat() );
 
665
        }
 
666
        return rect;
 
667
}
 
668
 
 
669
void
 
670
OoDrawImport::appendPoints(VPath &path, const QDomElement& object)
 
671
{
 
672
        double x = KoUnit::parseValue( object.attribute( "svg:x" ) );
 
673
        double y = KoUnit::parseValue( object.attribute( "svg:y" ) );
 
674
        double w = KoUnit::parseValue( object.attribute( "svg:width" ) );
 
675
        double h = KoUnit::parseValue( object.attribute( "svg:height" ) );
 
676
 
 
677
        KoRect rect = parseViewBox( object );
 
678
        rect.setX( rect.x() + x );
 
679
        rect.setY( rect.y() + y );
 
680
 
 
681
        QStringList ptList = QStringList::split( ' ', object.attribute( "draw:points" ) );
 
682
 
 
683
        QString pt_x, pt_y;
 
684
        double tmp_x, tmp_y;
 
685
        KoPoint point;
 
686
        bool bFirst = true;
 
687
        for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it )
 
688
        {
 
689
                tmp_x = rect.x() + ( (*it).section( ',', 0, 0 ).toInt() * w ) / rect.width();
 
690
                tmp_y = rect.y() + ( (*it).section( ',', 1, 1 ).toInt() * h ) / rect.height();
 
691
 
 
692
                point.setX( tmp_x );
 
693
                point.setY( ymirror( tmp_y ) );
 
694
                if( bFirst )
 
695
                {
 
696
                        path.moveTo( point );
 
697
                        bFirst = false;
 
698
                }
 
699
                else
 
700
                        path.lineTo( point );
 
701
    }
 
702
}
 
703
 
 
704
void
 
705
OoDrawImport::parseColor( VColor &color, const QString &s )
 
706
{
 
707
        if( s.startsWith( "rgb(" ) )
 
708
        {
 
709
                QString parse = s.stripWhiteSpace();
 
710
                QStringList colors = QStringList::split( ',', parse );
 
711
                QString r = colors[0].right( ( colors[0].length() - 4 ) );
 
712
                QString g = colors[1];
 
713
                QString b = colors[2].left( ( colors[2].length() - 1 ) );
 
714
 
 
715
                if( r.contains( "%" ) )
 
716
                {
 
717
                        r = r.left( r.length() - 1 );
 
718
                        r = QString::number( int( ( double( 255 * r.toDouble() ) / 100.0 ) ) );
 
719
                }
 
720
 
 
721
                if( g.contains( "%" ) )
 
722
                {
 
723
                        g = g.left( g.length() - 1 );
 
724
                        g = QString::number( int( ( double( 255 * g.toDouble() ) / 100.0 ) ) );
 
725
                }
 
726
 
 
727
                if( b.contains( "%" ) )
 
728
                {
 
729
                        b = b.left( b.length() - 1 );
 
730
                        b = QString::number( int( ( double( 255 * b.toDouble() ) / 100.0 ) ) );
 
731
                }
 
732
 
 
733
                QColor c( r.toInt(), g.toInt(), b.toInt() );
 
734
                color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
 
735
        }
 
736
        else
 
737
        {
 
738
                QString rgbColor = s.stripWhiteSpace();
 
739
                QColor c;
 
740
                if( rgbColor.startsWith( "#" ) )
 
741
                        c.setNamedColor( rgbColor );
 
742
                //else
 
743
                //      c = parseColor( rgbColor );
 
744
                color.set( c.red() / 255.0, c.green() / 255.0, c.blue() / 255.0 );
 
745
        }
 
746
}
 
747
 
 
748
double
 
749
OoDrawImport::ymirror( double y )
 
750
{
 
751
        return m_document.height() - y;
 
752
}
 
753
 
 
754
#include "oodrawimport.moc"