Subversion Repositories Scribus

Rev

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

Rev Author Line No. Line
16682 jghali 1
/*
2
For general Scribus (>=1.3.2) copyright and licensing information please refer
3
to the COPYING file provided with the program. Following this notice may exist
4
a copyright and/or license notice that predates the release of Scribus 1.3.2
5
for which a new license (GPL+exception) is in place.
6
*/
7
 
8
#include <QByteArray>
9
#include <QCursor>
10
#include <QDrag>
11
#include <QFile>
12
#include <QList>
13
#include <QMimeData>
14
#include <QRegExp>
15
#include <QStack>
16
#include <QDebug>
17
 
18
#include <cstdlib>
19
 
20
#include "commonstrings.h"
21
#include "importxfig.h"
22
#include "loadsaveplugin.h"
23
#include "pagesize.h"
24
#include "pageitem.h"
25
#include "prefscontext.h"
26
#include "prefsfile.h"
27
#include "prefsmanager.h"
28
#include "prefstable.h"
29
#include "rawimage.h"
30
#include "scclocale.h"
31
#include "sccolorengine.h"
32
#include "scconfig.h"
33
#include "scmimedata.h"
34
#include "scpaths.h"
35
#include "scpattern.h"
36
#include "scribus.h"
37
#include "scribusXml.h"
38
#include "scribuscore.h"
39
#include "sctextstream.h"
40
#include "selection.h"
41
#include "ui/customfdialog.h"
42
#include "ui/missing.h"
43
#include "ui/multiprogressdialog.h"
44
#include "ui/propertiespalette.h"
45
#include "undomanager.h"
46
#include "util.h"
47
#include "util_formats.h"
48
#include "util_icon.h"
49
#include "util_math.h"
50
 
51
extern SCRIBUS_API ScribusQApp * ScQApp;
52
 
53
XfigPlug::XfigPlug(ScribusDoc* doc, int flags)
54
{
55
        tmpSel=new Selection(this, false);
56
        m_Doc=doc;
57
        importerFlags = flags;
58
        interactive = (flags & LoadSavePlugin::lfInteractive);
16772 fschmid 59
        progressDialog = NULL;
16682 jghali 60
}
61
 
62
QImage XfigPlug::readThumbnail(QString fName)
63
{
64
        QFileInfo fi = QFileInfo(fName);
65
        baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
66
        double b, h, x, y;
67
        parseHeader(fName, x, y, b, h);
68
        docX = x;
69
        docY = y;
70
        if (b == 0.0)
71
                b = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
72
        if (h == 0.0)
73
                h = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
74
        docWidth = b - x;
75
        docHeight = h - y;
76
        progressDialog = NULL;
77
        m_Doc = new ScribusDoc();
78
        m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
79
        m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
80
        m_Doc->addPage(0);
81
        m_Doc->setGUI(false, ScCore->primaryMainWindow(), 0);
82
        baseX = m_Doc->currentPage()->xOffset();
83
        baseY = m_Doc->currentPage()->yOffset();
84
        Elements.clear();
85
        CustColors.clear();
86
        importedColors.insert(0, "Black");
87
        importedColors.insert(1, "Blue");
88
        importedColors.insert(2, "Green");
89
        importedColors.insert(3, "Cyan");
90
        importedColors.insert(4, "Red");
91
        importedColors.insert(5, "Magenta");
92
        importedColors.insert(6, "Yellow");
93
        importedColors.insert(7, "White");
94
        importedColors.insert(8, "Blue4");
95
        importedColors.insert(9, "Blue3");
96
        importedColors.insert(10, "Blue2");
97
        importedColors.insert(11, "LtBlue");
98
        importedColors.insert(12, "Green4");
99
        importedColors.insert(13, "Green3");
100
        importedColors.insert(14, "Green2");
101
        importedColors.insert(15, "Cyan4");
102
        importedColors.insert(16, "Cyan3");
103
        importedColors.insert(17, "Cyan2");
104
        importedColors.insert(18, "Red4");
105
        importedColors.insert(19, "Red3");
106
        importedColors.insert(20, "Red2");
107
        importedColors.insert(21, "Magenta4");
108
        importedColors.insert(22, "Magenta3");
109
        importedColors.insert(23, "Magenta2");
110
        importedColors.insert(24, "Brown4");
111
        importedColors.insert(25, "Brown3");
112
        importedColors.insert(26, "Brown2");
113
        importedColors.insert(27, "Pink4");
114
        importedColors.insert(28, "Pink3");
115
        importedColors.insert(29, "Pink2");
116
        importedColors.insert(30, "Pink");
117
        importedColors.insert(31, "Gold");
118
        CustColors.insert("Blue", ScColor(0, 0, 255));
119
        CustColors.insert("Blue4", ScColor(0, 0, 144));
120
        CustColors.insert("Blue3", ScColor(0, 0, 176));
121
        CustColors.insert("Blue2", ScColor(0, 0, 208));
122
        CustColors.insert("LtBlue", ScColor(135, 206, 255));
123
        CustColors.insert("Cyan", ScColor(255, 0, 0, 0));
124
        CustColors.insert("Cyan4", ScColor(0, 144, 144));
125
        CustColors.insert("Cyan3", ScColor(0, 176, 176));
126
        CustColors.insert("Cyan2", ScColor(0, 208, 208));
127
        CustColors.insert("Green", ScColor(255, 0, 255, 0));
128
        CustColors.insert("Green4", ScColor(0, 144, 0));
129
        CustColors.insert("Green3", ScColor(0, 176, 0));
130
        CustColors.insert("Green2", ScColor(0, 208, 0));
131
        CustColors.insert("Red", ScColor(0, 255, 255, 0));
132
        CustColors.insert("Red4", ScColor(144, 0, 0));
133
        CustColors.insert("Red3", ScColor(176, 0, 0));
134
        CustColors.insert("Red2", ScColor(208, 0, 0));
135
        CustColors.insert("Yellow", ScColor(0, 0, 255, 0));
136
        CustColors.insert("Magenta", ScColor(0, 255, 0, 0));
137
        CustColors.insert("Magenta4", ScColor(144, 0, 144));
138
        CustColors.insert("Magenta3", ScColor(176, 0, 176));
139
        CustColors.insert("Magenta2", ScColor(208, 0, 208));
140
        CustColors.insert("Brown4", ScColor(128, 48, 0));
141
        CustColors.insert("Brown3", ScColor(160, 64, 0));
142
        CustColors.insert("Brown2", ScColor(192, 96, 0));
143
        CustColors.insert("Pink4", ScColor(255, 128, 128));
144
        CustColors.insert("Pink3", ScColor(255, 160, 160));
145
        CustColors.insert("Pink2", ScColor(255, 192, 192));
146
        CustColors.insert("Pink", ScColor(255, 224, 224));
147
        CustColors.insert("Gold", ScColor(255, 215, 0));
148
        m_Doc->setLoading(true);
149
        m_Doc->DoDrawing = false;
150
        m_Doc->scMW()->setScriptRunning(true);
151
        QString CurDirP = QDir::currentPath();
152
        QDir::setCurrent(fi.path());
153
        if (convert(fName))
154
        {
155
                tmpSel->clear();
156
                QDir::setCurrent(CurDirP);
157
                if (Elements.count() > 1)
158
                        m_Doc->groupObjectsList(Elements);
159
                m_Doc->DoDrawing = true;
160
                m_Doc->m_Selection->delaySignalsOn();
161
                QImage tmpImage;
162
                if (Elements.count() > 0)
163
                {
164
                        for (int dre=0; dre<Elements.count(); ++dre)
165
                        {
166
                                tmpSel->addItem(Elements.at(dre), true);
167
                        }
168
                        tmpSel->setGroupRect();
169
                        double xs = tmpSel->width();
170
                        double ys = tmpSel->height();
171
                        tmpImage = Elements.at(0)->DrawObj_toImage(500);
172
                        tmpImage.setText("XSize", QString("%1").arg(xs));
173
                        tmpImage.setText("YSize", QString("%1").arg(ys));
174
                }
175
                m_Doc->scMW()->setScriptRunning(false);
176
                m_Doc->setLoading(false);
177
                m_Doc->m_Selection->delaySignalsOff();
178
                delete m_Doc;
179
                return tmpImage;
180
        }
181
        else
182
        {
183
                QDir::setCurrent(CurDirP);
184
                m_Doc->DoDrawing = true;
185
                m_Doc->scMW()->setScriptRunning(false);
186
                delete m_Doc;
187
        }
188
        return QImage();
189
}
190
 
