Subversion Repositories Scribus

Rev

Rev 3242 | Rev 3344 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
766 cbradney 1
#include <qwidget.h>
2
#include <qfile.h>
3
#include <qtextstream.h>
4
#include <qregexp.h>
5
#include <qcursor.h>
6
#include <qdragobject.h>
7
#include <qdir.h>
8
#include <qstring.h>
3207 craig 9
#include <qdom.h>
766 cbradney 10
#include <cmath>
11
 
541 fschmid 12
#include "oodrawimp.h"
13
#include "oodrawimp.moc"
766 cbradney 14
 
2688 craig 15
#include "scconfig.h"
16
 
766 cbradney 17
#include "scribus.h"
18
#include "scribusdoc.h"
19
#include "pageitem.h"
20
#include "fpointarray.h"
541 fschmid 21
#include "customfdialog.h"
22
#include "color.h"
23
#include "scribusXml.h"
24
#include "mpalette.h"
2856 cbradney 25
#include "prefsmanager.h"
541 fschmid 26
#include "prefsfile.h"
27
#include "prefscontext.h"
28
#include "prefstable.h"
1578 tsoots 29
#include "fileunzip.h"
544 fschmid 30
#include "serializer.h"
1436 tsoots 31
#include "undomanager.h"
1549 subik 32
#include "pluginmanager.h"
2529 craig 33
#include "util.h"
34
#include "scfontmetrics.h"
3207 craig 35
#include "stylestack.h"
541 fschmid 36
 
37
using namespace std;
38
 
3207 craig 39
int oodrawimp_getPluginAPIVersion()
541 fschmid 40
{
3207 craig 41
        return PLUGIN_API_VERSION;
541 fschmid 42
}
43
 
3207 craig 44
ScPlugin* oodrawimp_getPlugin()
541 fschmid 45
{
3207 craig 46
        OODrawImportPlugin* plug = new OODrawImportPlugin();
47
        Q_CHECK_PTR(plug);
48
        return plug;
541 fschmid 49
}
50
 
3207 craig 51
void oodrawimp_freePlugin(ScPlugin* plugin)
541 fschmid 52
{
3207 craig 53
        OODrawImportPlugin* plug = dynamic_cast<OODrawImportPlugin*>(plugin);
54
        Q_ASSERT(plug);
55
        delete plug;
541 fschmid 56
}
57
 
3207 craig 58
OODrawImportPlugin::OODrawImportPlugin() :
59
        ScActionPlugin(ScPlugin::PluginType_Import)
1208 cbradney 60
{
3207 craig 61
        // Set action info in languageChange, so we only have to do
62
        // it in one place.
63
        languageChange();
1208 cbradney 64
}
65
 
3207 craig 66
OODrawImportPlugin::~OODrawImportPlugin() {};
67
 
68
void OODrawImportPlugin::languageChange()
1208 cbradney 69
{
3207 craig 70
        // Note that we leave the unused members unset. They'll be initialised
71
        // with their default ctors during construction.
72
        // Action name
73
        m_actionInfo.name = "ImportOpenOfficeDraw";
74
        // Action text for menu, including accel
75
        m_actionInfo.text = tr("Import &OpenOffice.org Draw...");
76
        // Menu
77
        m_actionInfo.menu = "FileImport";
78
        m_actionInfo.enabledOnStartup = true;
1208 cbradney 79
}
80
 
3207 craig 81
const QString OODrawImportPlugin::fullTrName() const
1208 cbradney 82
{
3207 craig 83
        return QObject::tr("OpenOffice.org Draw Importer");
1208 cbradney 84
}
85
 
3207 craig 86
const ScActionPlugin::AboutData* OODrawImportPlugin::getAboutData() const
1208 cbradney 87
{
3241 craig 88
        AboutData* about = new AboutData;
89
        Q_CHECK_PTR(about);
90
        return about;
1208 cbradney 91
}
92
 
3241 craig 93
void OODrawImportPlugin::deleteAboutData(const AboutData* about) const
1208 cbradney 94
{
3241 craig 95
        Q_ASSERT(about);
96
        delete about;
1208 cbradney 97
}
98
 
3207 craig 99
bool OODrawImportPlugin::run(QString fileName)
541 fschmid 100
{
3207 craig 101
        bool interactive = false;
102
        if (fileName.isEmpty())
541 fschmid 103
        {
3207 craig 104
                interactive = true;
2856 cbradney 105
                PrefsContext* prefs = PrefsManager::instance()->prefsFile->getPluginContext("OODrawImport");
541 fschmid 106
                QString wdir = prefs->get("wdir", ".");
3207 craig 107
                CustomFDialog diaf(ScApp, wdir, QObject::tr("Open"), QObject::tr("OpenOffice.org Draw (*.sxd);;All Files (*)"));
541 fschmid 108
                if (diaf.exec())
109
                {
110
                        fileName = diaf.selectedFile();
111
                        prefs->set("wdir", fileName.left(fileName.findRev("/")));
112
                }
113
                else
3207 craig 114
                        return true;
541 fschmid 115
        }
3207 craig 116
        if (UndoManager::undoEnabled() && ScApp->HaveDoc)
1439 tsoots 117
        {
3207 craig 118
                UndoManager::instance()->beginTransaction(ScApp->doc->currentPage->getUName(),Um::IImageFrame,Um::ImportOOoDraw, fileName, Um::IImportOOoDraw);
1439 tsoots 119
        }
3207 craig 120
        else if (UndoManager::undoEnabled() && !ScApp->HaveDoc)
1439 tsoots 121
                UndoManager::instance()->setUndoEnabled(false);
3207 craig 122
        OODPlug *dia = new OODPlug(fileName, interactive);
1436 tsoots 123
        if (UndoManager::undoEnabled())
124
                UndoManager::instance()->commit();
1439 tsoots 125
        else
126
                UndoManager::instance()->setUndoEnabled(true);
541 fschmid 127
        delete dia;
3211 craig 128
        return true;
541 fschmid 129
}
130
 
3207 craig 131
OODPlug::OODPlug(QString fileName, bool isInteractive )
541 fschmid 132
{
3207 craig 133
        interactive = isInteractive;
550 fschmid 134
        QString f, f2, f3;
541 fschmid 135
        m_styles.setAutoDelete( true );
1578 tsoots 136
        FileUnzip* fun = new FileUnzip(fileName);
137
        stylePath   = fun->getFile("styles.xml");
138
        contentPath = fun->getFile("content.xml");
139
        metaPath = fun->getFile("meta.xml");
140
        delete fun;
541 fschmid 141
        if ((stylePath != NULL) && (contentPath != NULL))
142
        {
143
                QString docname = fileName.right(fileName.length() - fileName.findRev("/") - 1);
144
                docname = docname.left(docname.findRev("."));
145
                loadText(stylePath, &f);
146
                if(!inpStyles.setContent(f))
147
                        return;
148
                loadText(contentPath, &f2);
149
                if(!inpContents.setContent(f2))
150
                        return;
151
                QFile f1(stylePath);
152
                f1.remove();
153
                QFile f2(contentPath);
154
                f2.remove();
550 fschmid 155
                if (metaPath != NULL)
156
                {
157
                        HaveMeta = true;
158
                        loadText(metaPath, &f3);
159
                        if(!inpMeta.setContent(f3))
160
                                HaveMeta = false;
161
                        QFile f3(metaPath);
162
                        f3.remove();
163
                }
164
                else
165
                        HaveMeta = false;
541 fschmid 166
        }
167
        else if ((stylePath == NULL) && (contentPath != NULL))
168
        {
169
                QFile f2(contentPath);
170
                f2.remove();
171
        }
172
        else if ((stylePath != NULL) && (contentPath == NULL))
173
        {
174
                QFile f1(stylePath);
175
                f1.remove();
176
        }
177
        QString CurDirP = QDir::currentDirPath();
178
        QFileInfo efp(fileName);
179
        QDir::setCurrent(efp.dirPath());
180
        convert();
181
        QDir::setCurrent(CurDirP);
182
}
183
 