191
bool XfigPlug::import(QString fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
192
{
193
        QString fName = fNameIn;
194
        bool success = false;
195
        interactive = (flags & LoadSavePlugin::lfInteractive);
196
        importerFlags = flags;
197
        cancel = false;
198
        double x, y, b, h;
199
        bool ret = false;
200
        CustColors.clear();
201
        importedColors.insert(0, "Black");
202
        importedColors.insert(1, "Blue");
203
        importedColors.insert(2, "Green");
204
        importedColors.insert(3, "Cyan");
205
        importedColors.insert(4, "Red");
206
        importedColors.insert(5, "Magenta");
207
        importedColors.insert(6, "Yellow");
208
        importedColors.insert(7, "White");
209
        importedColors.insert(8, "Blue4");
210
        importedColors.insert(9, "Blue3");
211
        importedColors.insert(10, "Blue2");
212
        importedColors.insert(11, "LtBlue");
213
        importedColors.insert(12, "Green4");
214
        importedColors.insert(13, "Green3");
215
        importedColors.insert(14, "Green2");
216
        importedColors.insert(15, "Cyan4");
217
        importedColors.insert(16, "Cyan3");
218
        importedColors.insert(17, "Cyan2");
219
        importedColors.insert(18, "Red4");
220
        importedColors.insert(19, "Red3");
221
        importedColors.insert(20, "Red2");
222
        importedColors.insert(21, "Magenta4");
223
        importedColors.insert(22, "Magenta3");
224
        importedColors.insert(23, "Magenta2");
225
        importedColors.insert(24, "Brown4");
226
        importedColors.insert(25, "Brown3");
227
        importedColors.insert(26, "Brown2");
228
        importedColors.insert(27, "Pink4");
229
        importedColors.insert(28, "Pink3");
230
        importedColors.insert(29, "Pink2");
231
        importedColors.insert(30, "Pink");
232
        importedColors.insert(31, "Gold");
233
        CustColors.insert("Blue", ScColor(0, 0, 255));
234
        CustColors.insert("Blue4", ScColor(0, 0, 144));
235
        CustColors.insert("Blue3", ScColor(0, 0, 176));
236
        CustColors.insert("Blue2", ScColor(0, 0, 208));
237
        CustColors.insert("LtBlue", ScColor(135, 206, 255));
238
        CustColors.insert("Cyan", ScColor(255, 0, 0, 0));
239
        CustColors.insert("Cyan4", ScColor(0, 144, 144));
240
        CustColors.insert("Cyan3", ScColor(0, 176, 176));
241
        CustColors.insert("Cyan2", ScColor(0, 208, 208));
242
        CustColors.insert("Green", ScColor(255, 0, 255, 0));
243
        CustColors.insert("Green4", ScColor(0, 144, 0));
244
        CustColors.insert("Green3", ScColor(0, 176, 0));
245
        CustColors.insert("Green2", ScColor(0, 208, 0));
246
        CustColors.insert("Red", ScColor(0, 255, 255, 0));
247
        CustColors.insert("Red4", ScColor(144, 0, 0));
248
        CustColors.insert("Red3", ScColor(176, 0, 0));
249
        CustColors.insert("Red2", ScColor(208, 0, 0));
250
        CustColors.insert("Yellow", ScColor(0, 0, 255, 0));
251
        CustColors.insert("Magenta", ScColor(0, 255, 0, 0));
252
        CustColors.insert("Magenta4", ScColor(144, 0, 144));
253
        CustColors.insert("Magenta3", ScColor(176, 0, 176));
254
        CustColors.insert("Magenta2", ScColor(208, 0, 208));
255
        CustColors.insert("Brown4", ScColor(128, 48, 0));
256
        CustColors.insert("Brown3", ScColor(160, 64, 0));
257
        CustColors.insert("Brown2", ScColor(192, 96, 0));
258
        CustColors.insert("Pink4", ScColor(255, 128, 128));
259
        CustColors.insert("Pink3", ScColor(255, 160, 160));
260
        CustColors.insert("Pink2", ScColor(255, 192, 192));
261
        CustColors.insert("Pink", ScColor(255, 224, 224));
262
        CustColors.insert("Gold", ScColor(255, 215, 0));
263
        QFileInfo fi = QFileInfo(fName);
264
        if ( !ScCore->usingGUI() )
265
        {
266
                interactive = false;
267
                showProgress = false;
268
        }
269
        baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
270
        if ( showProgress )
271
        {
272
                ScribusMainWindow* mw=(m_Doc==0) ? ScCore->primaryMainWindow() : m_Doc->scMW();
273
                progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
274
                QStringList barNames, barTexts;
275
                barNames << "GI";
276
                barTexts << tr("Analyzing File:");
277
                QList<bool> barsNumeric;
278
                barsNumeric << false;
279
                progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
280
                progressDialog->setOverallTotalSteps(3);
281
                progressDialog->setOverallProgress(0);
282
                progressDialog->setProgress("GI", 0);
283
                progressDialog->show();
284
                connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
285
                qApp->processEvents();
286
        }
287
        else
288
                progressDialog = NULL;
289
/* Set default Page to size defined in Preferences */
290
        x = 0.0;
291
        y = 0.0;
292
        b = 0.0;
293
        h = 0.0;
294
        if (progressDialog)
295
        {
296
                progressDialog->setOverallProgress(1);
297
                qApp->processEvents();
298
        }
299
        parseHeader(fName, x, y, b, h);
300
        docX = x;
301
        docY = y;
302
        if (b == 0.0)
303
                b = PrefsManager::instance()->appPrefs.docSetupPrefs.pageWidth;
304
        if (h == 0.0)
305
                h = PrefsManager::instance()->appPrefs.docSetupPrefs.pageHeight;
306
        docWidth = b - x;
307
        docHeight = h - y;
308
        baseX = 0;
309
        baseY = 0;
310
        if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
311
        {
312
                m_Doc->setPage(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false);
313
                m_Doc->addPage(0);
314
                m_Doc->view()->addPage(0, true);
315
                baseX = 0;
316
                baseY = 0;
317
        }
318
        else
319
        {
320
                if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
321
                {
322
                        m_Doc=ScCore->primaryMainWindow()->doFileNew(b-x, h-y, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
323
                        ScCore->primaryMainWindow()->HaveNewDoc();
324
                        ret = true;
325
                        baseX = 0;
326
                        baseY = 0;
327
                }
328
        }
329
        if (flags & LoadSavePlugin::lfCreateDoc)
330
        {
331
                m_Doc->documentInfo().setAuthor(docCreator);
332
                m_Doc->documentInfo().setPublisher(docOrganisation);
333
                m_Doc->documentInfo().setTitle(docTitle);
334
                m_Doc->documentInfo().setDate(docDate+" "+docTime);
335
        }
336
        if ((!ret) && (interactive))
337
        {
338
                baseX = m_Doc->currentPage()->xOffset();
339
                baseY = m_Doc->currentPage()->yOffset();
340
        }
341
        if ((ret) || (!interactive))
342
        {
343
                if (b-x > h-y)
344
                        m_Doc->setPageOrientation(1);
345
                else
346
                        m_Doc->setPageOrientation(0);
347
                m_Doc->setPageSize("Custom");
348
        }
16645 jghali 349
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
16682 jghali 350
                m_Doc->view()->Deselect();
351
        Elements.clear();
352
        m_Doc->setLoading(true);
353
        m_Doc->DoDrawing = false;
354
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
355
                m_Doc->view()->updatesOn(false);
356
        m_Doc->scMW()->setScriptRunning(true);
18181 fschmid 357
        qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
16682 jghali 358
        QString CurDirP = QDir::currentPath();
359
        QDir::setCurrent(fi.path());
360
        if (convert(fName))
361
        {
362
                tmpSel->clear();
363
                QDir::setCurrent(CurDirP);
364
                if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
365
                        m_Doc->groupObjectsList(Elements);
366
                m_Doc->DoDrawing = true;
367
                m_Doc->scMW()->setScriptRunning(false);
368
                m_Doc->setLoading(false);
369
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
370
                if ((Elements.count() > 0) && (!ret) && (interactive))
371
                {
372
                        if (flags & LoadSavePlugin::lfScripted)
373
                        {
374
                                bool loadF = m_Doc->isLoading();
375
                                m_Doc->setLoading(false);
376
                                m_Doc->changed();
377
                                m_Doc->setLoading(loadF);
378
                                if (!(flags & LoadSavePlugin::lfLoadAsPattern))
379
                                {
380
                                        m_Doc->m_Selection->delaySignalsOn();
381
                                        for (int dre=0; dre<Elements.count(); ++dre)
382
                                        {
383
                                                m_Doc->m_Selection->addItem(Elements.at(dre), true);
384
                                        }
385
                                        m_Doc->m_Selection->delaySignalsOff();
386
                                        m_Doc->m_Selection->setGroupRect();
387
                                        m_Doc->view()->updatesOn(true);
388
                                }
389
                        }
390
                        else
391
                        {
392
                                m_Doc->DragP = true;
393
                                m_Doc->DraggedElem = 0;
394
                                m_Doc->DragElements.clear();
395
                                m_Doc->m_Selection->delaySignalsOn();
396
                                for (int dre=0; dre<Elements.count(); ++dre)
397
                                {
398
                                        tmpSel->addItem(Elements.at(dre), true);
399
                                }
400
                                tmpSel->setGroupRect();
18028 jghali 401
                                ScElemMimeData* md = ScriXmlDoc::WriteToMimeData(m_Doc, tmpSel);
16682 jghali 402
                                m_Doc->itemSelection_DeleteItem(tmpSel);
403
                                m_Doc->view()->updatesOn(true);
404
                                m_Doc->m_Selection->delaySignalsOff();
405
                                // We must copy the TransationSettings object as it is owned
406
                                // by handleObjectImport method afterwards
407
                                TransactionSettings* transacSettings = new TransactionSettings(trSettings);
408
                                m_Doc->view()->handleObjectImport(md, transacSettings);
409
                                m_Doc->DragP = false;
410
                                m_Doc->DraggedElem = 0;
411
                                m_Doc->DragElements.clear();
412
                        }
413
                }
414
                else
415
                {
416
                        m_Doc->changed();
417
                        m_Doc->reformPages();
418
                        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
419
                                m_Doc->view()->updatesOn(true);
420
                }
421
                success = true;
422
        }
423
        else
424
        {
425
                QDir::setCurrent(CurDirP);
426
                m_Doc->DoDrawing = true;
427
                m_Doc->scMW()->setScriptRunning(false);
428
                m_Doc->view()->updatesOn(true);
429
                qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
430
        }
431
        if (interactive)
432
                m_Doc->setLoading(false);
433
        //CB If we have a gui we must refresh it if we have used the progressbar
434
        if (!(flags & LoadSavePlugin::lfLoadAsPattern))
435
        {
436
                if ((showProgress) && (!interactive))
437
                        m_Doc->view()->DrawNew();
438
        }
18181 fschmid 439
        qApp->restoreOverrideCursor();
16682 jghali 440
        return success;
441
}
442
 
443
XfigPlug::~XfigPlug()
444
{
445
        if (progressDialog)
446
                delete progressDialog;
447
        delete tmpSel;
448
}
449
 
450
bool XfigPlug::parseHeader(QString fName, double &x, double &y, double &b, double &h)
451
{
452
        QString tmp, BBox, tmp2, FarNam;
453
        ScColor cc;
454
        bool found = false;
455
        QFile f(fName);
456
        if (f.open(QIODevice::ReadOnly))
457
        {
458
                QDataStream ts(&f);
459
                QString version = readLinefromDataStream(ts);
460
                if (!version.startsWith("#FIG 3"))
461
                {
462
                        f.close();
463
                        return false;
464
                }
465
                QString orientation = readLinefromDataStream(ts);
466
                QString justification = readLinefromDataStream(ts);
467
                QString units = readLinefromDataStream(ts);
468
                QString papersize = readLinefromDataStream(ts);
469
                PageSize ps(papersize);
470
                if (orientation.startsWith("Landscape"))
471
                {
472
                        h = ps.width();
473
                        b = ps.height();
474
                }
475
                else
476
                {
477
                        b = ps.width();
478
                        h = ps.height();
479
                }
480
                f.close();
481
                found = true;
482
        }
483
        return found;
484
}
485
 
486
void XfigPlug::parseColor(QString data)
487
{
488
        if (data.isEmpty())
489
                return;
490
        int colorNum, dummy;
491
        QString colorValues;
492
        ScColor tmp;
493
        ScTextStream Code(&data, QIODevice::ReadOnly);
494
        Code >> dummy >> colorNum >> colorValues;
495
        tmp.setNamedColor(colorValues);
496
        tmp.setSpotColor(false);
497
        tmp.setRegistrationColor(false);
498
        QString namPrefix = "FromXfig%1-"+colorValues;
499
        CustColors.insert(namPrefix.arg(colorNum), tmp);
500
        importedColors.insert(colorNum, namPrefix.arg(colorNum));
501
}
502
 
503
void XfigPlug::useColor(int colorNum, int area_fill, bool forFill)
504
{
505
        QString color = CommonStrings::None;
506
        int shade = 100;
507
        if (forFill)
508
        {
509
                if (area_fill == -1)
510
                        color = CommonStrings::None;
511
                else
512
                {
513
                        if ((colorNum == -1) || (colorNum == 0))
514
                        {
515
                                if (area_fill == 0)
516
                                {
517
                                        color = "White";
518
                                        shade = 100;
519
                                }
520
                                else if (area_fill == 20)
521
                                {
522
                                        color = "Black";
523
                                        shade = 100;
524
                                }
525
                                else if ((area_fill > 0) && (area_fill < 20))
526
                                {
527
                                        color = "Black";
528
                                        shade = qRound(100.0 / 19.0 * area_fill);
529
                                }
530
                        }
531
                        else if (colorNum == 7)
532
                        {
533
                                if (area_fill == 0)
534
                                {
535
                                        color = "Black";
536
                                        shade = 100;
537
                                }
538
                                else if (area_fill == 20)
539
                                {
540
                                        color = "White";
541
                                        shade = 100;
542
                                }
543
                                else if ((area_fill > 0) && (area_fill < 20))
544
                                {
545
                                        color = "Black";
546
                                        shade = qRound(100.0 / 19.0 * (20 - area_fill));
547
                                }
548
                        }
549
                        else
550
                        {
551
                                if (importedColors.contains(colorNum))
552
                                {
553
                                        color = importedColors[colorNum];
554
                                        if (!m_Doc->PageColors.contains(color))
555
                                                m_Doc->PageColors.insert(color, CustColors[color]);
556
                                        int sat = area_fill - 20;
557
                                        if ((sat > 0) && (sat < 20))
558
                                                shade = qRound(100.0 / 19.0 * sat);
559
                                }
560
                                else
561
                                        color = CommonStrings::None;
562
                        }
563
                }
564
                CurrColorFill = color;
565
                CurrFillShade = shade;
566
        }
567
        else
568
        {
569
                if (area_fill == -1)
570
                        CurrColorStroke = CommonStrings::None;
571
                else
572
                {
573
                        if ((colorNum == -1) || (colorNum == 0))
574
                                CurrColorStroke = "Black";
575
                        else
576
                        {
577
                                if (importedColors.contains(colorNum))
578
                                {
579
                                        CurrColorStroke = importedColors[colorNum];
580
                                        if (!m_Doc->PageColors.contains(CurrColorStroke))
581
                                                m_Doc->PageColors.insert(CurrColorStroke, CustColors[CurrColorStroke]);
582
                                }
583
                                else
584
                                        CurrColorStroke = CommonStrings::None;
585
                        }
586
                }
587
        }
588
}
589
 
590
QVector<double> XfigPlug::getDashValues(double linewidth, int code)
591
{
592
        QVector<double> tmp;
593
        if (code == 1)
594
        {
595
                tmp << qMax(4.0 * linewidth, 0.1);
596
                tmp << qMax(2.0 * linewidth, 0.1);
597
        }
598
        else if (code == 2)
599
        {
600
                tmp << qMax(1.0 * linewidth, 0.1);
601
                tmp << qMax(2.0 * linewidth, 0.1);
602
        }
603
        else if (code == 3)
604
        {
605
                tmp << qMax(4.0 * linewidth, 0.1);
606
                tmp << qMax(2.0 * linewidth, 0.1);
607
                tmp << qMax(1.0 * linewidth, 0.1);
608
                tmp << qMax(2.0 * linewidth, 0.1);
609
        }
610
        else if (code == 4)
611
        {
612
                tmp << qMax(4.0 * linewidth, 0.1);
613
                tmp << qMax(2.0 * linewidth, 0.1);
614
                tmp << qMax(1.0 * linewidth, 0.1);
615
                tmp << qMax(2.0 * linewidth, 0.1);
616
                tmp << qMax(1.0 * linewidth, 0.1);
617
                tmp << qMax(2.0 * linewidth, 0.1);
618
        }
619
        else if (code == 5)
620
        {
621
                tmp << qMax(4.0 * linewidth, 0.1);
622
                tmp << qMax(2.0 * linewidth, 0.1);
623
                tmp << qMax(1.0 * linewidth, 0.1);
624
                tmp << qMax(2.0 * linewidth, 0.1);
625
                tmp << qMax(1.0 * linewidth, 0.1);
626
                tmp << qMax(2.0 * linewidth, 0.1);
627
                tmp << qMax(1.0 * linewidth, 0.1);
628
                tmp << qMax(2.0 * linewidth, 0.1);
629
        }
630
        return tmp;
631
}
632
 
633
void XfigPlug::processArrows(int forward_arrow, QString fArrowData, int backward_arrow, QString bArrowData, int depth, PageItem *ite)
634
{
635
        int             arrow_typeAF;                   // (enumeration type)
636
        int             arrow_styleAF;                  // (enumeration type)
637
        float   arrow_thicknessAF;              // (1/80 inch)
638
        float   arrow_widthAF;                  // (Fig units)
639
        float   arrow_heightAF;                 // (Fig units)
640
        int             arrow_typeAB;                   // (enumeration type)
641
        int             arrow_styleAB;                  // (enumeration type)
642
        float   arrow_thicknessAB;              // (1/80 inch)
643
        float   arrow_widthAB;                  // (Fig units)
644
        float   arrow_heightAB;                 // (Fig units)
645
        FPointArray arrow;
646
        int z = -1;
647
        PageItem::ItemType iteType;
648
        if (forward_arrow == 1)
649
        {
650
                arrow.resize(0);
651
                ScTextStream CodeAF(&fArrowData, QIODevice::ReadOnly);
652
                CodeAF >> arrow_typeAF >> arrow_styleAF >> arrow_thicknessAF >> arrow_widthAF >> arrow_heightAF;
653
                arrow_widthAF = fig2Pts(arrow_widthAF);
654
                arrow_heightAF = fig2Pts(arrow_heightAF);
655
                arrow_thicknessAF = arrow_thicknessAF / 80.0 * 72.0;
656
                FPoint End = ite->PoLine.point(ite->PoLine.size()-2);
657
                for (uint xx = ite->PoLine.size()-1; xx > 0; xx -= 2)
658
                {
659
                        FPoint Vector = ite->PoLine.point(xx);
660
                        if ((End.x() != Vector.x()) || (End.y() != Vector.y()))
661
                        {
662
                                double r = atan2(End.y()-Vector.y(),End.x()-Vector.x())*(180.0/M_PI);
663
                                QTransform arrowTrans;
664
                                if (arrow_typeAF == 0)
665
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5");
666
                                else if (arrow_typeAF == 1)
667
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 z");
668
                                else if (arrow_typeAF == 2)
669
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 L -0.7 0 z");
670
                                else if (arrow_typeAF == 3)
671
                                        arrow.parseSVG("M -0.7, -0.5 L 0, 0 L -0.7, 0.5 L -1 0 z");
672
                                arrowTrans.translate(End.x(), End.y());
673
                                arrowTrans.rotate(r);
674
                                arrowTrans.scale(arrow_heightAF, arrow_widthAF);
675
                                arrow.map(arrowTrans);
676
                                break;
677
                        }
678
                }
679
                QString fillC = "White";
680
                if (arrow_styleAF == 1)
681
                        fillC = CurrColorStroke;
682
                if (arrow_typeAF == 0)
683
                {
684
                        fillC = CommonStrings::None;
685
                        iteType = PageItem::PolyLine;
686
                }
687
                else
688
                        iteType = PageItem::Polygon;
689
                z = m_Doc->itemAdd(iteType, PageItem::Unspecified, ite->xPos(), ite->yPos(), 10, 10, arrow_thicknessAF, fillC, CurrColorStroke, true);
690
                if (z >= 0)
691
                {
692
                        PageItem *item = m_Doc->Items->at(z);
693
                        item->PoLine = arrow.copy();
694
                        item->ClipEdited = true;
695
                        item->FrameType = 3;
696
                        item->setFillShade(CurrFillShade);
697
                        item->setLineShade(CurrStrokeShade);
698
                        FPoint wh = getMaxClipF(&item->PoLine);
699
                        item->setWidthHeight(wh.x(),wh.y());
700
                        item->setTextFlowMode(PageItem::TextFlowDisabled);
701
                        m_Doc->AdjustItemSize(item);
702
                        item->setWidthHeight(qMax(item->width(), 1.0), qMax(item->height(), 1.0));
703
                        depthMap.insert(999 - depth, currentItemNr);
704
                        currentItemNr++;
705
                }
706
        }
707
        if (backward_arrow == 1)
708
        {
709
                arrow.resize(0);
710
                ScTextStream CodeAB(&bArrowData, QIODevice::ReadOnly);
711
                CodeAB >> arrow_typeAB >> arrow_styleAB >> arrow_thicknessAB >> arrow_widthAB >> arrow_heightAB;
712
                arrow_widthAB = fig2Pts(arrow_widthAB);
713
                arrow_heightAB = fig2Pts(arrow_heightAB);
714
                arrow_thicknessAB = arrow_thicknessAB / 80.0 * 72.0;
715
                FPointArray arrow;
716
                FPoint Start = ite->PoLine.point(0);
18114 jghali 717
                for (int xx = 1; xx < ite->PoLine.size(); xx += 2)
16682 jghali 718
                {
719
                        FPoint Vector = ite->PoLine.point(xx);
720
                        if ((Start.x() != Vector.x()) || (Start.y() != Vector.y()))
721
                        {
722
                                double r = atan2(Start.y()-Vector.y(),Start.x()-Vector.x())*(180.0/M_PI);
723
                                QTransform arrowTrans;
724
                                if (arrow_typeAB == 0)
725
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5");
726
                                else if (arrow_typeAB == 1)
727
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 z");
728
                                else if (arrow_typeAB == 2)
729
                                        arrow.parseSVG("M -1, -0.5 L 0, 0 L -1, 0.5 L -0.7 0 z");
730
                                else if (arrow_typeAB == 3)
731
                                        arrow.parseSVG("M -0.7, -0.5 L 0, 0 L -0.7, 0.5 L -1 0 z");
732
                                arrowTrans.translate(Start.x(), Start.y());
733
                                arrowTrans.rotate(r);
734
                                arrowTrans.scale(arrow_heightAB, arrow_widthAB);
735
                                arrow.map(arrowTrans);
736
                                break;
737
                        }
738
                }
739
                QString fillC = "White";
740
                if (arrow_styleAB == 1)
741
                        fillC = CurrColorStroke;
742
                if (arrow_typeAB == 0)
743
                {
744
                        fillC = CommonStrings::None;
745
                        iteType = PageItem::PolyLine;
746
                }
747
                else
748
                        iteType = PageItem::Polygon;
749
                z = m_Doc->itemAdd(iteType, PageItem::Unspecified, ite->xPos(), ite->yPos(), 10, 10, arrow_thicknessAB, fillC, CurrColorStroke, true);
750
                if (z >= 0)
751
                {
752
                        PageItem *item = m_Doc->Items->at(z);
753
                        item->PoLine = arrow.copy();
754
                        item->ClipEdited = true;
755
                        item->FrameType = 3;
756
                        item->setFillShade(CurrFillShade);
757
                        item->setLineShade(CurrStrokeShade);
758
                        FPoint wh = getMaxClipF(&item->PoLine);
759
                        item->setWidthHeight(wh.x(),wh.y());
760
                        item->setTextFlowMode(PageItem::TextFlowDisabled);
761
                        m_Doc->AdjustItemSize(item);
762
                        item->setWidthHeight(qMax(item->width(), 1.0), qMax(item->height(), 1.0));
763
                        depthMap.insert(999 - depth, currentItemNr);
764
                        currentItemNr++;
765
                }
766
        }
767
}
768
 
769
void XfigPlug::processPolyline(QDataStream &ts, QString data)
770
{
771
        QString tmp = data;
772
        QString fArrowData = "";
773
        QString bArrowData = "";
774
        int             command;
775
        int             subtype;                                // (1: polyline, 2: box, 3: polygon, 4: arc-box, 5: imported-picture bounding-box)
776
        int             line_style;                             // (enumeration type)
777
        int             thickness;                              // (1/80 inch)
778
        int             pen_color;                              // (enumeration type, pen color)
779
        int             fill_color;                             // (enumeration type, fill color)
780
        int             depth;                                  // (enumeration type)
781
        int             pen_style;                              // (pen style, not used)
782
        int             area_fill;                              // (enumeration type, -1 = no fill)
783
        double  style_val;                              // (1/80 inch)
784
        int             join_style;                     // (enumeration type)
785
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
786
        int             radius;                                 // (1/80 inch, radius of arc-boxes)
787
        int             forward_arrow;                  // (0: off, 1: on)
788
        int             backward_arrow;                 // (0: off, 1: on)
789
        int             npoints;                                // (number of points in line)
790
        int pointsRead = 0;
791
        int imgFlipped;
792
        QString imgFile;
793
        double x, y;
794
        Coords.resize(0);
795
        Coords.svgInit();
796
        bool first = true;
797
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
798
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
799
        Code >> area_fill >> style_val >> join_style >> cap_style >> radius >> forward_arrow >> backward_arrow >> npoints;
800
        if (forward_arrow == 1)
801
                fArrowData = readLinefromDataStream(ts);
802
        if (backward_arrow == 1)
803
                bArrowData = readLinefromDataStream(ts);
804
        if (subtype == 5)
805
        {
806
                tmp = readLinefromDataStream(ts);
807
                ScTextStream imf(&tmp, QIODevice::ReadOnly);
808
                imf >> imgFlipped >> imgFile;
809
        }
810
        while (!ts.atEnd())
811
        {
812
                tmp = readLinefromDataStream(ts);
813
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
814
                while (!pts.atEnd())
815
                {
816
                        pts >> x >> y;
817
                        x = fig2Pts(x) - docX;
818
                        y = fig2Pts(y) - docY;
819
                        if (first)
820
                        {
821
                                Coords.svgMoveTo(x, y);
822
                                first = false;
823
                        }
824
                        else
825
                                Coords.svgLineTo(x, y);
826
                        pointsRead++;
827
                }
828
                if (pointsRead == npoints)
829
                {
830
                        if (npoints == 1)
831
                                Coords.svgLineTo(x, y);
832
                        break;
833
                }
834
        }
835
        useColor(pen_color, 0, false);
836
        useColor(fill_color, area_fill, true);
837
        LineW = thickness / 80.0 * 72.0;
838
        int z = -1;
839
        PageItem *ite;
840
        if (subtype == 1)
841
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
842
        else if ((subtype == 2) || (subtype == 3) || (subtype == 4))
843
        {
844
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
845
                Coords.svgClosePath();
846
        }
847
        else if (subtype == 5)
848
        {
849
                z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
850
                Coords.svgClosePath();
851
        }
852
        else
853
                z = -1;
854
        if (z >= 0)
855
        {
856
                ite = m_Doc->Items->at(z);
857
                ite->PoLine = Coords.copy();
858
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
859
                ite->ClipEdited = true;
860
                ite->FrameType = 3;
861
                ite->setFillShade(CurrFillShade);
862
                ite->setLineShade(CurrStrokeShade);
863
                if (line_style > 0)
864
                        ite->setDashes(getDashValues(LineW, line_style));
865
                if (subtype == 1)
866
                {
867
                        if (join_style == 0)
868
                                ite->setLineJoin(Qt::MiterJoin);
869
                        else if (join_style == 1)
870
                                ite->setLineJoin(Qt::RoundJoin);
871
                        else if (join_style == 2)
872
                                ite->setLineJoin(Qt::BevelJoin);
873
                        if (cap_style == 0)
874
                                ite->setLineEnd(Qt::FlatCap);
875
                        else if (cap_style == 1)
876
                                ite->setLineEnd(Qt::RoundCap);
877
                        else if (cap_style == 2)
878
                                ite->setLineEnd(Qt::SquareCap);
879
                }
880
                FPoint wh = getMaxClipF(&ite->PoLine);
881
                ite->setWidthHeight(wh.x(),wh.y());
882
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
883
                m_Doc->AdjustItemSize(ite);
884
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
885
                if (subtype == 4)
886
                {
887
                        ite->setCornerRadius(radius / 80.0 * 72.0);
888
                        ite->FrameType = 2;
889
                        ite->ClipEdited = false;
890
                        ite->updateClip();
891
                }
892
                if (subtype == 5)
893
                {
894
                        ite->Pfile = baseFile + "/" + imgFile;
895
                        m_Doc->loadPict(ite->Pfile, ite, false);
896
                        ite->setImageXYScale(72.0 / 80.0, 72.0 / 80.0);
897
                        ite->setImageXYOffset(0, 0);
898
                }
899
                depthMap.insert(999 - depth, currentItemNr);
900
                currentItemNr++;
901
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
902
                        processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
903
        }
904
}
905
 
906
void XfigPlug::processSpline(QDataStream &ts, QString data)
907
{
908
        QString tmp = data;
909
        QString fArrowData = "";
910
        QString bArrowData = "";
911
        int             command;
912
        int             subtype;                                // 0: open approximated spline
913
                                                                        // 1: closed approximated spline
914
                                                                        // 2: open   interpolated spline
915
                                                                        // 3: closed interpolated spline
916
                                                                        // 4: open   x-spline 
917
                                                                        // 5: closed x-spline
918
        int             line_style;                             // (enumeration type)
919
        int             thickness;                              // (1/80 inch)
920
        int             pen_color;                              // (enumeration type, pen color)
921
        int             fill_color;                             // (enumeration type, fill color)
922
        int             depth;                                  // (enumeration type)
923
        int             pen_style;                              // (pen style, not used)
924
        int             area_fill;                              // (enumeration type, -1 = no fill)
925
        double  style_val;                              // (1/80 inch)
926
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
927
        int             forward_arrow;                  // (0: off, 1: on)
928
        int             backward_arrow;                 // (0: off, 1: on)
929
        int             npoints;                                // (number of points in line)
930
        int pointsRead = 0;
931
        double x, y;
932
        Coords.resize(0);
933
        Coords.svgInit();
934
        bool first = true;
935
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
936
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
937
        Code >> area_fill >> style_val >> cap_style >> forward_arrow >> backward_arrow >> npoints;
938
        if (forward_arrow == 1)
939
                fArrowData = readLinefromDataStream(ts);
940
        if (backward_arrow == 1)
941
                bArrowData = readLinefromDataStream(ts);
942
        while (!ts.atEnd())
943
        {
944
                tmp = readLinefromDataStream(ts);
945
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
946
                while (!pts.atEnd())
947
                {
948
                        pts >> x >> y;
949
                        x = fig2Pts(x) - docX;
950
                        y = fig2Pts(y) - docY;
951
                        if (first)
952
                        {
953
                                Coords.svgMoveTo(x, y);
954
                                first = false;
955
                        }
956
                        else
957
                                Coords.svgLineTo(x, y);
958
                        pointsRead++;
959
                }
960
                if (pointsRead == npoints)
961
                {
962
                        if (npoints == 1)
963
                                Coords.svgLineTo(x, y);
964
                        break;
965
                }
966
        }
967
        pointsRead = 0;
968
        while (!ts.atEnd())
969
        {
970
                tmp = readLinefromDataStream(ts);
971
                ScTextStream pts(&tmp, QIODevice::ReadOnly);
972
                while (!pts.atEnd())
973
                {
974
                        pts >> x;
975
                        pointsRead++;
976
                }
977
                if (pointsRead == npoints)
978
                        break;
979
        }
980
        useColor(pen_color, 0, false);
981
        useColor(fill_color, area_fill, true);
982
        LineW = thickness / 80.0 * 72.0;
983
        int z = -1;
984
        PageItem *ite;
985
        if ((subtype == 0) || (subtype == 2) || (subtype == 4))
986
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
987
        else if ((subtype == 1) || (subtype == 3) || (subtype == 5))
988
        {
989
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
990
                Coords.svgClosePath();
991
        }
992
        if (z >= 0)
993
        {
994
                ite = m_Doc->Items->at(z);
995
                ite->PoLine = Coords.copy();
996
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
997
                ite->ClipEdited = true;
998
                ite->FrameType = 3;
999
                ite->setFillShade(CurrFillShade);
1000
                ite->setLineShade(CurrStrokeShade);
1001
                if (line_style > 0)
1002
                        ite->setDashes(getDashValues(LineW, line_style));
1003
                if ((subtype == 0) || (subtype == 2) || (subtype == 4))
1004
                {
1005
                        if (cap_style == 0)
1006
                                ite->setLineEnd(Qt::FlatCap);
1007
                        else if (cap_style == 1)
1008
                                ite->setLineEnd(Qt::RoundCap);
1009
                        else if (cap_style == 2)
1010
                                ite->setLineEnd(Qt::SquareCap);
1011
                }
1012
                FPoint wh = getMaxClipF(&ite->PoLine);
1013
                ite->setWidthHeight(wh.x(),wh.y());
1014
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1015
                m_Doc->AdjustItemSize(ite);
1016
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
1017
                depthMap.insert(999 - depth, currentItemNr);
1018
                currentItemNr++;
1019
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
1020
                        processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
1021
        }
1022
}
1023
 
1024
void XfigPlug::processArc(QDataStream &ts, QString data)
1025
{
1026
        QString tmp = data;
1027
        QString fArrowData = "";
1028
        QString bArrowData = "";
1029
        int             command;
1030
        int             subtype;                                // (1: open ended arc, 2: pie-wedge (closed))
1031
        int             line_style;                             // (enumeration type)
1032
        int             thickness;                              // (1/80 inch)
1033
        int             pen_color;                              // (enumeration type, pen color)
1034
        int             fill_color;                             // (enumeration type, fill color)
1035
        int             depth;                                  // (enumeration type)
1036
        int             pen_style;                              // (pen style, not used)
1037
        int             area_fill;                              // (enumeration type, -1 = no fill)
1038
        double  style_val;                              // (1/80 inch)
1039
        int             cap_style;                              // (enumeration type, only used for POLYLINE)
1040
        int             direction;                              // (always 1)
1041
        int             forward_arrow;                  // (0: off, 1: on)
1042
        int             backward_arrow;                 // (0: off, 1: on)
1043
        double  center_x, center_y;             // (center of the arc)
1044
        int             x1, y1;                                 // (Fig units, the 1st point the user entered)
1045
        int             x2, y2;                                 // (Fig units, the 2nd point)
1046
        int             x3, y3;                                 // (Fig units, the last point)
1047
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
1048
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
1049
        Code >> area_fill >> style_val >> cap_style >> direction >> forward_arrow >> backward_arrow;
1050
        Code >> center_x >> center_y >> x1 >> y1 >> x2 >> y2 >> x3 >> y3;
1051
        if (forward_arrow == 1)
1052
                fArrowData = readLinefromDataStream(ts);
1053
        if (backward_arrow == 1)
1054
                bArrowData = readLinefromDataStream(ts);
1055
        useColor(pen_color, 0, false);
1056
        useColor(fill_color, area_fill, true);
1057
        LineW = thickness / 80.0 * 72.0;
1058
        int z = -1;
1059
        PageItem *ite;
1060
        if (subtype == 1)
1061
                z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
1062
        else if (subtype == 2)
1063
                z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, LineW, CurrColorFill, CurrColorStroke, true);
1064
        else
1065
                z = -1;
1066
        center_x = fig2Pts(center_x) - docX;
1067
        center_y = fig2Pts(center_y) - docY;
1068
        double x1R = fig2Pts(x1) - docX;
1069
        double y1R = fig2Pts(y1) - docY;
1070
        double x3R = fig2Pts(x3) - docX;
1071
        double y3R = fig2Pts(y3) - docY;
1072
        double r1 = distance(x1R - center_x, y1R - center_y);
1073
        double x0 = center_x - r1;
1074
        double y0 = center_y - r1;
1075
        QRectF bBox = QRectF(x0, y0, r1 * 2.0, r1 * 2.0);
1076
        double angle1 = -xy2Deg(x1R - center_x, y1R - center_y);
1077
        double angle2 = -xy2Deg(x3R - center_x, y3R - center_y);
1078
        double sweep;
1079
        if (direction == 0)
1080
        {
1081
                sweep = angle1 - angle2;
1082
                if (sweep < 0.0)
1083
                        sweep = 360.0 + sweep;
1084
        }
1085
        else
1086
        {
1087
                sweep = angle2 - angle1;
1088
                if (sweep < 0.0)
1089
                        sweep = 360.0 + sweep;
1090
                double an = angle1;
1091
                angle1 = angle2;
1092
                angle2 = an;
1093
        }
1094
        QPainterPath aPath;
1095
        if (subtype == 1)
1096
        {
1097
                aPath.arcMoveTo(bBox, angle2);
1098
                aPath.arcTo(bBox, angle2, sweep);
1099
        }
1100
        else
1101
        {
1102
                aPath.moveTo(center_x, center_y);
1103
                aPath.arcTo(bBox, angle2, sweep);
1104
                aPath.lineTo(center_x, center_y);
1105
        }
1106
        FPointArray points;
1107
        points.fromQPainterPath(aPath);
1108
 
1109
        if (z >= 0)
1110
        {
1111
                ite = m_Doc->Items->at(z);
1112
                ite->PoLine = points.copy();
1113
                ite->PoLine.translate(m_Doc->currentPage()->xOffset(), m_Doc->currentPage()->yOffset());
1114
                ite->ClipEdited = true;
1115
                ite->FrameType = 3;
1116
                ite->setFillShade(CurrFillShade);
1117
                ite->setLineShade(CurrStrokeShade);
1118
                if (line_style > 0)
1119
                        ite->setDashes(getDashValues(LineW, line_style));
1120
                if (subtype == 1)
1121
                {
1122
                        if (cap_style == 0)
1123
                                ite->setLineEnd(Qt::FlatCap);
1124
                        else if (cap_style == 1)
1125
                                ite->setLineEnd(Qt::RoundCap);
1126
                        else if (cap_style == 2)
1127
                                ite->setLineEnd(Qt::SquareCap);
1128
                }
1129
                FPoint wh = getMaxClipF(&ite->PoLine);
1130
                ite->setWidthHeight(wh.x(),wh.y());
1131
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1132
                m_Doc->AdjustItemSize(ite);
1133
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
1134
                depthMap.insert(999 - depth, currentItemNr);
1135
                currentItemNr++;
1136
                if ((ite->itemType() == PageItem::PolyLine) && ((forward_arrow == 1) || (backward_arrow == 1)))
1137
                {
1138
                        if (direction == 1)
1139
                                processArrows(forward_arrow, fArrowData, backward_arrow, bArrowData, depth, ite);
1140
                        else
1141
                                processArrows(backward_arrow, bArrowData, forward_arrow, fArrowData, depth, ite);
1142
                }
1143
        }
1144
}
1145
 
1146
void XfigPlug::processEllipse(QString data)
1147
{
1148
        QString tmp = data;
1149
        int             command;                        // (always 1)
1150
        int             subtype;                        // (1: ellipse defined by radii
1151
                                                                //  2: ellipse defined by diameters
1152
                                                                //  3: circle defined by radius
1153
                                                                //  4: circle defined by diameter)
1154
        int             line_style;                     // (enumeration type)
1155
        int             thickness;                      // (1/80 inch)
1156
        int             pen_color;                      // (enumeration type, pen color)
1157
        int             fill_color;                     // (enumeration type, fill color)
1158
        int             depth;                          // (enumeration type)
1159
        int             pen_style;                      // (pen style, not used)
1160
        int             area_fill;                      // (enumeration type, -1 = no fill)
1161
        double  style_val;                      // (1/80 inch)
1162
        int             direction;                      // (always 1)
1163
        double  angle;                          // (radians, the angle of the x-axis)
1164
        int             center_x, center_y;     // (Fig units)
1165
        int             radius_x, radius_y;     // (Fig units)
1166
        int             start_x, start_y;       // (Fig units; the 1st point entered)
1167
        int             end_x, end_y;           // (Fig units; the last point entered)
1168
        double x, y, w, h;
1169
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
1170
        Code >> command >> subtype >> line_style >> thickness >> pen_color >> fill_color >> depth >> pen_style;
1171
        Code >> area_fill >> style_val >> direction >> angle >> center_x >> center_y >> radius_x >> radius_y;
1172
        Code >> start_x >> start_y >> end_x >> end_y;
1173
        useColor(pen_color, 0, false);
1174
        useColor(fill_color, area_fill, true);
1175
        LineW = thickness / 80.0 * 72.0;
1176
        w = fig2Pts(radius_x);
1177
        h = fig2Pts(radius_y);
1178
        x = fig2Pts(center_x) - w;
1179
        y = fig2Pts(center_y) - h;
1180
        w *= 2.0;
1181
        h *= 2.0;
1182
        x -= docX;
1183
        x += m_Doc->currentPage()->xOffset();
1184
        y -= docY;
1185
        y += m_Doc->currentPage()->yOffset();
1186
        int z = -1;
1187
        PageItem *ite;
1188
        z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX + x, baseY + y, w, h, LineW, CurrColorFill, CurrColorStroke, true);
1189
        if (z >= 0)
1190
        {
1191
                ite = m_Doc->Items->at(z);
1192
                ite->setFillShade(CurrFillShade);
1193
                ite->setLineShade(CurrStrokeShade);
1194
                if (line_style > 0)
1195
                        ite->setDashes(getDashValues(LineW, line_style));
1196
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1197
                int rot = m_Doc->RotMode();
1198
                m_Doc->RotMode ( 2);
1199
                m_Doc->RotateItem(-angle * 180.0 / M_PI, ite);
1200
                m_Doc->RotMode( rot);
1201
                depthMap.insert(999 - depth, currentItemNr);
1202
                currentItemNr++;
1203
        }
1204
}
1205
 
1206
QString XfigPlug::cleanText(QString text)
1207
{
1208
        QString ret = "";
1209
        QString tmp = "";
1210
        bool sep = false;
1211
        int sepcount = 0;
1212
        for (int a = 1; a < text.count(); ++a)
1213
        {
1214
                QString ch = text.mid(a,1);
1215
                if (sep)
1216
                {
1217
                        if (ch == "\\")
1218
                        {
1219
                                ret += ch;
1220
                                sep = false;
1221
                        }
1222
                        else
1223
                        {
1224
                                tmp += ch;
1225
                                sepcount++;
1226
                                if (sepcount == 3)
1227
                                {
1228
                                        sep = false;
1229
                                        bool ok = false;
1230
                                        if (tmp != "001")
1231
                                        {
1232
                                                int code = tmp.toInt(&ok, 8);
1233
                                                if (ok)
1234
                                                        ret += QChar(code);
1235
                                        }
1236
                                        tmp = "";
1237
                                }
1238
                        }
1239
                }
1240
                else
1241
                {
1242
                        if (ch == "\\")
1243
                        {
1244
                                sep = true;
1245
                                sepcount = 0;
1246
                        }
1247
                        else
1248
                                ret += ch;
1249
                }
1250
        }
1251
        return ret;
1252
}
1253
 