184
void OODPlug::convert()
185
{
186
        bool ret = false;
544 fschmid 187
        int PageCounter = 0;
541 fschmid 188
        createStyleMap( inpStyles );
189
        QDomElement docElem = inpContents.documentElement();
190
        QDomNode automaticStyles = docElem.namedItem( "office:automatic-styles" );
191
        if( !automaticStyles.isNull() )
192
                insertStyles( automaticStyles.toElement() );
193
        QDomNode body = docElem.namedItem( "office:body" );
194
        QDomNode drawPage = body.namedItem( "draw:page" );
195
        QDomElement dp = drawPage.toElement();
196
        QDomElement *master = m_styles[dp.attribute( "draw:master-page-name" )];
197
        QDomElement *style = m_styles[master->attribute( "style:page-master-name" )];
198
        QDomElement properties = style->namedItem( "style:properties" ).toElement();
199
        double width = !properties.attribute( "fo:page-width" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-width" ) ) : 550.0;
200
        double height = !properties.attribute( "fo:page-height" ).isEmpty() ? parseUnit(properties.attribute( "fo:page-height" ) ) : 841.0;
3207 craig 201
        if (!interactive)
202
                ScApp->doc->setPage(width, height, 0, 0, 0, 0, 0, 0, false, false);
541 fschmid 203
        else
204
        {
3207 craig 205
                if (!ScApp->HaveDoc)
541 fschmid 206
                {
3207 craig 207
                        ScApp->doFileNew(width, height, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom");
541 fschmid 208
                        ret = true;
209
                }
210
        }
3207 craig 211
        if ((ret) || (!interactive))
550 fschmid 212
        {
213
                if (width > height)
3207 craig 214
                        ScApp->doc->PageOri = 1;
550 fschmid 215
                else
3207 craig 216
                        ScApp->doc->PageOri = 0;
217
                ScApp->doc->PageSize = "Custom";
550 fschmid 218
                QDomNode mpg;
219
                QDomElement metaElem = inpMeta.documentElement();
220
                QDomElement mp = metaElem.namedItem( "office:meta" ).toElement();
221
                mpg = mp.namedItem( "dc:title" );
222
                if (!mpg.isNull())
3207 craig 223
                        ScApp->doc->documentInfo.setTitle(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 224
                mpg = mp.namedItem( "meta:initial-creator" );
225
                if (!mpg.isNull())
3207 craig 226
                        ScApp->doc->documentInfo.setAuthor(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 227
                mpg = mp.namedItem( "dc:description" );
228
                if (!mpg.isNull())
3207 craig 229
                        ScApp->doc->documentInfo.setComments(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 230
                mpg = mp.namedItem( "dc:language" );
231
                if (!mpg.isNull())
3207 craig 232
                        ScApp->doc->documentInfo.setLangInfo(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 233
                mpg = mp.namedItem( "meta:creation-date" );
234
                if (!mpg.isNull())
3207 craig 235
                        ScApp->doc->documentInfo.setDate(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 236
                mpg = mp.namedItem( "dc:creator" );
237
                if (!mpg.isNull())
3207 craig 238
                        ScApp->doc->documentInfo.setContrib(QString::fromUtf8(mpg.toElement().text()));
550 fschmid 239
                mpg = mp.namedItem( "meta:keywords" );
240
                if (!mpg.isNull())
241
                {
242
                        QString Keys = "";
243
                        for( QDomNode n = mpg.firstChild(); !n.isNull(); n = n.nextSibling() )
244
                        {
245
                                Keys += QString::fromUtf8(n.toElement().text())+", ";
246
                        }
247
                        if (Keys.length() > 2)
3207 craig 248
                                ScApp->doc->documentInfo.setKeywords(Keys.left(Keys.length()-2));
550 fschmid 249
                }
250
        }
3207 craig 251
        Doku = ScApp->doc;
2880 fschmid 252
        FPoint minSize = Doku->minCanvasCoordinate;
253
        FPoint maxSize = Doku->maxCanvasCoordinate;
3207 craig 254
        ScApp->view->Deselect();
541 fschmid 255
        Elements.clear();
2891 cbradney 256
        Doku->setLoading(true);
541 fschmid 257
        Doku->DoDrawing = false;
3207 craig 258
        ScApp->view->setUpdatesEnabled(false);
259
        ScApp->ScriptRunning = true;
541 fschmid 260
        qApp->setOverrideCursor(QCursor(Qt::waitCursor), true);
261
        if (!Doku->PageColors.contains("Black"))
2886 fschmid 262
                Doku->PageColors.insert("Black", ScColor(0, 0, 0, 255));
541 fschmid 263
        for( QDomNode drawPag = body.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
264
        {
265
                QDomElement dpg = drawPag.toElement();
3207 craig 266
                if (!interactive)
267
                        ScApp->view->addPage(PageCounter);
545 fschmid 268
                PageCounter++;
541 fschmid 269
                m_styleStack.clear();
270
                fillStyleStack( dpg );
271
                parseGroup( dpg );
272
        }
3207 craig 273
        ScApp->view->SelItem.clear();
274
        if ((Elements.count() > 1) && (interactive))
541 fschmid 275
        {
276
                for (uint a = 0; a < Elements.count(); ++a)
277
                {
278
                        Elements.at(a)->Groups.push(Doku->GroupCounter);
279
                }
280
                Doku->GroupCounter++;
281
        }
282
        Doku->DoDrawing = true;
3207 craig 283
        ScApp->view->setUpdatesEnabled(true);
284
        ScApp->ScriptRunning = false;
285
        if (interactive)
2891 cbradney 286
                Doku->setLoading(false);
541 fschmid 287
        qApp->setOverrideCursor(QCursor(Qt::arrowCursor), true);
3207 craig 288
        if ((Elements.count() > 0) && (!ret) && (interactive))
541 fschmid 289
        {
290
                Doku->DragP = true;
291
                Doku->DraggedElem = 0;
292
                Doku->DragElements.clear();
293
                for (uint dre=0; dre<Elements.count(); ++dre)
294
                {
295
                        Doku->DragElements.append(Elements.at(dre)->ItemNr);
3207 craig 296
                        ScApp->view->SelItem.append(Elements.at(dre));
541 fschmid 297
                }
298
                ScriXmlDoc *ss = new ScriXmlDoc();
3207 craig 299
                ScApp->view->setGroupRect();
300
                QDragObject *dr = new QTextDrag(ss->WriteElem(&ScApp->view->SelItem, Doku, ScApp->view), ScApp->view->viewport());
301
                ScApp->view->DeleteItem();
302
                ScApp->view->resizeContents(qRound((maxSize.x() - minSize.x()) * ScApp->view->getScale()), qRound((maxSize.y() - minSize.y()) * ScApp->view->getScale()));
303
                ScApp->view->scrollBy(qRound((Doku->minCanvasCoordinate.x() - minSize.x()) * ScApp->view->getScale()), qRound((Doku->minCanvasCoordinate.y() - minSize.y()) * ScApp->view->getScale()));
2880 fschmid 304
                Doku->minCanvasCoordinate = minSize;
305
                Doku->maxCanvasCoordinate = maxSize;
541 fschmid 306
                dr->setPixmap(loadIcon("DragPix.xpm"));
307
                dr->drag();
308
                delete ss;
309
                Doku->DragP = false;
310
                Doku->DraggedElem = 0;
311
                Doku->DragElements.clear();
312
        }
313
        else
314
        {
2891 cbradney 315
                Doku->setModified(false);
3207 craig 316
                ScApp->slotDocCh();
541 fschmid 317
        }
318
}
319
 
991 fschmid 320
QPtrList<PageItem> OODPlug::parseGroup(const QDomElement &e)
541 fschmid 321
{
322
        QPtrList<PageItem> GElements;
323
        FPointArray ImgClip;
324
        ImgClip.resize(0);
545 fschmid 325
        VGradient gradient;
795 fschmid 326
        double GradientAngle = 0;
327
        double xGoff = 0;
328
        double yGoff= 0;
545 fschmid 329
        bool HaveGradient = false;
330
        int GradientType = 0;
3200 cbradney 331
        double BaseX = Doku->currentPage->xOffset();
332
        double BaseY = Doku->currentPage->yOffset();
541 fschmid 333
        double lwidth = 0;
544 fschmid 334
        double x, y, w, h;
546 fschmid 335
        double FillTrans = 0;
547 fschmid 336
        double StrokeTrans = 0;
548 fschmid 337
        QValueList<double> dashes;
541 fschmid 338
        for (QDomNode n = e.firstChild(); !n.isNull(); n = n.nextSibling())
339
        {
340
                QString StrokeColor = "None";
341
                QString FillColor = "None";
546 fschmid 342
                FillTrans = 0;
547 fschmid 343
                StrokeTrans = 0;
541 fschmid 344
                int z = -1;
548 fschmid 345
                dashes.clear();
541 fschmid 346
                QDomElement b = n.toElement();
347
                if( b.isNull() )
348
                        continue;
349
                QString STag = b.tagName();
547 fschmid 350
                QString drawID = b.attribute("draw:name");
541 fschmid 351
                storeObjectStyles(b);
352
                if( m_styleStack.hasAttribute("draw:stroke"))
353
                {
544 fschmid 354
                        if( m_styleStack.attribute( "draw:stroke" ) == "none" )
355
                                lwidth = 0.0;
356
                        else
357
                        {
358
                                if( m_styleStack.hasAttribute("svg:stroke-width"))
359
                                {
360
                                        lwidth = parseUnit(m_styleStack.attribute("svg:stroke-width"));
361
                                        if (lwidth == 0)
362
                                                lwidth = 1;
363
                                }
364
                                if( m_styleStack.hasAttribute("svg:stroke-color"))
365
                                        StrokeColor = parseColor(m_styleStack.attribute("svg:stroke-color"));
547 fschmid 366
                                if( m_styleStack.hasAttribute( "svg:stroke-opacity" ) )
367
                                        StrokeTrans = m_styleStack.attribute( "svg:stroke-opacity" ).remove( '%' ).toDouble() / 100.0;
548 fschmid 368
                                if( m_styleStack.attribute( "draw:stroke" ) == "dash" )
369
                                {
370
                                        QString style = m_styleStack.attribute( "draw:stroke-dash" );
371
                                        if( style == "Ultrafine Dashed")
372
                                                dashes << 1.4 << 1.4;
373
                                        else if( style == "Fine Dashed" )
374
                                                dashes << 14.4 << 14.4;
375
                                        else if( style == "Fine Dotted")
376
                                                dashes << 13 << 13;
1549 subik 377
                                        else if( style == "Ultrafine 2 Dots 3 Dashes")
548 fschmid 378
                                                dashes << 1.45 << 3.6 << 1.45 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6 << 7.2 << 3.6;
379
                                        else if( style == "Line with Fine Dots")
380
                                        {
381
                                                dashes << 56.9 << 4.31;
382
                                                for (int dd = 0; dd < 10; ++ dd)
383
                                                {
384
                                                        dashes << 8.6 << 4.31;
385
                                                }
386
                                        }
387
                                        else if( style == "2 Dots 1 Dash" )
388
                                                dashes << 2.8 << 5.75 << 2.8 << 5.75 << 5.75 << 5.75;
389
                                }
544 fschmid 390
                        }
541 fschmid 391
                }
392
                if( m_styleStack.hasAttribute( "draw:fill" ) )
393
                {
394
                        QString fill = m_styleStack.attribute( "draw:fill" );
395
                        if( fill == "solid" )
396
                        {
397
                                if( m_styleStack.hasAttribute( "draw:fill-color" ) )
398
                                        FillColor = parseColor( m_styleStack.attribute("draw:fill-color"));
546 fschmid 399
                                if( m_styleStack.hasAttribute( "draw:transparency" ) )
400
                                        FillTrans = m_styleStack.attribute( "draw:transparency" ).remove( '%' ).toDouble() / 100.0;
541 fschmid 401
                        }
545 fschmid 402
                        else if( fill == "gradient" )
403
                        {
404
                                HaveGradient = true;
592 fschmid 405
                                GradientAngle = 0;
545 fschmid 406
                                gradient.clearStops();
407
                                gradient.setRepeatMethod( VGradient::none );
408
                                QString style = m_styleStack.attribute( "draw:fill-gradient-name" );
409
                                QDomElement* draw = m_draws[style];
410
                                if( draw )
411
                                {
412
                                        double border = 0.0;
546 fschmid 413
                                        int shadeS = 100;
414
                                        int shadeE = 100;
545 fschmid 415
                                        if( draw->hasAttribute( "draw:border" ) )
416
                                                border += draw->attribute( "draw:border" ).remove( '%' ).toDouble() / 100.0;
546 fschmid 417
                                        if( draw->hasAttribute( "draw:start-intensity" ) )
418
                                                shadeS = draw->attribute( "draw:start-intensity" ).remove( '%' ).toInt();
419
                                        if( draw->hasAttribute( "draw:end-intensity" ) )
420
                                                shadeE = draw->attribute( "draw:end-intensity" ).remove( '%' ).toInt();
545 fschmid 421
                                        QString type = draw->attribute( "draw:style" );
422
                                        if( type == "linear" || type == "axial" )
423
                                        {
424
                                                gradient.setType( VGradient::linear );
425
                                                GradientAngle = draw->attribute( "draw:angle" ).toDouble() / 10;
426
                                                GradientType = 1;
427
                                        }
592 fschmid 428
                                        else if( type == "radial" || type == "ellipsoid" )
429
                                        {
430
                                                if( draw->hasAttribute( "draw:cx" ) )
431
                                                        xGoff = draw->attribute( "draw:cx" ).remove( '%' ).toDouble() / 100.0;
432
                                                else
433
                                                        xGoff = 0.5;
434
                                                if( draw->hasAttribute( "draw:cy" ) )
435
                                                        yGoff = draw->attribute( "draw:cy" ).remove( '%' ).toDouble() / 100.0;
436
                                                else
437
                                                        yGoff = 0.5;
438
                                                GradientType = 2;
439
                                        }
546 fschmid 440
                                        QString c, c2;
441
                                        c = parseColor( draw->attribute( "draw:start-color" ) );
442
                                        c2 = parseColor( draw->attribute( "draw:end-color" ) );
592 fschmid 443
                                        if (((GradientAngle > 90) && (GradientAngle < 271)) || (GradientType == 2))
546 fschmid 444
                                        {
445
                                                gradient.addStop( Doku->PageColors[c2].getRGBColor(), 0.0, 0.5, 1, c2, shadeE );
446
                                                gradient.addStop( Doku->PageColors[c].getRGBColor(), 1.0 - border, 0.5, 1, c, shadeS );
447
                                        }
448
                                        else
449
                                        {
450
                                                gradient.addStop( Doku->PageColors[c].getRGBColor(), border, 0.5, 1, c, shadeS );
451
                                                gradient.addStop( Doku->PageColors[c2].getRGBColor(), 1.0, 0.5, 1, c2, shadeE );
452
                                        }
545 fschmid 453
                                }
454
                        }
541 fschmid 455
                }
545 fschmid 456
                if( STag == "draw:g" )
541 fschmid 457
                {
991 fschmid 458
                        QPtrList<PageItem> gElements = parseGroup( b );
459
                        for (uint gr = 0; gr < gElements.count(); ++gr)
548 fschmid 460
                        {
991 fschmid 461
                                gElements.at(gr)->Groups.push(Doku->GroupCounter);
462
                                GElements.append(gElements.at(gr));
548 fschmid 463
                        }
464
                        Doku->GroupCounter++;
545 fschmid 465
                }
466
                else if( STag == "draw:rect" )
467
                {
544 fschmid 468
                        x = parseUnit(b.attribute("svg:x"));
469
                        y = parseUnit(b.attribute("svg:y")) ;
470
                        w = parseUnit(b.attribute("svg:width"));
471
                        h = parseUnit(b.attribute("svg:height"));
541 fschmid 472
                        double corner = parseUnit(b.attribute("draw:corner-radius"));
3292 cbradney 473
                        //z = ScApp->view->PaintRect(BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor);
474
                        Doku->itemAdd(PageItem::Polygon, PageItem::Rectangle, BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor, !ScApp->view->Mpressed);
541 fschmid 475
                        PageItem* ite = Doku->Items.at(z);
476
                        if (corner != 0)
477
                        {
478
                                ite->RadRect = corner;
3242 cbradney 479
                                ite->SetFrameRound();
480
                                ScApp->view->setRedrawBounding(ite);
541 fschmid 481
                        }
482
                }
544 fschmid 483
                else if( STag == "draw:circle" || STag == "draw:ellipse" )
484
                {
485
                        x = parseUnit(b.attribute("svg:x"));
486
                        y = parseUnit(b.attribute("svg:y")) ;
487
                        w = parseUnit(b.attribute("svg:width"));
488
                        h = parseUnit(b.attribute("svg:height"));
3292 cbradney 489
                        //z = ScApp->view->PaintEllipse(BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor);
490
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Ellipse, BaseX+x, BaseY+y, w, h, lwidth, FillColor, StrokeColor, !ScApp->view->Mpressed);
544 fschmid 491
                }
492
                else if( STag == "draw:line" ) // line
493
                {
494
                        double x1 = b.attribute( "svg:x1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:x1" ) );
495
                        double y1 = b.attribute( "svg:y1" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:y1" ) );
496
                        double x2 = b.attribute( "svg:x2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:x2" ) );
497
                        double y2 = b.attribute( "svg:y2" ).isEmpty() ? 0.0 : parseUnit( b.attribute( "svg:y2" ) );
3292 cbradney 498
                        //z = ScApp->view->PaintPoly(BaseX, BaseY, 10, 10, lwidth, "None", StrokeColor);
499
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, "None", StrokeColor, !ScApp->view->Mpressed);
544 fschmid 500
                        PageItem* ite = Doku->Items.at(z);
501
                        ite->PoLine.resize(4);
502
                        ite->PoLine.setPoint(0, FPoint(x1, y1));
503
                        ite->PoLine.setPoint(1, FPoint(x1, y1));
504
                        ite->PoLine.setPoint(2, FPoint(x2, y2));
505
                        ite->PoLine.setPoint(3, FPoint(x2, y2));
1065 cbradney 506
                        FPoint wh = getMaxClipF(&ite->PoLine);
544 fschmid 507
                        ite->Width = wh.x();
508
                        ite->Height = wh.y();
550 fschmid 509
                        ite->ClipEdited = true;
510
                        ite->FrameType = 3;
548 fschmid 511
                        if (!b.hasAttribute("draw:transform"))
512
                        {
513
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
3207 craig 514
                                ScApp->view->AdjustItemSize(ite);
548 fschmid 515
                        }
1549 subik 516
                }
544 fschmid 517
                else if ( STag == "draw:polygon" )
518
                {
3292 cbradney 519
                        //z = ScApp->view->PaintPoly(BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor);
520
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor, !ScApp->view->Mpressed);
544 fschmid 521
                        PageItem* ite = Doku->Items.at(z);
522
                        ite->PoLine.resize(0);
523
                        appendPoints(&ite->PoLine, b);
1065 cbradney 524
                        FPoint wh = getMaxClipF(&ite->PoLine);
544 fschmid 525
                        ite->Width = wh.x();
526
                        ite->Height = wh.y();
550 fschmid 527
                        ite->ClipEdited = true;
528
                        ite->FrameType = 3;
548 fschmid 529
                        if (!b.hasAttribute("draw:transform"))
530
                        {
531
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
3207 craig 532
                                ScApp->view->AdjustItemSize(ite);
548 fschmid 533
                        }
544 fschmid 534
                }
535
                else if( STag == "draw:polyline" )
536
                {
3292 cbradney 537
                        //z = ScApp->view->PaintPolyLine(BaseX, BaseY, 10, 10, lwidth, "None", StrokeColor);
538
                        z = Doku->itemAdd(PageItem::PolyLine, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, "None", StrokeColor, !ScApp->view->Mpressed);
544 fschmid 539
                        PageItem* ite = Doku->Items.at(z);
540
                        ite->PoLine.resize(0);
541
                        appendPoints(&ite->PoLine, b);
1065 cbradney 542
                        FPoint wh = getMaxClipF(&ite->PoLine);
544 fschmid 543
                        ite->Width = wh.x();
544
                        ite->Height = wh.y();
550 fschmid 545
                        ite->ClipEdited = true;
546
                        ite->FrameType = 3;
548 fschmid 547
                        if (!b.hasAttribute("draw:transform"))
548
                        {
549
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
3207 craig 550
                                ScApp->view->AdjustItemSize(ite);
548 fschmid 551
                        }
544 fschmid 552
                }
553
                else if( STag == "draw:path" )
554
                {
3292 cbradney 555
                        //z = ScApp->view->PaintPoly(BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor);
556
                        z = Doku->itemAdd(PageItem::Polygon, PageItem::Unspecified, BaseX, BaseY, 10, 10, lwidth, FillColor, StrokeColor, !ScApp->view->Mpressed);
544 fschmid 557
                        PageItem* ite = Doku->Items.at(z);
558
                        ite->PoLine.resize(0);
559
                        if (parseSVG( b.attribute( "svg:d" ), &ite->PoLine ))
1460 cbradney 560
                                ite->convertTo(PageItem::PolyLine);
544 fschmid 561
                        if (ite->PoLine.size() < 4)
562
                        {
3207 craig 563
                                ScApp->view->SelItem.append(ite);
564
                                ScApp->view->DeleteItem();
544 fschmid 565
                                z = -1;
566
                        }
567
                        else
568
                        {
569
                                x = parseUnit(b.attribute("svg:x"));
570
                                y = parseUnit(b.attribute("svg:y")) ;
571
                                w = parseUnit(b.attribute("svg:width"));
572
                                h = parseUnit(b.attribute("svg:height"));
573
                                double vx = 0;
574
                                double vy = 0;
575
                                double vw = 1;
576
                                double vh = 1;
577
                                parseViewBox(b, &vx, &vy, &vw, &vh);
578
                                QWMatrix mat;
579
                                mat.translate(x, y);
580
                                mat.scale(w / vw, h / vh);
581
                                ite->PoLine.map(mat);
1065 cbradney 582
                                FPoint wh = getMaxClipF(&ite->PoLine);
544 fschmid 583
                                ite->Width = wh.x();
584
                                ite->Height = wh.y();
550 fschmid 585
                                ite->ClipEdited = true;
586
                                ite->FrameType = 3;
548 fschmid 587
                                if (!b.hasAttribute("draw:transform"))
588
                                {
589
                                        ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
3207 craig 590
                                        ScApp->view->AdjustItemSize(ite);
548 fschmid 591
                                }
544 fschmid 592
                        }
593
                }
594
                else if ( STag == "draw:text-box" )
595
                {
596
                        x = parseUnit(b.attribute("svg:x"));
597
                        y = parseUnit(b.attribute("svg:y")) ;
598
                        w = parseUnit(b.attribute("svg:width"));
599
                        h = parseUnit(b.attribute("svg:height"));
3292 cbradney 600
                        //z = ScApp->view->PaintText(BaseX+x, BaseY+y, w, h+(h*0.1), lwidth, StrokeColor);
601
                        z = Doku->itemAdd(PageItem::TextFrame, PageItem::Unspecified, BaseX+x, BaseY+y, w, h+(h*0.1), lwidth, "None", StrokeColor, !ScApp->view->Mpressed);
592 fschmid 602
                }
603
                else
604
                {
3211 craig 605
                        qDebug("Not supported yet: %s", STag.local8Bit().data());
592 fschmid 606
                        continue;
607
                }
608
                if (z != -1)
609
                {
544 fschmid 610
                        PageItem* ite = Doku->Items.at(z);
611
                        ite->Extra = 0;
612
                        ite->TExtra = 0;
613
                        ite->BExtra = 0;
614
                        ite->RExtra = 0;
615
                        bool firstPa = false;
616
                        for ( QDomNode n = b.firstChild(); !n.isNull(); n = n.nextSibling() )
617
                        {
1194 fschmid 618
                                int FontSize = Doku->toolSettings.defSize;
592 fschmid 619
                                int AbsStyle = 0;
544 fschmid 620
                                QDomElement e = n.toElement();
592 fschmid 621
                                if( m_styleStack.hasAttribute("fo:text-align"))
622
                                {
623
                                        if (m_styleStack.attribute("fo:text-align") == "left")
624
                                                AbsStyle = 0;
625
                                        if (m_styleStack.attribute("fo:text-align") == "center")
626
                                                AbsStyle = 1;
627
                                        if (m_styleStack.attribute("fo:text-align") == "right")
628
                                                AbsStyle = 2;
629
                                }
547 fschmid 630
                                if( m_styleStack.hasAttribute("fo:font-family"))
631
                                {
632
                                        FontSize = m_styleStack.attribute("fo:font-size").remove( "pt" ).toInt();
633
                                }
544 fschmid 634
/* ToDo: Add reading of Textstyles here */
592 fschmid 635
                                ite->LineSp = FontSize + FontSize * 0.2;
544 fschmid 636
                                Serializer *ss = new Serializer("");
592 fschmid 637
                                ss->Objekt = QString::fromUtf8(e.text())+QChar(10);
1194 fschmid 638
                                ss->GetText(ite, AbsStyle, Doku->toolSettings.defFont, FontSize*10, firstPa);
544 fschmid 639
                                delete ss;
640
                                firstPa = true;
1460 cbradney 641
                                if (ite->itemType() != PageItem::PolyLine)
642
                                        ite->convertTo(PageItem::TextFrame);
544 fschmid 643
                        }
1394 cbradney 644
                        ite->setFillTransparency(FillTrans);
645
                        ite->setLineTransparency(StrokeTrans);
548 fschmid 646
                        if (dashes.count() != 0)
647
                                ite->DashValues = dashes;
2877 cbradney 648
                        if (!drawID.isEmpty())
1361 tsoots 649
                                ite->setItemName(drawID);
541 fschmid 650
                        if (b.hasAttribute("draw:transform"))
651
                        {
546 fschmid 652
                                parseTransform(&ite->PoLine, b.attribute("draw:transform"));
545 fschmid 653
                                ite->ClipEdited = true;
654
                                ite->FrameType = 3;
1065 cbradney 655
                                FPoint wh = getMaxClipF(&ite->PoLine);
545 fschmid 656
                                ite->Width = wh.x();
657
                                ite->Height = wh.y();
658
                                ite->Clip = FlattenPath(ite->PoLine, ite->Segments);
3207 craig 659
                                ScApp->view->AdjustItemSize(ite);
541 fschmid 660
                        }
545 fschmid 661
                        if (HaveGradient)
662
                        {
663
                                ite->GrType = 0;
664
                                ite->fill_gradient = gradient;
665
                                if (GradientType == 1)
666
                                {
546 fschmid 667
                                        bool flipped = false;
668
                                        if ((GradientAngle == 0) || (GradientAngle == 180) || (GradientAngle == 90) || (GradientAngle == 270))
669
                                        {
670
                                                if ((GradientAngle == 0) || (GradientAngle == 180))
671
                                                {
672
                                                        ite->GrType = 2;
3207 craig 673
                                                        ScApp->view->updateGradientVectors(ite);
546 fschmid 674
                                                }
675
                                                else if ((GradientAngle == 90) || (GradientAngle == 270))
676
                                                {
677
                                                        ite->GrType = 1;
3207 craig 678
                                                        ScApp->view->updateGradientVectors(ite);
546 fschmid 679
                                                }
680
                                        }
681
                                        else
682
                                        {
683
                                                if ((GradientAngle > 90) && (GradientAngle < 270))
684
                                                        GradientAngle -= 180;
685
                                                else if ((GradientAngle > 270) && (GradientAngle < 360))
686
                                                {
687
                                                        GradientAngle = 360 - GradientAngle;
688
                                                        flipped = true;
689
                                                }
690
                                                double xpos;
1795 cbradney 691
                                                xpos = (ite->Width / 2) * tan(GradientAngle* M_PI / 180.0) * (ite->Height / ite->Width) + (ite->Width / 2);
546 fschmid 692
                                                if ((xpos < 0) || (xpos > ite->Width))
693
                                                {
1795 cbradney 694
                                                        xpos = (ite->Height / 2)- (ite->Height / 2) * tan(GradientAngle* M_PI / 180.0) * (ite->Height / ite->Width);
546 fschmid 695
                                                        if (flipped)
696
                                                        {
697
                                                                ite->GrEndX = ite->Width;
698
                                                                ite->GrEndY = ite->Height - xpos;
699
                                                                ite->GrStartX = 0;
700
                                                                ite->GrStartY = xpos;
701
                                                        }
702
                                                        else
703
                                                        {
704
                                                                ite->GrEndY = xpos;
705
                                                                ite->GrEndX = ite->Width;
706
                                                                ite->GrStartX = 0;
707
                                                                ite->GrStartY = ite->Height - xpos;
708
                                                        }
709
                                                }
710
                                                else
711
                                                {
712
                                                        ite->GrEndX = xpos;
713
                                                        ite->GrEndY = ite->Height;
714
                                                        ite->GrStartX = ite->Width - xpos;
715
                                                        ite->GrStartY = 0;
716
                                                }
717
                                                if (flipped)
718
                                                {
719
                                                        ite->GrEndX = ite->Width - xpos;
720
                                                        ite->GrEndY = ite->Height;
721
                                                        ite->GrStartX = xpos;
722
                                                        ite->GrStartY = 0;
723
                                                }
724
                                                ite->GrType = 6;
725
                                        }
545 fschmid 726
                                }
592 fschmid 727
                                if (GradientType == 2)
728
                                {
729
                                        ite->GrType = 7;
730
                                        ite->GrStartX = ite->Width * xGoff;
731
                                        ite->GrStartY = ite->Height* yGoff;
732
                                        if (ite->Width >= ite->Height)
733
                                        {
734
                                                ite->GrEndX = ite->Width;
735
                                                ite->GrEndY = ite->Height / 2.0;
736
                                        }
737
                                        else
738
                                        {
739
                                                ite->GrEndX = ite->Width / 2.0;
740
                                                ite->GrEndY = ite->Height;
741
                                        }
3207 craig 742
                                        ScApp->view->updateGradientVectors(ite);
592 fschmid 743
                                }
545 fschmid 744
                                HaveGradient = false;
745
                        }
541 fschmid 746
                        GElements.append(ite);
747
                        Elements.append(ite);
748
                }
749
        }
991 fschmid 750
        return GElements;
541 fschmid 751
}
752
 
753
void OODPlug::createStyleMap( QDomDocument &docstyles )
754
{
755
        QDomElement styles = docstyles.documentElement();
756
        if( styles.isNull() )
757
                return;
758
 
759
        QDomNode fixedStyles = styles.namedItem( "office:styles" );
760
        if( !fixedStyles.isNull() )
761
        {
545 fschmid 762
                insertDraws( fixedStyles.toElement() );
541 fschmid 763
                insertStyles( fixedStyles.toElement() );
764
        }
765
        QDomNode automaticStyles = styles.namedItem( "office:automatic-styles" );
766
        if( !automaticStyles.isNull() )
767
                insertStyles( automaticStyles.toElement() );
768
 
769
        QDomNode masterStyles = styles.namedItem( "office:master-styles" );
770
        if( !masterStyles.isNull() )
771
                insertStyles( masterStyles.toElement() );
772
}
773
 
545 fschmid 774
void OODPlug::insertDraws( const QDomElement& styles )
775
{
776
        for( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
777
        {
778
                QDomElement e = n.toElement();
779
                if( !e.hasAttribute( "draw:name" ) )
780
                        continue;
781
                QString name = e.attribute( "draw:name" );
782
                m_draws.insert( name, new QDomElement( e ) );
783
        }
784
}
785
 
541 fschmid 786
void OODPlug::insertStyles( const QDomElement& styles )
787
{
788
        for ( QDomNode n = styles.firstChild(); !n.isNull(); n = n.nextSibling() )
789
        {
790
                QDomElement e = n.toElement();
791
                if( !e.hasAttribute( "style:name" ) )
792
                        continue;
793
                QString name = e.attribute( "style:name" );
794
                m_styles.insert( name, new QDomElement( e ) );
795
        }
796
}
797
 
798
void OODPlug::fillStyleStack( const QDomElement& object )
799
{
800
        if( object.hasAttribute( "presentation:style-name" ) )
801
                addStyles( m_styles[object.attribute( "presentation:style-name" )] );
802
        if( object.hasAttribute( "draw:style-name" ) )
803
                addStyles( m_styles[object.attribute( "draw:style-name" )] );
804
        if( object.hasAttribute( "draw:text-style-name" ) )
805
                addStyles( m_styles[object.attribute( "draw:text-style-name" )] );
806
        if( object.hasAttribute( "text:style-name" ) )
807
                addStyles( m_styles[object.attribute( "text:style-name" )] );
808
}
809
 
810
void OODPlug::addStyles( const QDomElement* style )
811
{
812
        if( style->hasAttribute( "style:parent-style-name" ) )
813
                addStyles( m_styles[style->attribute( "style:parent-style-name" )] );
814
        m_styleStack.push( *style );
815
}
816
 
817
void OODPlug::storeObjectStyles( const QDomElement& object )
818
{
819
        fillStyleStack( object );
820
}
821
 
822
double OODPlug::parseUnit(const QString &unit)
823
{
824
        QString unitval=unit;
2877 cbradney 825
        if (unit.isEmpty())
541 fschmid 826
                return 0.0;
827
        if( unit.right( 2 ) == "pt" )
828
                unitval.replace( "pt", "" );
829
        else if( unit.right( 2 ) == "cm" )
830
                unitval.replace( "cm", "" );
831
        else if( unit.right( 2 ) == "mm" )
832
                unitval.replace( "mm" , "" );
833
        else if( unit.right( 2 ) == "in" )
834
                unitval.replace( "in", "" );
835
        else if( unit.right( 2 ) == "px" )
836
                unitval.replace( "px", "" );
837
        double value = unitval.toDouble();
838
        if( unit.right( 2 ) == "pt" )
839
                value = value;
840
        else if( unit.right( 2 ) == "cm" )
841
                value = ( value / 2.54 ) * 72;
842
        else if( unit.right( 2 ) == "mm" )
843
                value = ( value / 25.4 ) * 72;
844
        else if( unit.right( 2 ) == "in" )
845
                value = value * 72;
846
        else if( unit.right( 2 ) == "px" )
847
                value = value;
848
        return value;
849
}
850
 
851
QColor OODPlug::parseColorN( const QString &rgbColor )
852
{
853
        int r, g, b;
854
        keywordToRGB( rgbColor, r, g, b );
855
        return QColor( r, g, b );
856
}
857
 
858
QString OODPlug::parseColor( const QString &s )
859
{
860
        QColor c;
861
        QString ret = "None";
862
        if( s.startsWith( "rgb(" ) )
863
        {
864
                QString parse = s.stripWhiteSpace();
865
                QStringList colors = QStringList::split( ',', parse );
866
                QString r = colors[0].right( ( colors[0].length() - 4 ) );
867
                QString g = colors[1];
868
                QString b = colors[2].left( ( colors[2].length() - 1 ) );
869
                if( r.contains( "%" ) )
870
                {
871
                        r = r.left( r.length() - 1 );
872
                        r = QString::number( static_cast<int>( ( static_cast<double>( 255 * r.toDouble() ) / 100.0 ) ) );
873
                }
874
                if( g.contains( "%" ) )
875
                {
876
                        g = g.left( g.length() - 1 );
877
                        g = QString::number( static_cast<int>( ( static_cast<double>( 255 * g.toDouble() ) / 100.0 ) ) );
878
                }
879
                if( b.contains( "%" ) )
880
                {
881
                        b = b.left( b.length() - 1 );
882
                        b = QString::number( static_cast<int>( ( static_cast<double>( 255 * b.toDouble() ) / 100.0 ) ) );
883
                }
884
                c = QColor(r.toInt(), g.toInt(), b.toInt());
885
        }
886
        else
887
        {
888
                QString rgbColor = s.stripWhiteSpace();
889
                if( rgbColor.startsWith( "#" ) )
890
                        c.setNamedColor( rgbColor );
891
                else
892
                        c = parseColorN( rgbColor );
893
        }
1065 cbradney 894
        ColorList::Iterator it;
541 fschmid 895
        bool found = false;
1488 fschmid 896
        int r, g, b;
897
        QColor tmpR;
541 fschmid 898
        for (it = Doku->PageColors.begin(); it != Doku->PageColors.end(); ++it)
899
        {
1488 fschmid 900
                Doku->PageColors[it.key()].getRGB(&r, &g, &b);
901
                tmpR.setRgb(r, g, b);
902
                if (c == tmpR && Doku->PageColors[it.key()].getColorModel() == colorModelRGB)
541 fschmid 903
                {
904
                        ret = it.key();
905
                        found = true;
906
                }
907
        }
908
        if (!found)
909
        {
2886 fschmid 910
                ScColor tmp;
541 fschmid 911
                tmp.fromQColor(c);
912
                Doku->PageColors.insert("FromOODraw"+c.name(), tmp);
3207 craig 913
                ScApp->propertiesPalette->Cpal->SetColors(Doku->PageColors);
541 fschmid 914
                ret = "FromOODraw"+c.name();
915
        }
916
        return ret;
917
}
918
 
546 fschmid 919
void OODPlug::parseTransform(FPointArray *composite, const QString &transform)
541 fschmid 920
{
545 fschmid 921
        double dx, dy;
922
        QWMatrix result;
541 fschmid 923
        QStringList subtransforms = QStringList::split(')', transform);
924
        QStringList::ConstIterator it = subtransforms.begin();
925
        QStringList::ConstIterator end = subtransforms.end();
546 fschmid 926
        for (; it != end; ++it)
541 fschmid 927
        {
928
                QStringList subtransform = QStringList::split('(', (*it));
929
                subtransform[0] = subtransform[0].stripWhiteSpace().lower();
930
                subtransform[1] = subtransform[1].simplifyWhiteSpace();
931
                QRegExp reg("[,( ]");
932
                QStringList params = QStringList::split(reg, subtransform[1]);
933
                if(subtransform[0].startsWith(";") || subtransform[0].startsWith(","))
934
                        subtransform[0] = subtransform[0].right(subtransform[0].length() - 1);
935
                if(subtransform[0] == "rotate")
546 fschmid 936
                {
937
                        result = QWMatrix();
1795 cbradney 938
                        result.rotate(-parseUnit(params[0]) * 180 / M_PI);
546 fschmid 939
                        composite->map(result);
940
                }
541 fschmid 941
                else if(subtransform[0] == "translate")
942
                {
943
                        if(params.count() == 2)
944
                        {
545 fschmid 945
                                dx = parseUnit(params[0]);
946
                                dy = parseUnit(params[1]);
541 fschmid 947
                        }
948
                        else
949
                        {
545 fschmid 950
                                dx = parseUnit(params[0]);
951
                                dy =0.0;
541 fschmid 952
                        }
546 fschmid 953
                        result = QWMatrix();
545 fschmid 954
                        result.translate(dx, dy);
546 fschmid 955
                        composite->map(result);
541 fschmid 956
                }
545 fschmid 957
                else if(subtransform[0] == "skewx")
546 fschmid 958
                {
959
                        result = QWMatrix();
545 fschmid 960
                        result.shear(-params[0].toDouble(), 0.0);
546 fschmid 961
                        composite->map(result);
962
                }
545 fschmid 963
                else if(subtransform[0] == "skewy")
546 fschmid 964
                {
965
                        result = QWMatrix();
545 fschmid 966
                        result.shear(0.0, -params[0].toDouble());
546 fschmid 967
                        composite->map(result);
968
                }
541 fschmid 969
        }
970
}
971
 
544 fschmid 972
void OODPlug::parseViewBox( const QDomElement& object, double *x, double *y, double *w, double *h )
541 fschmid 973
{
544 fschmid 974
        if( !object.attribute( "svg:viewBox" ).isEmpty() )
975
        {
976
                QString viewbox( object.attribute( "svg:viewBox" ) );
977
                QStringList points = QStringList::split( ' ', viewbox.replace( QRegExp(","), " ").simplifyWhiteSpace() );
978
                *x = points[0].toDouble();
979
                *y = points[1].toDouble();
980
                *w = points[2].toDouble();
981
                *h = points[3].toDouble();
982
        }
541 fschmid 983
}
984
 
544 fschmid 985
void OODPlug::appendPoints(FPointArray *composite, const QDomElement& object)
541 fschmid 986
{
544 fschmid 987
        double x = parseUnit(object.attribute("svg:x"));
988
        double y = parseUnit(object.attribute("svg:y")) ;
989
        double w = parseUnit(object.attribute("svg:width"));
990
        double h = parseUnit(object.attribute("svg:height"));
991
        double vx = 0;
992
        double vy = 0;
993
        double vw = 1;
994
        double vh = 1;
995
        parseViewBox(object, &vx, &vy, &vw, &vh);
996
        QStringList ptList = QStringList::split( ' ', object.attribute( "draw:points" ) );
997
        FPoint point, firstP;
998
        bool bFirst = true;
999
        for( QStringList::Iterator it = ptList.begin(); it != ptList.end(); ++it )
1000
        {
1001
                point = FPoint((*it).section( ',', 0, 0 ).toDouble(), (*it).section( ',', 1, 1 ).toDouble());
1002
                if (bFirst)
1003
                {
1004
                        composite->addPoint(point);
1005
                        composite->addPoint(point);
1006
                        firstP = point;
1007
                        bFirst = false;
1008
                }
1009
                else
1010
                {
1011
                        composite->addPoint(point);
1012
                        composite->addPoint(point);
1013
                        composite->addPoint(point);
1014
                        composite->addPoint(point);
1015
                }
1016
    }
1017
        composite->addPoint(firstP);
1018
        composite->addPoint(firstP);
1019
        QWMatrix mat;
1020
        mat.translate(x, y);
1021
        mat.scale(w / vw, h / vh);
1022
        composite->map(mat);
541 fschmid 1023
}
1024
 
544 fschmid 1025
const char * OODPlug::getCoord( const char *ptr, double &number )
541 fschmid 1026
{
1027
        int integer, exponent;
1028
        double decimal, frac;
1029
        int sign, expsign;
1030
 
1031
        exponent = 0;
1032
        integer = 0;
1033
        frac = 1.0;
1034
        decimal = 0;
1035
        sign = 1;
1036
        expsign = 1;
1037
 
544 fschmid 1038
        // read the sign
541 fschmid 1039
        if(*ptr == '+')
1040
                ptr++;
1041
        else if(*ptr == '-')
1042
        {
1043
                ptr++;
1044
                sign = -1;
1045
        }
1046
 
544 fschmid 1047
        // read the integer part
541 fschmid 1048
        while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1049
                integer = (integer * 10) + *(ptr++) - '0';
544 fschmid 1050
        if(*ptr == '.') // read the decimals
541 fschmid 1051
        {
1052
                ptr++;
1053
                while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1054
                        decimal += (*(ptr++) - '0') * (frac *= 0.1);
1055
        }
1056
 
544 fschmid 1057
        if(*ptr == 'e' || *ptr == 'E') // read the exponent part
541 fschmid 1058
        {
1059
                ptr++;
1060
 
544 fschmid 1061
                // read the sign of the exponent
541 fschmid 1062
                if(*ptr == '+')
1063
                        ptr++;
1064
                else if(*ptr == '-')
1065
                {
1066
                        ptr++;
1067
                        expsign = -1;
1068
                }
1069
 
1070
                exponent = 0;
1071
                while(*ptr != '\0' && *ptr >= '0' && *ptr <= '9')
1072
                {
1073
                        exponent *= 10;
1074
                        exponent += *ptr - '0';
1075
                        ptr++;
1076
                }
1077
        }
1078
        number = integer + decimal;
1079
        number *= sign * pow( static_cast<double>(10), static_cast<double>( expsign * exponent ) );
1080
 
544 fschmid 1081
        // skip the following space
541 fschmid 1082
        if(*ptr == ' ')
1083
                ptr++;
1084
 
1085
        return ptr;
1086
}
1087
 
544 fschmid 1088
bool OODPlug::parseSVG( const QString &s, FPointArray *ite )
541 fschmid 1089
{
1090
        QString d = s;
1091
        d = d.replace( QRegExp( "," ), " ");
1092
        bool ret = false;
1093
        if( !d.isEmpty() )
1094
        {
1095
                d = d.simplifyWhiteSpace();
1096
                const char *ptr = d.latin1();
1097
                const char *end = d.latin1() + d.length() + 1;
1098
                double contrlx, contrly, curx, cury, subpathx, subpathy, tox, toy, x1, y1, x2, y2, xc, yc;
1099
                double px1, py1, px2, py2, px3, py3;
1100
                bool relative;
1101
                FirstM = true;
1102
                char command = *(ptr++), lastCommand = ' ';
1103
                subpathx = subpathy = curx = cury = contrlx = contrly = 0.0;
1104
                while( ptr < end )
1105
                {
1106
                        if( *ptr == ' ' )
1107
                                ptr++;
1108
                        relative = false;
1109
                        switch( command )
1110
                        {
1111
                        case 'm':
1112
                                relative = true;
1113
                        case 'M':
1114
                                {
1115
                                        ptr = getCoord( ptr, tox );
1116
                                        ptr = getCoord( ptr, toy );
1117
                                        WasM = true;
1118
                                        subpathx = curx = relative ? curx + tox : tox;
1119
                                        subpathy = cury = relative ? cury + toy : toy;
1120
                                        svgMoveTo(curx, cury );
1121
                                        break;
1122
                                }
1123
                        case 'l':
1124
                                relative = true;
1125
                        case 'L':
1126
                                {
1127
                                        ptr = getCoord( ptr, tox );
1128
                                        ptr = getCoord( ptr, toy );
1129
                                        curx = relative ? curx + tox : tox;
1130
                                        cury = relative ? cury + toy : toy;
1131
                                        svgLineTo(ite, curx, cury );
1132
                                        break;
1133
                                }
1134
                        case 'h':
1135
                                {
1136
                                        ptr = getCoord( ptr, tox );
1137
                                        curx = curx + tox;
1138
                                        svgLineTo(ite, curx, cury );
1139
                                        break;
1140
                                }
1141
                        case 'H':
1142
                                {
1143
                                        ptr = getCoord( ptr, tox );
1144
                                        curx = tox;
1145
                                        svgLineTo(ite, curx, cury );
1146
                                        break;
1147
                                }
1148
                        case 'v':
1149
                                {
1150
                                        ptr = getCoord( ptr, toy );
1151
                                        cury = cury + toy;
1152
                                        svgLineTo(ite, curx, cury );
1153
                                        break;
1154
                                }
1155
                        case 'V':
1156
                                {
1157
                                        ptr = getCoord( ptr, toy );
1158
                                        cury = toy;
1159
                                        svgLineTo(ite,  curx, cury );
1160
                                        break;
1161
                                }
1162
                        case 'z':
1163
                        case 'Z':
1164
                                {
587 fschmid 1165
//                                      curx = subpathx;
1166
//                                      cury = subpathy;
541 fschmid 1167
                                        svgClosePath(ite);
1168
                                        break;
1169
                                }
1170
                        case 'c':
1171
                                relative = true;
1172
                        case 'C':
1173
                                {
1174
                                        ptr = getCoord( ptr, x1 );
1175
                                        ptr = getCoord( ptr, y1 );
1176
                                        ptr = getCoord( ptr, x2 );
1177
                                        ptr = getCoord( ptr, y2 );
1178
                                        ptr = getCoord( ptr, tox );
1179
                                        ptr = getCoord( ptr, toy );
1180
                                        px1 = relative ? curx + x1 : x1;
1181
                                        py1 = relative ? cury + y1 : y1;
1182
                                        px2 = relative ? curx + x2 : x2;
1183
                                        py2 = relative ? cury + y2 : y2;
1184
                                        px3 = relative ? curx + tox : tox;
1185
                                        py3 = relative ? cury + toy : toy;
1186
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1187
                                        contrlx = relative ? curx + x2 : x2;
1188
                                        contrly = relative ? cury + y2 : y2;
1189
                                        curx = relative ? curx + tox : tox;
1190
                                        cury = relative ? cury + toy : toy;
1191
                                        break;
1192
                                }
1193
                        case 's':
1194
                                relative = true;
1195
                        case 'S':
1196
                                {
1197
                                        ptr = getCoord( ptr, x2 );
1198
                                        ptr = getCoord( ptr, y2 );
1199
                                        ptr = getCoord( ptr, tox );
1200
                                        ptr = getCoord( ptr, toy );
1201
                                        px1 = 2 * curx - contrlx;
1202
                                        py1 = 2 * cury - contrly;
1203
                                        px2 = relative ? curx + x2 : x2;
1204
                                        py2 = relative ? cury + y2 : y2;
1205
                                        px3 = relative ? curx + tox : tox;
1206
                                        py3 = relative ? cury + toy : toy;
1207
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1208
                                        contrlx = relative ? curx + x2 : x2;
1209
                                        contrly = relative ? cury + y2 : y2;
1210
                                        curx = relative ? curx + tox : tox;
1211
                                        cury = relative ? cury + toy : toy;
1212
                                        break;
1213
                                }
1214
                        case 'q':
1215
                                relative = true;
1216
                        case 'Q':
1217
                                {
1218
                                        ptr = getCoord( ptr, x1 );
1219
                                        ptr = getCoord( ptr, y1 );
1220
                                        ptr = getCoord( ptr, tox );
1221
                                        ptr = getCoord( ptr, toy );
1222
                                        px1 = relative ? (curx + 2 * (x1 + curx)) * (1.0 / 3.0) : (curx + 2 * x1) * (1.0 / 3.0);
1223
                                        py1 = relative ? (cury + 2 * (y1 + cury)) * (1.0 / 3.0) : (cury + 2 * y1) * (1.0 / 3.0);
1224
                                        px2 = relative ? ((curx + tox) + 2 * (x1 + curx)) * (1.0 / 3.0) : (tox + 2 * x1) * (1.0 / 3.0);
1225
                                        py2 = relative ? ((cury + toy) + 2 * (y1 + cury)) * (1.0 / 3.0) : (toy + 2 * y1) * (1.0 / 3.0);
1226
                                        px3 = relative ? curx + tox : tox;
1227
                                        py3 = relative ? cury + toy : toy;
1228
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1229
                                        contrlx = relative ? curx + x1 : (tox + 2 * x1) * (1.0 / 3.0);
1230
                                        contrly = relative ? cury + y1 : (toy + 2 * y1) * (1.0 / 3.0);
1231
                                        curx = relative ? curx + tox : tox;
1232
                                        cury = relative ? cury + toy : toy;
1233
                                        break;
1234
                                }
1235
                        case 't':
1236
                                relative = true;
1237
                        case 'T':
1238
                                {
1239
                                        ptr = getCoord(ptr, tox);
1240
                                        ptr = getCoord(ptr, toy);
1241
                                        xc = 2 * curx - contrlx;
1242
                                        yc = 2 * cury - contrly;
1243
                                        px1 = relative ? (curx + 2 * xc) * (1.0 / 3.0) : (curx + 2 * xc) * (1.0 / 3.0);
1244
                                        py1 = relative ? (cury + 2 * yc) * (1.0 / 3.0) : (cury + 2 * yc) * (1.0 / 3.0);
1245
                                        px2 = relative ? ((curx + tox) + 2 * xc) * (1.0 / 3.0) : (tox + 2 * xc) * (1.0 / 3.0);
1246
                                        py2 = relative ? ((cury + toy) + 2 * yc) * (1.0 / 3.0) : (toy + 2 * yc) * (1.0 / 3.0);
1247
                                        px3 = relative ? curx + tox : tox;
1248
                                        py3 = relative ? cury + toy : toy;
1249
                                        svgCurveToCubic(ite, px1, py1, px2, py2, px3, py3 );
1250
                                        contrlx = xc;
1251
                                        contrly = yc;
1252
                                        curx = relative ? curx + tox : tox;
1253
                                        cury = relative ? cury + toy : toy;
1254
                                        break;
1255
                                }
1256
                        case 'a':
1257
                                relative = true;
1258
                        case 'A':
1259
                                {
1260
                                        bool largeArc, sweep;
1261
                                        double angle, rx, ry;
1262
                                        ptr = getCoord( ptr, rx );
1263
                                        ptr = getCoord( ptr, ry );
1264
                                        ptr = getCoord( ptr, angle );
1265
                                        ptr = getCoord( ptr, tox );
1266
                                        largeArc = tox == 1;
1267
                                        ptr = getCoord( ptr, tox );
1268
                                        sweep = tox == 1;
1269
                                        ptr = getCoord( ptr, tox );
1270
                                        ptr = getCoord( ptr, toy );
1271
                                        calculateArc(ite, relative, curx, cury, angle, tox, toy, rx, ry, largeArc, sweep );
1272
                                }
1273
                        }
1274
                        lastCommand = command;
1275
                        if(*ptr == '+' || *ptr == '-' || (*ptr >= '0' && *ptr <= '9'))
1276
                        {
1277
                                // there are still coords in this command
1278
                                if(command == 'M')
1279
                                        command = 'L';
1280
                                else if(command == 'm')
1281
                                        command = 'l';
1282
                        }
1283
                        else
1284
                                command = *(ptr++);
1285
 
1286
                        if( lastCommand != 'C' && lastCommand != 'c' &&
1287
                                lastCommand != 'S' && lastCommand != 's' &&
1288
                                lastCommand != 'Q' && lastCommand != 'q' &&
1289
                                lastCommand != 'T' && lastCommand != 't')
1290
                        {
1291
                                contrlx = curx;
1292
                                contrly = cury;
1293
                        }
1294
                }
1295
                if ((lastCommand != 'z') && (lastCommand != 'Z'))
1296
                        ret = true;
1297
                if (ite->size() > 2)
1298
                {
1299
                        if ((ite->point(0).x() == ite->point(ite->size()-2).x()) && (ite->point(0).y() == ite->point(ite->size()-2).y()))
1300
                                ret = false;
1301
                }
1302
        }
1303
        return ret;
1304
}
1305
 
544 fschmid 1306
void OODPlug::calculateArc(FPointArray *ite, bool relative, double &curx, double &cury, double angle, double x, double y, double r1, double r2, bool largeArcFlag, bool sweepFlag)
541 fschmid 1307
{
1308
        double sin_th, cos_th;
1309
        double a00, a01, a10, a11;
1310
        double x0, y0, x1, y1, xc, yc;
1311
        double d, sfactor, sfactor_sq;
1312
        double th0, th1, th_arc;
1313
        int i, n_segs;
1314
        sin_th = sin(angle * (M_PI / 180.0));
1315
        cos_th = cos(angle * (M_PI / 180.0));
1316
        double dx;
1317
        if(!relative)
1318
                dx = (curx - x) / 2.0;
1319
        else
1320
                dx = -x / 2.0;
1321
        double dy;
1322
        if(!relative)
1323
                dy = (cury - y) / 2.0;
1324
        else
1325
                dy = -y / 2.0;
1326
        double _x1 =  cos_th * dx + sin_th * dy;
1327
        double _y1 = -sin_th * dx + cos_th * dy;
1328
        double Pr1 = r1 * r1;
1329
        double Pr2 = r2 * r2;
1330
        double Px = _x1 * _x1;
1331
        double Py = _y1 * _y1;
1332
        double check = Px / Pr1 + Py / Pr2;
1333
        if(check > 1)
1334
        {
1335
                r1 = r1 * sqrt(check);
1336
                r2 = r2 * sqrt(check);
1337
        }
1338
        a00 = cos_th / r1;
1339
        a01 = sin_th / r1;
1340
        a10 = -sin_th / r2;
1341
        a11 = cos_th / r2;
1342
        x0 = a00 * curx + a01 * cury;
1343
        y0 = a10 * curx + a11 * cury;
1344
        if(!relative)
1345
                x1 = a00 * x + a01 * y;
1346
        else
1347
                x1 = a00 * (curx + x) + a01 * (cury + y);
1348
        if(!relative)
1349
                y1 = a10 * x + a11 * y;
1350
        else
1351
                y1 = a10 * (curx + x) + a11 * (cury + y);
1352
        d = (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
1353
        sfactor_sq = 1.0 / d - 0.25;
1354
        if(sfactor_sq < 0)
1355
                sfactor_sq = 0;
1356
        sfactor = sqrt(sfactor_sq);
1357
        if(sweepFlag == largeArcFlag)
1358
                sfactor = -sfactor;
1359
        xc = 0.5 * (x0 + x1) - sfactor * (y1 - y0);
1360
        yc = 0.5 * (y0 + y1) + sfactor * (x1 - x0);
1361
 
1362
        th0 = atan2(y0 - yc, x0 - xc);
1363
        th1 = atan2(y1 - yc, x1 - xc);
1364
        th_arc = th1 - th0;
1365
        if(th_arc < 0 && sweepFlag)
1366
                th_arc += 2 * M_PI;
1367
        else if(th_arc > 0 && !sweepFlag)
1368
                th_arc -= 2 * M_PI;
1369
        n_segs = static_cast<int>(ceil(fabs(th_arc / (M_PI * 0.5 + 0.001))));
1370
        for(i = 0; i < n_segs; i++)
1371
        {
1372
                {
1373
                        double sin_th, cos_th;
1374
                        double a00, a01, a10, a11;
1375
                        double x1, y1, x2, y2, x3, y3;
1376
                        double t;
1377
                        double th_half;
1378
                        double _th0 = th0 + i * th_arc / n_segs;
1379
                        double _th1 = th0 + (i + 1) * th_arc / n_segs;
1380
                        sin_th = sin(angle * (M_PI / 180.0));
1381
                        cos_th = cos(angle * (M_PI / 180.0));
1382
                        a00 = cos_th * r1;
1383
                        a01 = -sin_th * r2;
1384
                        a10 = sin_th * r1;
1385
                        a11 = cos_th * r2;
1386
                        th_half = 0.5 * (_th1 - _th0);
1387
                        t = (8.0 / 3.0) * sin(th_half * 0.5) * sin(th_half * 0.5) / sin(th_half);
1388
                        x1 = xc + cos(_th0) - t * sin(_th0);
1389
                        y1 = yc + sin(_th0) + t * cos(_th0);
1390
                        x3 = xc + cos(_th1);
1391
                        y3 = yc + sin(_th1);
1392
                        x2 = x3 + t * sin(_th1);
1393
                        y2 = y3 - t * cos(_th1);
1394
                        svgCurveToCubic(ite, a00 * x1 + a01 * y1, a10 * x1 + a11 * y1, a00 * x2 + a01 * y2, a10 * x2 + a11 * y2, a00 * x3 + a01 * y3, a10 * x3 + a11 * y3 );
1395
                }
1396
        }
1397
        if(!relative)
1398
                curx = x;
1399
        else
1400
                curx += x;
1401
        if(!relative)
1402
                cury = y;
1403
        else
1404
                cury += y;
1405
}
1406
 
544 fschmid 1407
void OODPlug::svgMoveTo(double x1, double y1)
541 fschmid 1408
{
1409
        CurrX = x1;
1410
        CurrY = y1;
1411
        StartX = x1;
1412
        StartY = y1;
1413
        PathLen = 0;
1414
}
1415
 
544 fschmid 1416
void OODPlug::svgLineTo(FPointArray *i, double x1, double y1)
541 fschmid 1417
{
1418
        if ((!FirstM) && (WasM))
1419
        {
1420
                i->setMarker();
1421
                PathLen += 4;
1422
        }
1423
        FirstM = false;
1424
        WasM = false;
1425
        if (i->size() > 3)
1426
        {
1427
                FPoint b1 = i->point(i->size()-4);
1428
                FPoint b2 = i->point(i->size()-3);
1429
                FPoint b3 = i->point(i->size()-2);
1430
                FPoint b4 = i->point(i->size()-1);
1431
                FPoint n1 = FPoint(CurrX, CurrY);
1432
                FPoint n2 = FPoint(x1, y1);
1433
                if ((b1 == n1) && (b2 == n1) && (b3 == n2) && (b4 == n2))
1434
                        return;
1435
        }
1436
        i->addPoint(FPoint(CurrX, CurrY));
1437
        i->addPoint(FPoint(CurrX, CurrY));
1438
        i->addPoint(FPoint(x1, y1));
1439
        i->addPoint(FPoint(x1, y1));
1440
        CurrX = x1;
1441
        CurrY = y1;
1442
        PathLen += 4;
1443
}
1444
 
544 fschmid 1445
void OODPlug::svgCurveToCubic(FPointArray *i, double x1, double y1, double x2, double y2, double x3, double y3)
541 fschmid 1446
{
1447
        if ((!FirstM) && (WasM))
1448
        {
1449
                i->setMarker();
1450
                PathLen += 4;
1451
        }
1452
        FirstM = false;
1453
        WasM = false;
1454
        if (PathLen > 3)
1455
        {
1456
                FPoint b1 = i->point(i->size()-4);
1457
                FPoint b2 = i->point(i->size()-3);
1458
                FPoint b3 = i->point(i->size()-2);
1459
                FPoint b4 = i->point(i->size()-1);
1460
                FPoint n1 = FPoint(CurrX, CurrY);
1461
                FPoint n2 = FPoint(x1, y1);
1462
                FPoint n3 = FPoint(x3, y3);
1463
                FPoint n4 = FPoint(x2, y2);
1464
                if ((b1 == n1) && (b2 == n2) && (b3 == n3) && (b4 == n4))
1465
                        return;
1466
        }
1467
        i->addPoint(FPoint(CurrX, CurrY));
1468
        i->addPoint(FPoint(x1, y1));
1469
        i->addPoint(FPoint(x3, y3));
1470
        i->addPoint(FPoint(x2, y2));
1471
        CurrX = x3;
1472
        CurrY = y3;
1473
        PathLen += 4;
1474
}
1475
 
544 fschmid 1476
void OODPlug::svgClosePath(FPointArray *i)
541 fschmid 1477
{
1478
        if (PathLen > 2)
1479
        {
1480
                if ((PathLen == 4) || (i->point(i->size()-2).x() != StartX) || (i->point(i->size()-2).y() != StartY))
1481
                {
1482
                        i->addPoint(i->point(i->size()-2));
1483
                        i->addPoint(i->point(i->size()-3));
1484
                        i->addPoint(FPoint(StartX, StartY));
1485
                        i->addPoint(FPoint(StartX, StartY));
1486
                }
1487
        }
1488
}
1489
 
544 fschmid 1490
OODPlug::~OODPlug()
1491
{}
541 fschmid 1492