1254
void XfigPlug::processText(QString data)
1255
{
1256
        QString tmp = data;
1257
        int             command;                        // (always 4)
1258
        int             subtype;                        // (0: Left justified
1259
                                                                //  1: Center justified
1260
                                                                //  2: Right justified)
1261
        int             color;                          // (enumeration type)
1262
        int             depth;                          // (enumeration type)
1263
        int             pen_style;                      // (enumeration , not used)
1264
        int             font;                           // (enumeration type)
1265
        float   font_size;                      // (font size in points)
1266
        float   angle;                          // (radians, the angle of the text)
1267
        int             font_flags;                     // (bit vector)
1268
        float   height;                         // (Fig units)
1269
        float   length;                         // (Fig units)
1270
        int             xT, yT;                         // (Fig units, coordinate of the origin
1271
                                                                //  of the string.  If sub_type = 0, it is
1272
                                                                //  the lower left corner of the string.
1273
                                                                //  If sub_type = 1, it is the lower
1274
                                                                //  center.  Otherwise it is the lower
1275
                                                                //  right corner of the string.)
1276
        QString text;
1277
        double x, y, w, h;
1278
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
1279
        Code >> command >> subtype >> color >> depth >> pen_style >> font >> font_size >> angle;
1280
        Code >> font_flags >> height >> length >> xT >> yT;
1281
        text = Code.readAll();
1282
        text = cleanText(text);
1283
        FPointArray textPath;
1284
        QPainterPath painterPath;
1285
        QString TFont(m_Doc->itemToolPrefs().textFont);
1286
        QFont::Weight weight = QFont::Normal;
1287
        bool isItalic = false;
1288
        if (font_flags & 4)
1289
        {
1290
                switch (font)
1291
                {
1292
                        case 0:
1293
                                TFont = "Times Roman";
1294
                                weight = QFont::Normal;
1295
                                break;
1296
                        case 1:
1297
                                TFont = "Times Italic";
1298
                                weight = QFont::Normal;
1299
                                isItalic = true;
1300
                                break;
1301
                        case 2:
1302
                                TFont = "Times Bold";
1303
                                weight = QFont::Bold;
1304
                                break;
1305
                        case 3:
1306
                                TFont = "Times Bold Italic";
1307
                                weight = QFont::Bold;
1308
                                isItalic = true;
1309
                                break;
1310
                        case 4:
1311
                                TFont = "AvantGarde Book";
1312
                                weight = QFont::Normal;
1313
                                break;
1314
                        case 5:
1315
                                TFont = "AvantGarde Book Oblique";
1316
                                weight = QFont::Normal;
1317
                                break;
1318
                        case 6:
1319
                                TFont = "AvantGarde Demi";
1320
                                weight = QFont::DemiBold;
1321
                                break;
1322
                        case 7:
1323
                                TFont = "AvantGarde Demi Oblique";
1324
                                weight = QFont::DemiBold;
1325
                                break;
1326
                        case 8:
1327
                                TFont = "Bookman Light";
1328
                                weight = QFont::Light;
1329
                                break;
1330
                        case 9:
1331
                                TFont = "Bookman Light Italic";
1332
                                weight = QFont::Light;
1333
                                isItalic = true;
1334
                                break;
1335
                        case 10:
1336
                                TFont = "Bookman Demi";
1337
                                weight = QFont::DemiBold;
1338
                                break;
1339
                        case 11:
1340
                                TFont = "Bookman Demi Italic";
1341
                                weight = QFont::DemiBold;
1342
                                isItalic = true;
1343
                                break;
1344
                        case 12:
1345
                                TFont = "Courier";
1346
                                weight = QFont::Normal;
1347
                                break;
1348
                        case 13:
1349
                                TFont = "Courier Oblique";
1350
                                weight = QFont::Normal;
1351
                                break;
1352
                        case 14:
1353
                                TFont = "Courier Bold";
1354
                                weight = QFont::Bold;
1355
                                break;
1356
                        case 15:
1357
                                TFont = "Courier Bold Oblique";
1358
                                weight = QFont::Bold;
1359
                                break;
1360
                        case 16:
1361
                                TFont = "Helvetica";
1362
                                weight = QFont::Normal;
1363
                                break;
1364
                        case 17:
1365
                                TFont = "Helvetica Oblique";
1366
                                weight = QFont::Normal;
1367
                                break;
1368
                        case 18:
1369
                                TFont = "Helvetica Bold";
1370
                                weight = QFont::Bold;
1371
                                break;
1372
                        case 19:
1373
                                TFont = "Helvetica Bold Oblique";
1374
                                weight = QFont::Bold;
1375
                                break;
1376
                        case 20:
1377
                                TFont = "Helvetica Narrow";
1378
                                weight = QFont::Normal;
1379
                                break;
1380
                        case 21:
1381
                                TFont = "Helvetica Narrow Oblique";
1382
                                weight = QFont::Normal;
1383
                                break;
1384
                        case 22:
1385
                                TFont = "Helvetica Narrow Bold";
1386
                                weight = QFont::Bold;
1387
                                break;
1388
                        case 23:
1389
                                TFont = "Helvetica Narrow Bold Oblique";
1390
                                weight = QFont::Bold;
1391
                                break;
1392
                        case 24:
1393
                                TFont = "New Century Schoolbook Roman";
1394
                                weight = QFont::Normal;
1395
                                break;
1396
                        case 25:
1397
                                TFont = "New Century Schoolbook Italic";
1398
                                weight = QFont::Normal;
1399
                                isItalic = true;
1400
                                break;
1401
                        case 26:
1402
                                TFont = "New Century Schoolbook Bold";
1403
                                weight = QFont::Bold;
1404
                                break;
1405
                        case 27:
1406
                                TFont = "New Century Schoolbook Bold Italic";
1407
                                weight = QFont::Bold;
1408
                                isItalic = true;
1409
                                break;
1410
                        case 28:
1411
                                TFont = "Palatino Roman";
1412
                                weight = QFont::Normal;
1413
                                break;
1414
                        case 29:
1415
                                TFont = "Palatino Italic";
1416
                                weight = QFont::Normal;
1417
                                isItalic = true;
1418
                                break;
1419
                        case 30:
1420
                                TFont = "Palatino Bold";
1421
                                weight = QFont::Bold;
1422
                                break;
1423
                        case 31:
1424
                                TFont = "Palatino Bold Italic";
1425
                                weight = QFont::Bold;
1426
                                isItalic = true;
1427
                                break;
1428
                        case 32:
1429
                                TFont = "Symbol";
1430
                                weight = QFont::Normal;
1431
                                break;
1432
                        case 33:
1433
                                TFont = "Zapf Chancery Medium Italic";
1434
                                weight = QFont::Normal;
1435
                                isItalic = true;
1436
                                break;
1437
                        case 34:
1438
                                TFont = "Zapf Dingbats";
1439
                                weight = QFont::Normal;
1440
                                break;
1441
                        default:
1442
                                TFont = m_Doc->itemToolPrefs().textFont;
1443
                                weight = QFont::Normal;
1444
                                break;
1445
                }
1446
        }
1447
        else
1448
        {
1449
                switch (font)
1450
                {
1451
                case 1: // Roman
1452
                                TFont = "Times";
1453
                                weight = QFont::Normal;
1454
                                break;
1455
                        case 2: // Bold
1456
                                TFont = "Times";
1457
                                weight = QFont::Bold;
1458
                                break;
1459
                        case 3: // Italic
1460
                                TFont = "Times";
1461
                                weight = QFont::Normal;
1462
                                isItalic = true;
1463
                                break;
1464
                        case 4: // Sans Serif
1465
                                TFont = "Helvetica";
1466
                                weight = QFont::Normal;
1467
                                break;
1468
                        case 5: // Typewriter
1469
                                TFont = "Courier";
1470
                                weight = QFont::Normal;
1471
                                break;
1472
                        default:
1473
                                TFont = m_Doc->itemToolPrefs().textFont;
1474
                                weight = QFont::Normal;
1475
                                break;
1476
                }
1477
        }
1478
        w = fig2Pts(length);
1479
        h = fig2Pts(height);
1480
        x = fig2Pts(xT);
1481
        y = fig2Pts(yT);
1482
        x -= docX;
1483
        x += m_Doc->currentPage()->xOffset();
1484
        y -= docY;
1485
        y += m_Doc->currentPage()->yOffset();
1486
        QFont tf = QFont(TFont, 10, weight, isItalic);
1487
        tf.setPointSizeF(font_size / 80.0 * 72.0);
1488
        painterPath.addText( 0, 0, tf, text );
1489
        QRectF br = painterPath.boundingRect();
1490
        if ((angle == 0) && (br.width() > w))
1491
        {
1492
                QTransform m;
1493
                m.scale(w / br.width(), w / br.width());
1494
                painterPath = m.map(painterPath);
1495
        }
1496
        textPath.fromQPainterPath(painterPath);
1497
        useColor(color, 0, false);
1498
        int z = -1;
1499
        PageItem *ite;
1500
        z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX + x, baseY + y, w, h, 0, CurrColorStroke, CommonStrings::None, true);
1501
        if (z >= 0)
1502
        {
1503
                ite = m_Doc->Items->at(z);
1504
                ite->setRotation(-angle * 180.0 / M_PI);
1505
                ite->PoLine = textPath.copy();
1506
                ite->ClipEdited = true;
1507
                ite->FrameType = 3;
1508
                FPoint wh = getMaxClipF(&ite->PoLine);
1509
                ite->setWidthHeight(wh.x(),wh.y());
1510
                ite->setTextFlowMode(PageItem::TextFlowDisabled);
1511
                m_Doc->AdjustItemSize(ite);
1512
                ite->setWidthHeight(qMax(ite->width(), 1.0), qMax(ite->height(), 1.0));
1513
                if (subtype == 1)
1514
                        m_Doc->MoveRotated(ite, FPoint(-br.width() / 2.0, 0.0));
1515
                else if (subtype == 2)
1516
                        m_Doc->MoveRotated(ite, FPoint(-br.width(), 0.0));
1517
                depthMap.insert(999 - depth, currentItemNr);
1518
                currentItemNr++;
1519
        }
1520
}
1521
 
1522
void XfigPlug::processData(QDataStream &ts, QString data)
1523
{
1524
        QString tmp = data;
1525
        int command, subtype;
1526
        ScTextStream Code(&tmp, QIODevice::ReadOnly);
1527
        Code >> command >> subtype;
1528
        switch (command)
1529
        {
1530
                case 0:
1531
                        parseColor(data);
1532
                        break;
1533
                case 1:
1534
                        processEllipse(data);
1535
                        break;
1536
                case 2:
1537
                        processPolyline(ts, data);
1538
                        break;
1539
                case 3:
1540
                        processSpline(ts, data);
1541
                        break;
1542
                case 4:
1543
                        processText(data);
1544
                        break;
1545
                case 5:
1546
                        processArc(ts, data);
1547
                        break;
1548
                case 6:
1549
//                      qDebug() << "Xfig-Import:: Unsupported Compound object";
1550
                        break;
1551
                case -6:
1552
//                      qDebug() << "Xfig-Import:: Unsupported End of Compound object";
1553
                        break;
1554
        }
1555
}
1556
 
1557
void XfigPlug::resortItems()
1558
{
1559
        int ac = m_Doc->Items->count();
1560
        QList<PageItem*> itemList;
1561
        for (int as = oldDocItemCount; as < ac; ++as)
1562
        {
1563
                itemList.append(m_Doc->Items->takeAt(oldDocItemCount));
1564
        }
1565
        QList<int> keylist = depthMap.uniqueKeys();
1566
        int keysCount = keylist.count();
1567
        int currentLayer = 0;
1568
        for (int it = 0; it < keysCount; ++it)
1569
        {
1570
                if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (it > 0))
1571
                        currentLayer = m_Doc->addLayer(QString("Layer %1").arg(it), true);
1572
                QList<int> elems = depthMap.values(keylist.at(it));
1573
                qSort(elems);
1574
                int itemsCount = elems.count();
1575
                for (int i = 0; i < itemsCount; ++i)
1576
                {
1577
                        PageItem* ite = itemList.at(elems.at(i));
1578
                        Elements.append(ite);
1579
                        m_Doc->Items->append(ite);
1580
                        if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (it > 0))
1581
                                ite->LayerID = currentLayer;
1582
                }
1583
        }
1584
}
1585
 
1586
 
1587
double XfigPlug::fig2Pts(double in)
1588
{
1589
        return in / 1200.0 * 72.0;
1590
}
1591
 
1592
bool XfigPlug::convert(QString fn)
1593
{
1594
        QString tmp;
1595
        CurrColorFill = "White";
1596
        CurrFillShade = 100.0;
1597
        CurrColorStroke = "Black";
1598
        CurrStrokeShade = 100.0;
1599
        patternMode = false;
1600
        patternX1 = 0.0;
1601
        patternY1 = 0.0;
1602
        patternX2 = 0.0;
1603
        patternY2 = 0.0;
1604
        Coords.resize(0);
1605
        Coords.svgInit();
1606
        clipCoords.resize(0);
1607
        clipCoords.svgInit();
1608
        currentPatternName = "";
1609
        currentPatternX = 0.0;
1610
        currentPatternY = 0.0;
1611
        currentPatternXScale = 1.0;
1612
        currentPatternYScale = 1.0;
1613
        currentPatternRotation = 0.0;
1614
        QList<PageItem*> gElements;
1615
        groupStack.push(gElements);
1616
        currentItemNr = 0;
1617
        if(progressDialog)
1618
        {
1619
                progressDialog->setOverallProgress(2);
1620
                progressDialog->setLabel("GI", tr("Generating Items"));
1621
                qApp->processEvents();
1622
        }
1623
        QFile f(fn);
1624
        if (f.open(QIODevice::ReadOnly))
1625
        {
1626
                oldDocItemCount = m_Doc->Items->count();
1627
                int fSize = (int) f.size();
1628
                if (progressDialog)
1629
                {
1630
                        progressDialog->setTotalSteps("GI", fSize);
1631
                        qApp->processEvents();
1632
                }
1633
                QDataStream ts(&f);
1634
                QString version = readLinefromDataStream(ts);
1635
                QString orientation = readLinefromDataStream(ts);
1636
                QString justification = readLinefromDataStream(ts);
1637
                QString units = readLinefromDataStream(ts);
1638
                QString papersize = readLinefromDataStream(ts);
1639
                QString magnification = readLinefromDataStream(ts);
1640
                QString multiple = readLinefromDataStream(ts);
1641
                QString transparent = readLinefromDataStream(ts);
1642
                tmp = readLinefromDataStream(ts);
1643
                if (tmp.startsWith("#"))
1644
                        tmp = readLinefromDataStream(ts);
1645
                QString resolution = tmp;
1646
                while (!ts.atEnd())
1647
                {
1648
                        tmp = readLinefromDataStream(ts);
1649
                        if (tmp.startsWith("#"))
1650
                                continue;
1651
                        processData(ts, tmp);
1652
                        if (progressDialog)
1653
                        {
1654
                                progressDialog->setProgress("GI", ts.device()->pos());
1655
                                qApp->processEvents();
1656
                        }
1657
                }
1658
                resortItems();
1659
        }
1660
        if (progressDialog)
1661
                progressDialog->close();
1662
        return true;
1663
}