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 -------------------
9 begin : Sun Sep 29 2013
10 copyright : (C) 2013 by Franz Schmid
11 email : Franz.Schmid@altmuehlnet.de
12 ***************************************************************************/
13
14 #include <QByteArray>
15 #include <QCursor>
16 #include <QDrag>
17 #include <QFile>
18 #include <QList>
19 #include <QMimeData>
20 #include <QRegExp>
21 #include <QStack>
22 #include <QUrl>
23 #include <QDebug>
24
25 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
26 #define _USE_MATH_DEFINES
27 #endif
28
29 #include <cstdlib>
30 #include <climits>
31 #include <limits>
32
33
34 #include "importviva.h"
35
36
37
38 #include "commonstrings.h"
39 #include "loadsaveplugin.h"
40 #include "pageitem_table.h"
41 #include "pagesize.h"
42 #include "prefscontext.h"
43 #include "prefsfile.h"
44 #include "prefsmanager.h"
45 #include "prefstable.h"
46 #include "rawimage.h"
47 #include "scclocale.h"
48 #include "sccolorengine.h"
49 #include "scconfig.h"
50 #include "scmimedata.h"
51 #include "scpaths.h"
52 #include "scribusXml.h"
53 #include "scribuscore.h"
54 #include "scribusdoc.h"
55 #include "scribusview.h"
56 #include "sctextstream.h"
57 #include "selection.h"
58 #include "ui/customfdialog.h"
59 #include "ui/missing.h"
60 #include "ui/multiprogressdialog.h"
61 #include "ui/propertiespalette.h"
62 #include "undomanager.h"
63 #include "util.h"
64 #include "util_formats.h"
65 #include "util_math.h"
66
VivaPlug(ScribusDoc * doc,int flags)67 VivaPlug::VivaPlug(ScribusDoc* doc, int flags)
68 {
69 tmpSel = new Selection(this, false);
70 m_Doc = doc;
71 importerFlags = flags;
72 interactive = (flags & LoadSavePlugin::lfInteractive);
73 progressDialog = nullptr;
74 }
75
parseUnit(const QString & unit)76 double VivaPlug::parseUnit(const QString &unit)
77 {
78 bool noUnit = false;
79 QString unitval=unit;
80 if (unit.right( 2 ) == "pt")
81 unitval.replace( "pt", "");
82 else if (unit.right( 2 ) == "cm")
83 unitval.replace( "cm", "" );
84 else if (unit.right( 2 ) == "mm")
85 unitval.replace( "mm" , "");
86 else if (unit.right( 2 ) == "in")
87 unitval.replace( "in", "" );
88 else if (unit.right( 2 ) == "px")
89 unitval.replace( "px", "" );
90 if (unitval == unit)
91 noUnit = true;
92 double value = ScCLocale::toDoubleC(unitval);
93 if (unit.right( 2 ) == "pt")
94 {}/* value = value; */ //no change
95 else if (unit.right( 2 ) == "cm")
96 value = ( value / 2.54 ) * 72;
97 else if (unit.right( 2 ) == "mm")
98 value = ( value / 25.4 ) * 72;
99 else if (unit.right( 2 ) == "in")
100 value = value * 72;
101 else if (unit.right( 2 ) == "px")
102 value = value * 0.8;
103 else if (noUnit)
104 {}/* value = value; */ //no change
105 return value;
106 }
107
readThumbnail(const QString & fName)108 QImage VivaPlug::readThumbnail(const QString& fName)
109 {
110 QImage tmp;
111 if ( !QFile::exists(fName) )
112 return QImage();
113 progressDialog = nullptr;
114 QFileInfo fi = QFileInfo(fName);
115 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
116 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
117 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
118 m_Doc = new ScribusDoc();
119 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
120 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
121 m_Doc->addPage(0);
122 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
123 baseX = m_Doc->currentPage()->xOffset();
124 baseY = m_Doc->currentPage()->yOffset();
125 Elements.clear();
126 m_Doc->setLoading(true);
127 m_Doc->DoDrawing = false;
128 m_Doc->scMW()->setScriptRunning(true);
129 QString CurDirP = QDir::currentPath();
130 QDir::setCurrent(fi.path());
131 if (convert(fName))
132 {
133 tmpSel->clear();
134 QDir::setCurrent(CurDirP);
135 if (Elements.count() > 1)
136 m_Doc->groupObjectsList(Elements);
137 m_Doc->DoDrawing = true;
138 m_Doc->m_Selection->delaySignalsOn();
139 QImage tmpImage;
140 if (Elements.count() > 0)
141 {
142 for (int dre=0; dre<Elements.count(); ++dre)
143 {
144 tmpSel->addItem(Elements.at(dre), true);
145 }
146 tmpSel->setGroupRect();
147 double xs = tmpSel->width();
148 double ys = tmpSel->height();
149 tmpImage = Elements.at(0)->DrawObj_toImage(500);
150 tmpImage.setText("XSize", QString("%1").arg(xs));
151 tmpImage.setText("YSize", QString("%1").arg(ys));
152 }
153 m_Doc->scMW()->setScriptRunning(false);
154 m_Doc->setLoading(false);
155 m_Doc->m_Selection->delaySignalsOff();
156 delete m_Doc;
157 return tmpImage;
158 }
159 QDir::setCurrent(CurDirP);
160 m_Doc->DoDrawing = true;
161 m_Doc->scMW()->setScriptRunning(false);
162 delete m_Doc;
163 return tmp;
164 }
165
readColors(const QString & fileName,ColorList & colors)166 bool VivaPlug::readColors(const QString& fileName, ColorList & colors)
167 {
168 bool success = false;
169 m_Doc = new ScribusDoc();
170 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
171 m_Doc->setPage(1, 1, 0, 0, 0, 0, 0, 0, false, false);
172 m_Doc->addPage(0);
173 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
174 importedColors.clear();
175 QByteArray f;
176 loadRawText(fileName, f);
177 if (designMapDom.setContent(f))
178 {
179 QDomElement docElem = designMapDom.documentElement();
180 for (QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling() )
181 {
182 QDomElement dpg = drawPag.toElement();
183 if (dpg.tagName() == "vc:colors")
184 parseColorsXML(dpg);
185 }
186 }
187 if (importedColors.count() != 0)
188 {
189 colors = m_Doc->PageColors;
190 success = true;
191 }
192 delete m_Doc;
193 return success;
194 }
195
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)196 bool VivaPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
197 {
198 bool success = false;
199 interactive = (flags & LoadSavePlugin::lfInteractive);
200 importerFlags = flags;
201 cancel = false;
202 bool ret = false;
203 hasLayers = false;
204 firstLayer = true;
205 firstPage = true;
206 pagecount = 1;
207 mpagecount = 0;
208 QFileInfo fi = QFileInfo(fNameIn);
209 if ( !ScCore->usingGUI() )
210 {
211 interactive = false;
212 showProgress = false;
213 }
214 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
215 if ( showProgress )
216 {
217 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
218 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
219 QStringList barNames, barTexts;
220 barNames << "GI";
221 barTexts << tr("Analyzing File:");
222 QList<bool> barsNumeric;
223 barsNumeric << false;
224 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
225 progressDialog->setOverallTotalSteps(3);
226 progressDialog->setOverallProgress(0);
227 progressDialog->setProgress("GI", 0);
228 progressDialog->show();
229 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
230 qApp->processEvents();
231 }
232 else
233 progressDialog = nullptr;
234 if (progressDialog)
235 {
236 progressDialog->setOverallProgress(1);
237 qApp->processEvents();
238 }
239 /* Set default Page to size defined in Preferences */
240 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
241 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
242 baseX = 0;
243 baseY = 0;
244 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
245 {
246 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
247 m_Doc->addPage(0);
248 m_Doc->view()->addPage(0, true);
249 baseX = 0;
250 baseY = 0;
251 }
252 else
253 {
254 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
255 {
256 m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
257 ScCore->primaryMainWindow()->HaveNewDoc();
258 ret = true;
259 baseX = 0;
260 baseY = 0;
261 baseX = m_Doc->currentPage()->xOffset();
262 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
263 }
264 }
265 if ((!ret) && (interactive))
266 {
267 baseX = m_Doc->currentPage()->xOffset();
268 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
269 }
270 if ((ret) || (!interactive))
271 {
272 if (docWidth > docHeight)
273 m_Doc->setPageOrientation(1);
274 else
275 m_Doc->setPageOrientation(0);
276 m_Doc->setPageSize("Custom");
277 }
278 Elements.clear();
279 m_Doc->setLoading(true);
280 m_Doc->DoDrawing = false;
281 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
282 m_Doc->view()->updatesOn(false);
283 m_Doc->scMW()->setScriptRunning(true);
284 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
285 QString CurDirP = QDir::currentPath();
286 QDir::setCurrent(fi.path());
287 if (convert(fNameIn))
288 {
289 tmpSel->clear();
290 QDir::setCurrent(CurDirP);
291 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
292 m_Doc->groupObjectsList(Elements);
293 m_Doc->DoDrawing = true;
294 m_Doc->scMW()->setScriptRunning(false);
295 m_Doc->setLoading(false);
296 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
297 if ((Elements.count() > 0) && (!ret) && (interactive))
298 {
299 if (flags & LoadSavePlugin::lfScripted)
300 {
301 bool loadF = m_Doc->isLoading();
302 m_Doc->setLoading(false);
303 m_Doc->changed();
304 m_Doc->setLoading(loadF);
305 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
306 {
307 m_Doc->m_Selection->delaySignalsOn();
308 for (int dre=0; dre<Elements.count(); ++dre)
309 {
310 m_Doc->m_Selection->addItem(Elements.at(dre), true);
311 }
312 m_Doc->m_Selection->delaySignalsOff();
313 m_Doc->m_Selection->setGroupRect();
314 m_Doc->view()->updatesOn(true);
315 }
316 }
317 else
318 {
319 m_Doc->DragP = true;
320 m_Doc->DraggedElem = nullptr;
321 m_Doc->DragElements.clear();
322 m_Doc->m_Selection->delaySignalsOn();
323 for (int dre=0; dre<Elements.count(); ++dre)
324 {
325 tmpSel->addItem(Elements.at(dre), true);
326 }
327 tmpSel->setGroupRect();
328 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
329 m_Doc->itemSelection_DeleteItem(tmpSel);
330 m_Doc->view()->updatesOn(true);
331 m_Doc->m_Selection->delaySignalsOff();
332 // We must copy the TransationSettings object as it is owned
333 // by handleObjectImport method afterwards
334 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
335 m_Doc->view()->handleObjectImport(md, transacSettings);
336 m_Doc->DragP = false;
337 m_Doc->DraggedElem = nullptr;
338 m_Doc->DragElements.clear();
339 }
340 }
341 else
342 {
343 m_Doc->changed();
344 m_Doc->reformPages();
345 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
346 m_Doc->view()->updatesOn(true);
347 }
348 success = true;
349 }
350 else
351 {
352 QDir::setCurrent(CurDirP);
353 m_Doc->DoDrawing = true;
354 m_Doc->scMW()->setScriptRunning(false);
355 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
356 m_Doc->view()->updatesOn(true);
357 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
358 }
359 if (interactive)
360 m_Doc->setLoading(false);
361 //CB If we have a gui we must refresh it if we have used the progressbar
362 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
363 {
364 if ((showProgress) && (!interactive))
365 m_Doc->view()->DrawNew();
366 }
367 qApp->restoreOverrideCursor();
368 return success;
369 }
370
~VivaPlug()371 VivaPlug::~VivaPlug()
372 {
373 delete progressDialog;
374 delete tmpSel;
375 }
376
convert(const QString & fn)377 bool VivaPlug::convert(const QString& fn)
378 {
379 Coords.resize(0);
380 Coords.svgInit();
381 importedColors.clear();
382 facingPages = false;
383 if (progressDialog)
384 {
385 progressDialog->setOverallProgress(2);
386 progressDialog->setLabel("GI", tr("Generating Items"));
387 qApp->processEvents();
388 }
389 bool retVal = true;
390 importedColors.clear();
391 storyMap.clear();
392 QByteArray f;
393 loadRawText(fn, f);
394 if (designMapDom.setContent(f))
395 {
396 QDomElement docElem = designMapDom.documentElement();
397 for (QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
398 {
399 QDomElement dpg = drawPag.toElement();
400 if (dpg.tagName() == "vd:settings")
401 parseSettingsXML(dpg);
402 else if (dpg.tagName() == "vc:colors")
403 parseColorsXML(dpg);
404 else if (dpg.tagName() == "vs:stylesheets")
405 parseStylesheetsXML(dpg);
406 else if (dpg.tagName() == "vd:preferences")
407 parsePreferencesXML(dpg);
408 else if (dpg.tagName() == "vd:layer")
409 parseLayerXML(dpg);
410 else if (dpg.tagName() == "vd:singleAliasPage")
411 parseMasterSpreadXML(dpg);
412 else if (dpg.tagName() == "vd:doubleAliasPage")
413 parseMasterSpreadXML(dpg);
414 else if (dpg.tagName() == "vd:spread")
415 parseSpreadXML(dpg);
416 else if (dpg.tagName() == "vd:textChains")
417 parseTextChainsXML(dpg);
418 }
419 }
420 if (progressDialog)
421 progressDialog->close();
422 return retVal;
423 }
424
parseSettingsXML(const QDomElement & grNode)425 void VivaPlug::parseSettingsXML(const QDomElement& grNode)
426 {
427 if (importerFlags & LoadSavePlugin::lfCreateDoc)
428 {
429 topMargin = m_Doc->marginsVal().top();
430 leftMargin = m_Doc->marginsVal().left();
431 rightMargin = m_Doc->marginsVal().right();
432 bottomMargin = m_Doc->marginsVal().bottom();
433 double pgCols = m_Doc->PageSp;
434 double pgGap = m_Doc->PageSpa;
435 papersize = "Custom";
436 QString paperOrien = "portrait";
437 bool hasPageSize = false;
438 for (QDomNode n = grNode.firstChild(); !n.isNull(); n = n.nextSibling() )
439 {
440 QDomElement e = n.toElement();
441 if (e.tagName() == "vd:pageMargins")
442 {
443 topMargin = parseUnit(e.attribute("vd:top", "0"));
444 leftMargin = parseUnit(e.attribute("vd:left", "0"));
445 rightMargin = parseUnit(e.attribute("vd:right", "0"));
446 bottomMargin = parseUnit(e.attribute("vd:bottom", "0"));
447 }
448 else if (e.tagName() == "vd:pageColumns")
449 {
450 pgCols = e.attribute("vd:count", "1").toInt();
451 pgGap = parseUnit(e.attribute("vd:distance", "0"));
452 }
453 else if (e.tagName() == "vd:pageMode")
454 facingPages = e.text() == "doublePage";
455 else if (e.tagName() == "vd:pageFormat")
456 papersize = e.text();
457 else if (e.tagName() == "vd:pageOrientation")
458 paperOrien = e.text();
459 else if (e.tagName() == "vd:pageSize")
460 {
461 docWidth = parseUnit(e.attribute("vd:width", "0"));
462 docHeight = parseUnit(e.attribute("vd:height", "0"));
463 hasPageSize = true;
464 }
465 }
466 PageSize ps(papersize);
467 if (hasPageSize)
468 {
469 if (!paperOrien.startsWith("portrait"))
470 {
471 double tmp = docWidth;
472 docWidth = docHeight;
473 docHeight = tmp;
474 }
475 }
476 else
477 {
478 if (paperOrien.startsWith("portrait"))
479 {
480 docWidth = ps.width();
481 docHeight = ps.height();
482 }
483 else
484 {
485 docHeight = ps.width();
486 docWidth = ps.height();
487 }
488 }
489 m_Doc->setPage(docWidth, docHeight, topMargin, leftMargin, rightMargin, bottomMargin, pgCols, pgGap, false, facingPages);
490 m_Doc->setPageSize(papersize);
491 m_Doc->currentPage()->setSize(papersize);
492 m_Doc->currentPage()->setInitialHeight(docHeight);
493 m_Doc->currentPage()->setInitialWidth(docWidth);
494 m_Doc->currentPage()->setHeight(docHeight);
495 m_Doc->currentPage()->setWidth(docWidth);
496 m_Doc->currentPage()->initialMargins.setTop(topMargin);
497 m_Doc->currentPage()->initialMargins.setBottom(bottomMargin);
498 m_Doc->currentPage()->initialMargins.setLeft(leftMargin);
499 m_Doc->currentPage()->initialMargins.setRight(rightMargin);
500 m_Doc->reformPages(true);
501 }
502 }
503
parseColorsXML(const QDomElement & grNode)504 void VivaPlug::parseColorsXML(const QDomElement& grNode)
505 {
506 for (QDomNode n = grNode.firstChild(); !n.isNull(); n = n.nextSibling() )
507 {
508 QDomElement e = n.toElement();
509 if (e.tagName() == "vc:color")
510 {
511 QString colorName = e.attribute("vc:name");
512 if (e.hasChildNodes())
513 {
514 bool seenSpot = false;
515 bool seenRegC = false;
516 ScColor tmp;
517 for (QDomNode gr = e.firstChild(); !gr.isNull(); gr = gr.nextSibling() )
518 {
519 QDomElement grs = gr.toElement();
520 if (grs.tagName() == "vc:rgb")
521 {
522 int r = grs.attribute("vc:red", "0").toInt();
523 int g = grs.attribute("vc:green", "0").toInt();
524 int b = grs.attribute("vc:blue", "0").toInt();
525 tmp.setRgbColor(r, g, b);
526 break;
527 }
528 if (grs.tagName() == "vc:cmyk")
529 {
530 int c = grs.attribute("vc:cyan", "0").toInt();
531 int m = grs.attribute("vc:magenta", "0").toInt();
532 int y = grs.attribute("vc:yellow", "0").toInt();
533 int k = grs.attribute("vc:key", "0").toInt();
534 tmp.setColor(c, m, y, k);
535 break;
536 }
537 if (grs.tagName() == "vc:lab")
538 {
539 double L = grs.attribute("vc:l", "100").toDouble();
540 double a = grs.attribute("vc:a", "0").toDouble();
541 double b = grs.attribute("vc:b", "0").toDouble();
542 tmp.setLabColor(L, a, b);
543 break;
544 }
545 if (grs.tagName() == "vc:hsv")
546 {
547 int h = grs.attribute("vc:hue", "0").toInt();
548 int s = grs.attribute("vc:saturation", "0").toInt();
549 int v = grs.attribute("vc:value", "0").toInt();
550 QColor qc;
551 qc.setHsv(h, s, v);
552 tmp.fromQColor(qc);
553 tmp = ScColorEngine::convertToModel(tmp, m_Doc, colorModelRGB);
554 break;
555 }
556 if (grs.tagName() == "vc:registrationColor")
557 {
558 seenRegC = true;
559 int r = e.attribute("vc:red", "0").toInt();
560 int g = e.attribute("vc:green", "0").toInt();
561 int b = e.attribute("vc:blue", "0").toInt();
562 tmp.setRgbColor(r, g, b);
563 break;
564 }
565 if (grs.tagName() == "vc:spotColor")
566 seenSpot = true;
567 }
568 tmp.setSpotColor(seenSpot);
569 tmp.setRegistrationColor(seenRegC);
570 QString fNam = m_Doc->PageColors.tryAddColor(colorName, tmp);
571 if (fNam == colorName)
572 importedColors.append(fNam);
573 colorTranslate.insert(colorName, fNam);
574 }
575 else
576 {
577 int r = e.attribute("vc:red", "0").toInt();
578 int g = e.attribute("vc:green", "0").toInt();
579 int b = e.attribute("vc:blue", "0").toInt();
580 ScColor tmp;
581 tmp.setRgbColor(r, g, b);
582 tmp.setSpotColor(false);
583 tmp.setRegistrationColor(false);
584 QString fNam = m_Doc->PageColors.tryAddColor(colorName, tmp);
585 if (fNam == colorName)
586 importedColors.append(fNam);
587 colorTranslate.insert(colorName, fNam);
588 }
589 }
590 else if (e.tagName() == "vc:gradient")
591 {
592 QString grName = e.attribute("vc:name");
593 QString grSelf = grName;
594 int grTyp = 6;
595 if (e.attribute("vc:type") == "linear")
596 grTyp =6;
597 else if (e.attribute("vc:type") == "radial")
598 grTyp = 7;
599 else if (e.attribute("vc:type") == "rectangle")
600 grTyp = 10;
601 VGradient currentGradient = VGradient(VGradient::linear);
602 currentGradient.clearStops();
603 for (QDomNode gr = e.firstChild(); !gr.isNull(); gr = gr.nextSibling())
604 {
605 QDomElement grs = gr.toElement();
606 if ((grs.tagName() == "vc:firstColor") || (grs.tagName() == "vc:secondColor"))
607 {
608 QString stopName = grs.attribute("vc:name");
609 int tint = 0;
610 if (grs.attribute("vc:density") == "transparent")
611 tint = 0;
612 else
613 tint = grs.attribute("vc:density").toInt();
614 if (colorTranslate.contains(stopName))
615 stopName = colorTranslate[stopName];
616 else
617 stopName = "Black";
618 const ScColor& gradC = m_Doc->PageColors[stopName];
619 if (grTyp == 6)
620 {
621 if (grs.tagName() == "vc:firstColor")
622 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, stopName, tint );
623 else
624 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), 1.0, 0.5, 1.0, stopName, tint );
625 }
626 else
627 {
628 if (grs.tagName() == "vc:firstColor")
629 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), 1.0, 0.5, 1.0, stopName, tint );
630 else
631 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), 0.0, 0.5, 1.0, stopName, tint );
632 }
633 }
634 }
635 if (m_Doc->addGradient(grName, currentGradient))
636 importedGradients.append(grName);
637 gradientTranslate.insert(grSelf, grName);
638 gradientTypeMap.insert(grName, grTyp);
639 }
640 }
641 }
642
parsePreferencesXML(const QDomElement & spNode)643 void VivaPlug::parsePreferencesXML(const QDomElement& spNode)
644 {
645 if (importerFlags & LoadSavePlugin::lfCreateDoc)
646 {
647 for (QDomNode n = spNode.firstChild(); !n.isNull(); n = n.nextSibling() )
648 {
649 QDomElement e = n.toElement();
650 if (e.tagName() == "vd:text")
651 {
652 for (QDomNode spo = e.firstChild(); !spo.isNull(); spo = spo.nextSibling())
653 {
654 QDomElement eo = spo.toElement();
655 if (eo.tagName() == "vd:superscriptVerticalOffset")
656 m_Doc->typographicPrefs().valueSuperScript = eo.text().toInt();
657 else if (eo.tagName() == "vd:superscriptCharacterHeight")
658 m_Doc->typographicPrefs().scalingSuperScript = eo.text().toInt();
659 else if (eo.tagName() == "vd:subscriptVerticalOffset")
660 m_Doc->typographicPrefs().valueSubScript = eo.text().toInt();
661 else if (eo.tagName() == "vd:subscriptCharacterHeight")
662 m_Doc->typographicPrefs().scalingSubScript = eo.text().toInt();
663 else if (eo.tagName() == "vd:smallCapsCharacterHeight")
664 m_Doc->typographicPrefs().valueSmallCaps = eo.text().toInt();
665 }
666 }
667 }
668 }
669 }
670
parseLayerXML(const QDomElement & spNode)671 void VivaPlug::parseLayerXML(const QDomElement& spNode)
672 {
673 if (importerFlags & LoadSavePlugin::lfCreateDoc)
674 {
675 QString layerName = spNode.attribute("vd:name");
676 bool printable = true;
677 bool visible = true;
678 bool locked = false;
679 bool flow = false;
680 int rc = 0;
681 int gc = 0;
682 int bc = 0;
683 for (QDomNode n = spNode.firstChild(); !n.isNull(); n = n.nextSibling() )
684 {
685 QDomElement e = n.toElement();
686 if (e.tagName() == "vd:print")
687 printable = e.text() == "true";
688 if (e.tagName() == "vd:hidden")
689 visible = e.text() == "false";
690 if (e.tagName() == "vd:locked")
691 locked = e.text() == "true";
692 if (e.tagName() == "vd:keepRunaround")
693 flow = e.text() == "true";
694 if (e.tagName() == "vd:color")
695 {
696 rc = e.attribute("vd:red", "0").toInt();
697 gc = e.attribute("vd:green", "0").toInt();
698 bc = e.attribute("vd:blue", "0").toInt();
699 }
700 }
701 int currentLayer = m_Doc->activeLayer();
702 if (!firstLayer)
703 currentLayer = m_Doc->addLayer(layerName);
704 else
705 m_Doc->changeLayerName(currentLayer, layerName);
706 m_Doc->setLayerVisible(currentLayer, visible);
707 m_Doc->setLayerLocked(currentLayer, locked);
708 m_Doc->setLayerPrintable(currentLayer, printable);
709 m_Doc->setLayerFlow(currentLayer, flow);
710 m_Doc->setLayerMarker(currentLayer, QColor(rc, gc, bc));
711 }
712 firstLayer = false;
713 }
714
parseMasterSpreadXML(const QDomElement & spNode)715 void VivaPlug::parseMasterSpreadXML(const QDomElement& spNode)
716 {
717 if (importerFlags & LoadSavePlugin::lfCreateDoc)
718 {
719 bool firstSpread = true;
720 m_Doc->setMasterPageMode(true);
721 ScPage *oldCur = m_Doc->currentPage();
722 for (QDomNode n = spNode.firstChild(); !n.isNull(); n = n.nextSibling() )
723 {
724 QString pageNam = spNode.attribute("vd:name");
725 QDomElement e = n.toElement();
726 if (e.tagName() == "vd:aliasPage")
727 {
728 if (spNode.tagName() == "vd:doubleAliasPage")
729 {
730 mspreadTypes.insert(pageNam, 1);
731 if (firstSpread)
732 pageNam += "_Left";
733 else
734 pageNam += "_Right";
735 }
736 else
737 mspreadTypes.insert(pageNam, 0);
738 ScPage *addedPage = m_Doc->addMasterPage(mpagecount, pageNam);
739 m_Doc->setCurrentPage(addedPage);
740 addedPage->clearMasterPageName();
741 m_Doc->view()->addPage(mpagecount, true);
742 baseX = addedPage->xOffset();
743 baseY = addedPage->yOffset();
744 mpagecount++;
745 for (QDomNode spo = e.firstChild(); !spo.isNull(); spo = spo.nextSibling())
746 {
747 QDomElement eo = spo.toElement();
748 if (eo.tagName() == "vo:object")
749 {
750 PageItem* ite = parseObjectXML(eo);
751 if (ite != nullptr)
752 {
753 m_Doc->Items->append(ite);
754 Elements.append(ite);
755 }
756 }
757 }
758 firstSpread = false;
759 }
760 }
761 m_Doc->setCurrentPage(oldCur);
762 m_Doc->setMasterPageMode(false);
763 }
764 }
765
parseSpreadXML(const QDomElement & spNode)766 void VivaPlug::parseSpreadXML(const QDomElement& spNode)
767 {
768 for (QDomNode n = spNode.firstChild(); !n.isNull(); n = n.nextSibling() )
769 {
770 QDomElement e = n.toElement();
771 if (e.tagName() == "vd:page")
772 {
773 if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (!firstPage))
774 {
775 m_Doc->addPage(pagecount);
776 m_Doc->currentPage()->setSize(papersize);
777 m_Doc->currentPage()->setInitialHeight(docHeight);
778 m_Doc->currentPage()->setInitialWidth(docWidth);
779 m_Doc->currentPage()->setHeight(docHeight);
780 m_Doc->currentPage()->setWidth(docWidth);
781 m_Doc->currentPage()->initialMargins.setTop(topMargin);
782 m_Doc->currentPage()->initialMargins.setBottom(bottomMargin);
783 m_Doc->currentPage()->initialMargins.setLeft(leftMargin);
784 m_Doc->currentPage()->initialMargins.setRight(rightMargin);
785 m_Doc->currentPage()->setMasterPageNameNormal();
786 m_Doc->view()->addPage(pagecount, true);
787 pagecount++;
788 }
789 baseX = m_Doc->currentPage()->xOffset();
790 baseY = m_Doc->currentPage()->yOffset();
791 for (QDomNode sp = e.firstChild(); !sp.isNull(); sp = sp.nextSibling())
792 {
793 QDomElement spe = sp.toElement();
794 if (spe.tagName() == "vd:content")
795 {
796 for (QDomNode spo = spe.firstChild(); !spo.isNull(); spo = spo.nextSibling())
797 {
798 QDomElement eo = spo.toElement();
799 if (eo.tagName() == "vo:object")
800 {
801 PageItem* ite = parseObjectXML(eo);
802 if (ite != nullptr)
803 {
804 m_Doc->Items->append(ite);
805 Elements.append(ite);
806 }
807 }
808 }
809 }
810 else if (spe.tagName() == "vd:column")
811 {
812 if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (firstPage))
813 {
814 if (spe.text() == "1")
815 m_Doc->setPageSetFirstPage(m_Doc->pagePositioning(), 0);
816 else
817 m_Doc->setPageSetFirstPage(m_Doc->pagePositioning(), 1);
818 m_Doc->reformPages(false);
819 baseX = m_Doc->currentPage()->xOffset();
820 baseY = m_Doc->currentPage()->yOffset();
821 }
822 if (importerFlags & LoadSavePlugin::lfCreateDoc)
823 {
824 QString mpage = e.attribute("vd:aliasPageName");
825 int mType = mspreadTypes[mpage];
826 if (mType == 1)
827 {
828 if (facingPages == 1)
829 {
830 if (spe.text() == "1")
831 mpage += "_Left";
832 else
833 mpage += "_Right";
834 }
835 }
836 m_Doc->applyMasterPage(mpage, m_Doc->currentPageNumber());
837 }
838 }
839 }
840 firstPage = false;
841 }
842 }
843 }
844
parseTextChainsXML(const QDomElement & obNode)845 void VivaPlug::parseTextChainsXML(const QDomElement& obNode)
846 {
847 if (storyMap.isEmpty())
848 return;
849 QDomElement eo = obNode.toElement();
850 for (QDomNode ob = eo.firstChild(); !ob.isNull(); ob = ob.nextSibling())
851 {
852 QDomElement obe = ob.toElement();
853 if (obe.tagName() == "vd:sequence")
854 {
855 QList<PageItem*> GElements;
856 GElements.clear();
857 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
858 {
859 QDomElement eog = obg.toElement();
860 if (eog.tagName() == "vd:object")
861 {
862 QString id = eog.attribute("vd:id");
863 if (storyMap.contains(id))
864 GElements.append(storyMap[id]);
865 }
866 }
867 if (GElements.count() > 1)
868 {
869 PageItem *first = GElements[0];
870 for (int a = 1; a < GElements.count(); a++)
871 {
872 PageItem *next = GElements[a];
873 first->link(next);
874 next->setColumns(first->columns());
875 next->setColumnGap(first->columnGap());
876 first = next;
877 }
878 }
879 }
880 }
881 }
882
parseObjectXML(const QDomElement & obNode)883 PageItem* VivaPlug::parseObjectXML(const QDomElement& obNode)
884 {
885 PageItem *retObj = nullptr;
886 QDomElement eo = obNode.toElement();
887 QString id = eo.attribute("vo:id");
888 for (QDomNode ob = eo.firstChild(); !ob.isNull(); ob = ob.nextSibling())
889 {
890 QDomElement obe = ob.toElement();
891 if (obe.tagName() == "vo:groupObject")
892 {
893 QList<PageItem*> GElements;
894 double ob_xpos = 0;
895 double ob_ypos = 0;
896 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
897 {
898 QDomElement eog = obg.toElement();
899 if (eog.tagName() == "vo:object")
900 {
901 PageItem *gItem = parseObjectXML(eog);
902 if (gItem != nullptr)
903 GElements.append(gItem);
904 }
905 else if (eog.tagName() == "vo:transformation")
906 {
907 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
908 {
909 QDomElement eo = spo.toElement();
910 if (eo.tagName() == "vo:translationX")
911 ob_xpos = parseUnit(eo.text());
912 else if (eo.tagName() == "vo:translationY")
913 ob_ypos = parseUnit(eo.text());
914 }
915 }
916 }
917 if (GElements.count() > 0)
918 {
919 double minx = std::numeric_limits<double>::max();
920 double miny = std::numeric_limits<double>::max();
921 double maxx = -std::numeric_limits<double>::max();
922 double maxy = -std::numeric_limits<double>::max();
923 bool groupClip = true;
924 for (int ep = 0; ep < GElements.count(); ++ep)
925 {
926 PageItem* currItem = GElements.at(ep);
927 double x1, x2, y1, y2;
928 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
929 minx = qMin(minx, x1);
930 miny = qMin(miny, y1);
931 maxx = qMax(maxx, x2);
932 maxy = qMax(maxy, y2);
933 if (currItem->hasSoftShadow())
934 groupClip = false;
935 }
936 double gx = minx;
937 double gy = miny;
938 double gw = maxx - minx;
939 double gh = maxy - miny;
940 int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
941 if (z >= 0)
942 {
943 retObj = m_Doc->Items->at(z);
944 retObj->ClipEdited = true;
945 retObj->FrameType = 3;
946 retObj->setFillEvenOdd(false);
947 retObj->OldB2 = retObj->width();
948 retObj->OldH2 = retObj->height();
949 retObj->updateClip();
950 m_Doc->groupObjectsToItem(retObj, GElements);
951 retObj->setGroupClipping(groupClip);
952 retObj->moveBy(ob_xpos, ob_ypos, true);
953 m_Doc->adjustItemSize(retObj);
954 retObj->OwnPage = m_Doc->OnPage(retObj);
955 m_Doc->GroupOnPage(retObj);
956 m_Doc->Items->removeLast();
957 }
958 }
959 }
960 else if (obe.tagName() == "vo:graphicObject")
961 retObj = parseObjectDetailsXML(obe, 0);
962 else if (obe.tagName() == "vo:pictureObject")
963 retObj = parseObjectDetailsXML(obe, 1);
964 else if (obe.tagName() == "vo:textObject")
965 {
966 retObj = parseObjectDetailsXML(obe, 2);
967 storyMap.insert(id, retObj);
968 }
969 }
970 return retObj;
971 }
972
parseObjectDetailsXML(const QDomElement & obNode,int baseType)973 PageItem* VivaPlug::parseObjectDetailsXML(const QDomElement& obNode, int baseType)
974 {
975 PageItem *retObj = nullptr;
976 QDomElement eo = obNode.toElement();
977 double ob_width = 0;
978 double ob_height = 0;
979 double ob_xpos = 0;
980 double ob_ypos = 0;
981 double ob_rotation = 0;
982 QString fillColor = CommonStrings::None;
983 QString strokeColor = CommonStrings::None;
984 QString fillGradient = "";
985 int fillGradientTyp = 6;
986 int fillTint = 100;
987 int strokeTint = 100;
988 double lineWidth = 0;
989 double fillOpacity = 0.0;
990 double strokeOpacity = 0.0;
991 double imageOpacity = 0.0;
992 double gradientAngle = 0.0;
993 double imageXoffs = 0;
994 double imageYoffs = 0;
995 double imageScaleX = 1.0;
996 // double imageScaleY = 1.0;
997 double cornerRadius = 0.0;
998 int ob_type = 0;
999 bool printable = false;
1000 bool locked = false;
1001 bool resizable = false;
1002 FPointArray Path;
1003 Path.resize(0);
1004 QString imageFile = "";
1005 QByteArray imageData;
1006 imageData.resize(0);
1007 QVector<double> DashValues;
1008 DashValues.clear();
1009 int LineStyle = 0;
1010 int ArrowLeft = 1;
1011 int ArrowRight = 1;
1012 double textMarginLeft = 0.0;
1013 double textMarginRight = 0.0;
1014 double textMarginTop = 0.0;
1015 double textMarginBottom = 0.0;
1016 double textColumnGap = 0.0;
1017 int textColumnCount = 1;
1018 bool hasShadow = false;
1019 double shadowX = 0.0;
1020 double shadowY = 0.0;
1021 double shadowBlur = 0.0;
1022 double shadowOpacity = 0.0;
1023 int shadowTint = 100;
1024 bool shadowErase = false;
1025 bool shadowObjTrans = false;
1026 QString shadowColor = "Black";
1027 StoryText itemText;
1028 itemText.clear();
1029 PageItem::TextFlowMode textFlow = PageItem::TextFlowDisabled;
1030 for (QDomNode ob = eo.firstChild(); !ob.isNull(); ob = ob.nextSibling())
1031 {
1032 QDomElement obe = ob.toElement();
1033 if ((obe.tagName() == "vo:rectangle") || (obe.tagName() == "vo:oval") || (obe.tagName() == "vo:polygon") || (obe.tagName() == "vo:line") || (obe.tagName() == "vo:polyline"))
1034 {
1035 if (obe.tagName() == "vo:rectangle")
1036 ob_type = 0;
1037 if (obe.tagName() == "vo:oval")
1038 ob_type = 1;
1039 if (obe.tagName() == "vo:polygon")
1040 ob_type = 2;
1041 if (obe.tagName() == "vo:line")
1042 ob_type = 3;
1043 if (obe.tagName() == "vo:polyline")
1044 ob_type = 4;
1045 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
1046 {
1047 QDomElement eog = obg.toElement();
1048 if (eog.tagName() == "vo:size")
1049 {
1050 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1051 {
1052 QDomElement eo = spo.toElement();
1053 if (eo.tagName() == "vo:width")
1054 ob_width = parseUnit(eo.text());
1055 else if (eo.tagName() == "vo:height")
1056 ob_height = parseUnit(eo.text());
1057 }
1058 }
1059 else if (eog.tagName() == "vo:transformation")
1060 {
1061 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1062 {
1063 QDomElement eo = spo.toElement();
1064 if (eo.tagName() == "vo:translationX")
1065 ob_xpos = parseUnit(eo.text());
1066 else if (eo.tagName() == "vo:translationY")
1067 ob_ypos = parseUnit(eo.text());
1068 else if (eo.tagName() == "vo:rotation")
1069 ob_rotation = eo.text().toDouble();
1070 }
1071 }
1072 else if (eog.tagName() == "vo:design")
1073 {
1074 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1075 {
1076 QDomElement eo = spo.toElement();
1077 if (eo.tagName() == "vo:lineColor")
1078 strokeColor = colorTranslate[eo.text()];
1079 else if (eo.tagName() == "vo:fillColor")
1080 {
1081 if (colorTranslate.contains(eo.text()))
1082 fillColor = colorTranslate[eo.text()];
1083 else if (gradientTranslate.contains(eo.text()))
1084 {
1085 fillGradient = gradientTranslate[eo.text()];
1086 fillGradientTyp = gradientTypeMap[fillGradient];
1087 }
1088 }
1089 else if (eo.tagName() == "vo:lineDensity")
1090 {
1091 if (eo.text() == "transparent")
1092 strokeTint = 0;
1093 else if (eo.text() == "opaque")
1094 strokeTint = 100;
1095 else
1096 strokeTint = eo.text().toInt();
1097 }
1098 else if (eo.tagName() == "vo:fillDensity")
1099 {
1100 if (eo.text() == "transparent")
1101 fillTint = 0;
1102 else if (eo.text() == "opaque")
1103 fillTint = 100;
1104 else
1105 fillTint = eo.text().toInt();
1106 }
1107 else if (eo.tagName() == "vo:lineWidth")
1108 lineWidth = parseUnit(eo.text());
1109 else if (eo.tagName() == "vo:lineStyle")
1110 {
1111 QString Lstyle = eo.text();
1112 if (Lstyle != "Solid")
1113 {
1114 if (Lstyle == "2")
1115 DashValues << 3 << 2;
1116 else if (Lstyle == "3")
1117 LineStyle = 15;
1118 else if (Lstyle == "4")
1119 DashValues << 5 << 2.2 << 1 << 2.2;
1120 else if (Lstyle == "5")
1121 LineStyle = 6;
1122 else if (Lstyle == "6")
1123 DashValues << 2 << 3.1;
1124 else if ((Lstyle == "7") || (Lstyle == "10"))
1125 LineStyle = 21;
1126 else if (Lstyle == "8")
1127 DashValues << 4 << 3.2 << 0.2 << 3.2;
1128 else if (Lstyle == "9")
1129 DashValues << 0.2 << 2;
1130 }
1131 }
1132 else if (eo.tagName() == "vo:startCap")
1133 {
1134 ArrowLeft = eo.text().toInt();
1135 if (ArrowLeft == 2)
1136 ArrowLeft = 3;
1137 else if (ArrowLeft == 3)
1138 ArrowLeft = 18;
1139 else if (ArrowLeft == 4)
1140 ArrowLeft = 6;
1141 }
1142 else if (eo.tagName() == "vo:endCap")
1143 {
1144 ArrowRight = eo.text().toInt();
1145 if (ArrowRight == 2)
1146 ArrowRight = 3;
1147 else if (ArrowRight == 3)
1148 ArrowRight = 18;
1149 else if (ArrowRight == 4)
1150 ArrowRight = 6;
1151 }
1152 else if (eo.tagName() == "vo:blendAngle")
1153 gradientAngle = eo.text().toDouble();
1154 else if (eo.tagName() == "vo:fillOpacity")
1155 {
1156 if (eo.text() == "transparent")
1157 fillOpacity = 1;
1158 else if (eo.text() == "opaque")
1159 fillOpacity = 0;
1160 else
1161 fillOpacity = 1.0 - (eo.text().toDouble() / 100.0);
1162 }
1163 else if (eo.tagName() == "vo:lineOpacity")
1164 {
1165 if (eo.text() == "transparent")
1166 strokeOpacity = 1;
1167 else if (eo.text() == "opaque")
1168 strokeOpacity = 0;
1169 else
1170 strokeOpacity = 1.0 - (eo.text().toDouble() / 100.0);
1171 }
1172 else if (eo.tagName() == "vo:baseOpacity")
1173 {
1174 double opa = 0.0;
1175 if (eo.text() == "transparent")
1176 opa = 1;
1177 else if (eo.text() == "opaque")
1178 opa = 0;
1179 else
1180 opa = 1.0 - (eo.text().toDouble() / 100.0);
1181 fillOpacity = 1.0 - ((1.0 - fillOpacity) * (1.0 - opa));
1182 strokeOpacity = 1.0 - ((1.0 - strokeOpacity) * (1.0 - opa));
1183 }
1184 else if (eo.tagName() == "vo:cornerRadius")
1185 cornerRadius = parseUnit(eo.text());
1186 }
1187 }
1188 else if (eog.tagName() == "vo:points")
1189 {
1190 Path.resize(0);
1191 bool hasBefore = false;
1192 bool hasAfter = false;
1193 triplePoint triPoint;
1194 QList<triplePoint> tPoints;
1195 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1196 {
1197 QDomElement eo = spo.toElement();
1198 if (eo.tagName() == "vo:point")
1199 {
1200 FPoint pp = FPoint(parseUnit(eo.attribute("vo:x", "0")), parseUnit(eo.attribute("vo:y", "0")));
1201 if (eo.hasAttribute("vo:control"))
1202 {
1203 if ((eo.attribute("vo:control") == "constraint-before") || (eo.attribute("vo:control") == "before"))
1204 hasBefore = true;
1205 else if ((eo.attribute("vo:control") == "constraint-after") || (eo.attribute("vo:control") == "after"))
1206 hasAfter = true;
1207 }
1208 if ((hasBefore) && ((eo.attribute("vo:control") == "constraint-before") || (eo.attribute("vo:control") == "before")))
1209 triPoint.beforePolyPoint = pp;
1210 else if (hasAfter && hasBefore)
1211 {
1212 triPoint.afterPolyPoint = pp;
1213 tPoints.append(triPoint);
1214 hasBefore = false;
1215 hasAfter = false;
1216 }
1217 else if (hasBefore)
1218 triPoint.PolyPoint = pp;
1219 else
1220 {
1221 triPoint.beforePolyPoint = pp;
1222 triPoint.PolyPoint = pp;
1223 triPoint.afterPolyPoint = pp;
1224 tPoints.append(triPoint);
1225 hasBefore = false;
1226 hasAfter = false;
1227 }
1228 }
1229 }
1230 if (tPoints.count() > 0)
1231 {
1232 if (ob_type == 2)
1233 {
1234 Path.addPoint(tPoints[0].PolyPoint);
1235 Path.addPoint(tPoints[0].afterPolyPoint);
1236 for (int ppx = 1; ppx < tPoints.count(); ppx++)
1237 {
1238 Path.addPoint(tPoints[ppx].PolyPoint);
1239 Path.addPoint(tPoints[ppx].beforePolyPoint);
1240 Path.addPoint(tPoints[ppx].PolyPoint);
1241 Path.addPoint(tPoints[ppx].afterPolyPoint);
1242 }
1243 Path.addPoint(tPoints[0].PolyPoint);
1244 Path.addPoint(tPoints[0].beforePolyPoint);
1245 }
1246 else if (ob_type == 3)
1247 {
1248 Path.addPoint(tPoints[0].PolyPoint);
1249 Path.addPoint(tPoints[0].PolyPoint);
1250 Path.addPoint(tPoints[1].PolyPoint);
1251 Path.addPoint(tPoints[1].PolyPoint);
1252 }
1253 else if (ob_type == 4)
1254 {
1255 Path.addPoint(tPoints[0].PolyPoint);
1256 Path.addPoint(tPoints[0].afterPolyPoint);
1257 for (int ppx = 1; ppx < tPoints.count()-1; ppx++)
1258 {
1259 Path.addPoint(tPoints[ppx].PolyPoint);
1260 Path.addPoint(tPoints[ppx].beforePolyPoint);
1261 Path.addPoint(tPoints[ppx].PolyPoint);
1262 Path.addPoint(tPoints[ppx].afterPolyPoint);
1263 }
1264 Path.addPoint(tPoints[tPoints.count()-1].PolyPoint);
1265 Path.addPoint(tPoints[tPoints.count()-1].beforePolyPoint);
1266 }
1267 }
1268 }
1269 else if (eog.tagName() == "vo:shadow")
1270 {
1271 hasShadow = true;
1272 double shadowAngle = 0;
1273 double shadowOffset = 0;
1274 for (QDomElement spo = eog.firstChildElement(); !spo.isNull(); spo = spo.nextSiblingElement())
1275 {
1276 if (spo.tagName() == "uni:color")
1277 shadowColor = colorTranslate[spo.text()];
1278 else if (spo.tagName() == "uni:opacity")
1279 {
1280 if (spo.text() == "transparent")
1281 shadowOpacity = 1;
1282 else if (spo.text() == "opaque")
1283 shadowOpacity = 0;
1284 else
1285 shadowOpacity = 1.0 - (spo.text().toDouble() / 100.0);
1286 }
1287 else if (spo.tagName() == "uni:density")
1288 {
1289 if (spo.text() == "transparent")
1290 shadowTint = 0;
1291 else if (spo.text() == "opaque")
1292 shadowTint = 100;
1293 else
1294 shadowTint = spo.text().toInt();
1295 }
1296 else if (spo.tagName() == "uni:angle")
1297 shadowAngle = spo.text().toDouble();
1298 else if (spo.tagName() == "uni:offset")
1299 shadowOffset = parseUnit(spo.text());
1300 else if (spo.tagName() == "uni:softValue")
1301 shadowBlur = parseUnit(spo.text());
1302 else if (spo.tagName() == "uni:coverShadow")
1303 shadowErase = (spo.text() == "true");
1304 else if (spo.tagName() == "uni:applyElementOpacity")
1305 shadowObjTrans = (spo.text() == "true");
1306 }
1307 QLineF oLine = QLineF(0, 0, shadowOffset, 0);
1308 oLine.setAngle(shadowAngle - 180.0);
1309 shadowX = oLine.p2().x();
1310 shadowY = oLine.p2().y();
1311 }
1312 }
1313 }
1314 else if (obe.tagName() == "vo:properties")
1315 {
1316 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
1317 {
1318 QDomElement eog = obg.toElement();
1319 if (eog.tagName() == "vo:printable")
1320 printable = eog.text() == "true";
1321 else if (eog.tagName() == "vo:protected")
1322 locked = eog.text() == "true";
1323 else if (eog.tagName() == "vo:fixed")
1324 resizable = eog.text() == "true";
1325 }
1326 }
1327 else if (obe.tagName() == "vo:runaround")
1328 {
1329 if ((obe.attribute("vo:mode") == "all") || (obe.attribute("vo:mode") == "left") || (obe.attribute("vo:mode") == "right"))
1330 {
1331 textFlow = PageItem::TextFlowUsesFrameShape;
1332 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
1333 {
1334 QDomElement eog = obg.toElement();
1335 if (eog.tagName() == "vo:shape")
1336 {
1337 textFlow = PageItem::TextFlowUsesFrameShape;
1338 break;
1339 }
1340 if (eog.tagName() == "vo:block")
1341 {
1342 textFlow = PageItem::TextFlowUsesBoundingBox;
1343 break;
1344 }
1345 }
1346 }
1347 }
1348 else if (obe.tagName() == "vo:content")
1349 {
1350 for (QDomNode obg = obe.firstChild(); !obg.isNull(); obg = obg.nextSibling())
1351 {
1352 QDomElement eog = obg.toElement();
1353 if (eog.tagName() == "vo:filePath")
1354 {
1355 QString fileP = eog.text();
1356 QFileInfo fp(fileP);
1357 if (fp.exists())
1358 imageFile = fileP;
1359 else
1360 {
1361 QString fileName = fp.fileName();
1362 QFileInfo fi2(fileName);
1363 if (fi2.exists())
1364 imageFile = fileName;
1365 else
1366 imageFile = fileP;
1367 }
1368 }
1369 else if (eog.tagName() == "vo:fillOpacity")
1370 {
1371 if (eog.text() == "transparent")
1372 imageOpacity = 1;
1373 else if (eog.text() == "opaque")
1374 imageOpacity = 0;
1375 else
1376 imageOpacity = 1.0 - (eog.text().toDouble() / 100.0);
1377 }
1378 else if (eog.tagName() == "vo:transformation")
1379 {
1380 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1381 {
1382 QDomElement eo = spo.toElement();
1383 if (eo.tagName() == "vo:translationX")
1384 imageXoffs = parseUnit(eo.text());
1385 else if (eo.tagName() == "vo:translationY")
1386 imageYoffs = parseUnit(eo.text());
1387 else if (eo.tagName() == "vo:scaleHorizontal")
1388 imageScaleX = eo.text().toDouble() / 100.0;
1389 // else if (eo.tagName() == "vo:scaleVertical")
1390 // imageScaleY = eo.text().toDouble() / 100.0;
1391 }
1392 }
1393 else if (eog.tagName() == "vo:preview")
1394 imageData = QByteArray::fromBase64(eog.text().toLatin1());
1395 else if (eog.tagName() == "vo:areaStructure")
1396 {
1397 for (QDomNode spo = eog.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1398 {
1399 QDomElement eo = spo.toElement();
1400 if (eo.tagName() == "uni:indents")
1401 {
1402 for (QDomNode stx = eo.firstChild(); !stx.isNull(); stx = stx.nextSibling())
1403 {
1404 QDomElement stxe = stx.toElement();
1405 if (stxe.tagName() == "uni:left")
1406 textMarginLeft = parseUnit(stxe.text());
1407 else if (stxe.tagName() == "uni:right")
1408 textMarginRight = parseUnit(stxe.text());
1409 else if (stxe.tagName() == "uni:top")
1410 textMarginTop = parseUnit(stxe.text());
1411 else if (stxe.tagName() == "uni:bottom")
1412 textMarginBottom = parseUnit(stxe.text());
1413 }
1414 }
1415 else if (eo.tagName() == "uni:columns")
1416 {
1417 for (QDomNode stx = eo.firstChild(); !stx.isNull(); stx = stx.nextSibling())
1418 {
1419 QDomElement stxe = stx.toElement();
1420 if (stxe.tagName() == "uni:distance")
1421 textColumnGap = parseUnit(stxe.text());
1422 else if (stxe.tagName() == "uni:count")
1423 textColumnCount = stxe.text().toInt();
1424 }
1425 }
1426 }
1427 }
1428 else if (eog.tagName() == "vtr:vivaText")
1429 {
1430 itemText.setDoc(m_Doc);
1431 parseTextXML(eog, itemText, textColumnCount, textColumnGap);
1432 }
1433 }
1434 }
1435 }
1436 int z = -1;
1437 if (baseType == 0)
1438 {
1439 if (ob_type == 0)
1440 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1441 else if (ob_type == 1)
1442 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1443 else if (ob_type == 2)
1444 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1445 else if (ob_type == 3)
1446 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1447 else if (ob_type == 4)
1448 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1449 }
1450 else if (baseType == 1)
1451 {
1452 if (ob_type == 0)
1453 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Rectangle, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1454 else if (ob_type == 1)
1455 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Ellipse, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1456 else if (ob_type == 2)
1457 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1458 }
1459 else if (baseType == 2)
1460 {
1461 if (ob_type == 0)
1462 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Rectangle, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1463 else if (ob_type == 1)
1464 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Ellipse, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1465 else if (ob_type == 2)
1466 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX, baseY, ob_width, ob_height, lineWidth, fillColor, strokeColor);
1467 }
1468 if (z >= 0)
1469 {
1470 PageItem* item = m_Doc->Items->at(z);
1471 item->setTextFlowMode(textFlow);
1472 if (((ob_type == 2) || (ob_type == 3) || (ob_type == 4)) && (Path.count() > 0))
1473 {
1474 item->PoLine = Path.copy();
1475 FPoint wh = getMaxClipF(&item->PoLine);
1476 item->setWidthHeight(wh.x(),wh.y());
1477 m_Doc->adjustItemSize(item, true);
1478 }
1479 item->ClipEdited = true;
1480 if ((cornerRadius != 0) && (item->frameType() == PageItem::Rectangle))
1481 {
1482 item->setCornerRadius(cornerRadius);
1483 item->SetFrameRound();
1484 }
1485 else
1486 item->FrameType = 3;
1487 if (fillTint == 0)
1488 {
1489 item->setFillColor(CommonStrings::None);
1490 item->setFillShade(100);
1491 }
1492 else
1493 {
1494 item->setFillColor(fillColor);
1495 item->setFillShade(fillTint);
1496 }
1497 if (strokeTint == 0)
1498 {
1499 item->setLineColor(CommonStrings::None);
1500 item->setLineShade(100);
1501 }
1502 else
1503 {
1504 item->setLineColor(strokeColor);
1505 item->setLineShade(strokeTint);
1506 }
1507 if (baseType == 1)
1508 item->setFillTransparency(imageOpacity);
1509 else
1510 item->setFillTransparency(fillOpacity);
1511 item->setLineTransparency(strokeOpacity);
1512 if (!fillGradient.isEmpty())
1513 {
1514 QLineF gradientVectorE;
1515 gradientVectorE.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
1516 gradientVectorE.setAngle(gradientAngle);
1517 gradientVectorE.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
1518 QPointF gradEnd = intersectBoundingRect(item, gradientVectorE);
1519 QLineF gradientVectorS;
1520 gradientVectorS.setP1(QPointF(item->width() / 2.0, item->height() / 2.0));
1521 gradientVectorS.setAngle(gradientAngle + 180);
1522 gradientVectorS.setLength(sqrt(item->width() * item->width() + item->height() * item->height()) / 2.0 + 1.0);
1523 QPointF gradStart = intersectBoundingRect(item, gradientVectorS);
1524 item->fill_gradient = m_Doc->docGradients[fillGradient];
1525 if (fillGradientTyp == 6)
1526 {
1527 item->setGradientVector(gradStart.x(), gradStart.y(), gradEnd.x(), gradEnd.y(), gradStart.x(), gradStart.y(), 1, 0);
1528 item->setGradient(fillGradient);
1529 item->setGradientType(fillGradientTyp);
1530 }
1531 else if (fillGradientTyp == 7)
1532 {
1533 QList<VColorStop*> colorStops = item->fill_gradient.colorStops();
1534 QString gradColor2Str = colorStops[0]->name;
1535 QColor gradColor2 = colorStops[0]->color;
1536 QString gradColor1Str = colorStops[1]->name;
1537 QColor gradColor1 = colorStops[1]->color;
1538 item->meshGradientPatches.clear();
1539 FPoint center = FPoint(item->width() / 2.0, item->height() / 2.0);
1540 MeshPoint cP;
1541 cP.resetTo(center);
1542 cP.transparency = 1.0;
1543 cP.shade = 100;
1544 cP.colorName = gradColor2Str;
1545 cP.color = gradColor2;
1546 for (int poi = 0; poi < item->PoLine.size()-3; poi += 4)
1547 {
1548 meshGradientPatch patch;
1549 patch.BL = cP;
1550 patch.BR = cP;
1551 if (item->PoLine.isMarker(poi))
1552 continue;
1553 MeshPoint tL;
1554 tL.resetTo(item->PoLine.point(poi));
1555 tL.controlRight = item->PoLine.point(poi + 1);
1556 tL.transparency = 1.0;
1557 tL.shade = 100;
1558 tL.colorName = gradColor1Str;
1559 tL.color = gradColor1;
1560 MeshPoint tR;
1561 tR.resetTo(item->PoLine.point(poi + 2));
1562 tR.controlLeft = item->PoLine.point(poi + 3);
1563 tR.transparency = 1.0;
1564 tR.shade = 100;
1565 tR.colorName = gradColor1Str;
1566 tR.color = gradColor1;
1567 patch.TL = tL;
1568 patch.TR = tR;
1569 item->meshGradientPatches.append(patch);
1570 }
1571 item->GrType = Gradient_PatchMesh;
1572 }
1573 else
1574 {
1575 item->GrControl1 = FPoint(0, 0);
1576 item->GrControl2 = FPoint(item->width(), 0);
1577 item->GrControl3 = FPoint(item->width(), item->height());
1578 item->GrControl4 = FPoint(0, item->height());
1579 if (gradientAngle != 0)
1580 {
1581 QLineF gradientVector = QLineF(item->width() / 2.0, item->height() / 2.0, 0, 0);
1582 gradientVector.setLength(gradientVector.length() + 1);
1583 gradientVector.setAngle(gradientVector.angle() + gradientAngle);
1584 QPointF g1 = intersectBoundingRect(item, gradientVector);
1585 item->GrControl1 = FPoint(g1.x(), g1.y());
1586 gradientVector = QLineF(item->width() / 2.0, item->height() / 2.0, item->width(), 0);
1587 gradientVector.setLength(gradientVector.length() + 1);
1588 gradientVector.setAngle(gradientVector.angle() + gradientAngle);
1589 g1 = intersectBoundingRect(item, gradientVector);
1590 item->GrControl2 = FPoint(g1.x(), g1.y());
1591 gradientVector = QLineF(item->width() / 2.0, item->height() / 2.0, item->width(), item->height());
1592 gradientVector.setLength(gradientVector.length() + 1);
1593 gradientVector.setAngle(gradientVector.angle() + gradientAngle);
1594 g1 = intersectBoundingRect(item, gradientVector);
1595 item->GrControl3 = FPoint(g1.x(), g1.y());
1596 gradientVector = QLineF(item->width() / 2.0, item->height() / 2.0, 0, item->height());
1597 gradientVector.setLength(gradientVector.length() + 1);
1598 gradientVector.setAngle(gradientVector.angle() + gradientAngle);
1599 g1 = intersectBoundingRect(item, gradientVector);
1600 item->GrControl4 = FPoint(g1.x(), g1.y());
1601 }
1602 item->GrControl5 = FPoint(item->width() / 2.0, item->height() / 2.0);
1603 item->setGradient(fillGradient);
1604 item->setGradientType(fillGradientTyp);
1605 }
1606 }
1607 item->setDashOffset(0);
1608 if (!DashValues.isEmpty())
1609 {
1610 QVector<double> pattern(DashValues.count());
1611 for (int i = 0; i < DashValues.count(); ++i)
1612 {
1613 pattern[i] = DashValues[i] * lineWidth;
1614 }
1615 item->setDashes(pattern);
1616 }
1617 else
1618 item->setLineStyle(Qt::PenStyle(LineStyle));
1619 if (ArrowLeft > 1)
1620 item->setStartArrowIndex(ArrowLeft);
1621 if (ArrowRight > 1)
1622 item->setEndArrowIndex(ArrowRight);
1623 item->setRotation(-ob_rotation, true);
1624 item->moveBy(ob_xpos, ob_ypos, true);
1625 item->setFillEvenOdd(false);
1626 item->OldB2 = item->width();
1627 item->OldH2 = item->height();
1628 item->updateClip();
1629 item->OwnPage = m_Doc->OnPage(item);
1630 item->ContourLine = item->PoLine.copy();
1631 if (hasShadow)
1632 {
1633 item->setHasSoftShadow(true);
1634 item->setSoftShadowColor(shadowColor);
1635 item->setSoftShadowXOffset(shadowX);
1636 item->setSoftShadowYOffset(shadowY);
1637 item->setSoftShadowBlurRadius(shadowBlur);
1638 item->setSoftShadowShade(shadowTint);
1639 item->setSoftShadowOpacity(shadowOpacity);
1640 item->setSoftShadowBlendMode(0);
1641 item->setSoftShadowErasedByObject(shadowErase);
1642 item->setSoftShadowHasObjectTransparency(shadowObjTrans);
1643 }
1644 if (baseType == 1)
1645 {
1646 item->AspectRatio = true;
1647 item->ScaleType = false;
1648 bool erf = m_Doc->loadPict(imageFile, item);
1649 if (!erf)
1650 {
1651 if (!imageData.isEmpty())
1652 {
1653 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_viva_XXXXXX.png");
1654 tempFile->setAutoRemove(false);
1655 if (tempFile->open())
1656 {
1657 QString fileName = getLongPathName(tempFile->fileName());
1658 if (!fileName.isEmpty())
1659 {
1660 tempFile->write(imageData);
1661 tempFile->close();
1662 item->isInlineImage = true;
1663 item->isTempFile = true;
1664 item->AspectRatio = true;
1665 item->ScaleType = false;
1666 m_Doc->loadPict(fileName, item);
1667 }
1668 }
1669 delete tempFile;
1670 }
1671 }
1672 item->setImageXYScale(imageScaleX / item->pixm.imgInfo.xres * 72, imageScaleX / item->pixm.imgInfo.xres * 72);
1673 item->setImageXYOffset(imageXoffs / item->imageXScale(), imageYoffs / item->imageYScale());
1674 }
1675 else if (baseType == 2)
1676 {
1677 item->setTextToFrameDist(textMarginLeft, textMarginRight, textMarginTop, textMarginBottom);
1678 item->setColumns(textColumnCount);
1679 item->setColumnGap(textColumnGap);
1680 if (itemText.length() > 0)
1681 item->itemText.append(itemText);
1682 item->itemText.trim();
1683 }
1684 item->setLocked(locked);
1685 item->setSizeLocked(resizable);
1686 item->setPrintEnabled(printable);
1687 retObj = m_Doc->Items->takeAt(z);
1688 }
1689 return retObj;
1690 }
1691
parseTextXML(const QDomElement & obNode,StoryText & itemText,int & textColumnCount,double & textColumnGap)1692 void VivaPlug::parseTextXML(const QDomElement& obNode, StoryText &itemText, int &textColumnCount, double &textColumnGap)
1693 {
1694 QString pStyle = CommonStrings::DefaultParagraphStyle;
1695 ParagraphStyle newStyle;
1696 newStyle.setDefaultStyle(false);
1697 newStyle.setParent(pStyle);
1698 ParagraphStyle ttx = m_Doc->paragraphStyle(pStyle);
1699 CharStyle nstyle = ttx.charStyle();
1700 newStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
1701 newStyle.setLineSpacing(nstyle.fontSize() / 10.0);
1702 itemText.setDefaultStyle(newStyle);
1703 int posC = 0;
1704 for (QDomNode spo = obNode.firstChild(); !spo.isNull(); spo = spo.nextSibling())
1705 {
1706 QDomElement eo = spo.toElement();
1707 if (eo.tagName() == "vs:stylesheets")
1708 parseStylesheetsXML(eo);
1709 else if (eo.tagName() == "vs:attribute-sets")
1710 parseAttributeSetsXML(eo);
1711 else if (eo.tagName() == "vt:story")
1712 {
1713 if (eo.hasAttribute("vt:story-attribute-set"))
1714 {
1715 applyParagraphAttrs(newStyle, AttributeSets[eo.attribute("vt:story-attribute-set")]);
1716 applyCharacterAttrs(newStyle.charStyle(), newStyle, AttributeSets[eo.attribute("vt:story-attribute-set")]);
1717 }
1718 for (QDomNode stx = eo.firstChild(); !stx.isNull(); stx = stx.nextSibling())
1719 {
1720 QDomElement stxe = stx.toElement();
1721 if (stxe.tagName() == "vt:chapter")
1722 {
1723 for (QDomNode st = stxe.firstChild(); !st.isNull(); st = st.nextSibling())
1724 {
1725 QDomElement ste = st.toElement();
1726 if (ste.tagName() == "vt:layout")
1727 {
1728 if (ste.hasAttribute("vt:layout-attribute-set"))
1729 {
1730 AttributeSet attrs = AttributeSets[ste.attribute("vt:layout-attribute-set")];
1731 if (attrs.columnCount.valid)
1732 textColumnCount = attrs.columnCount.value.toInt();
1733 if (attrs.columnGutter.valid)
1734 textColumnGap = attrs.columnGutter.value.toDouble();
1735 }
1736 for (QDomNode stc = ste.firstChild(); !stc.isNull(); stc = stc.nextSibling())
1737 {
1738 QDomElement stce = stc.toElement();
1739 if (stce.tagName() == "vt:p")
1740 {
1741 ParagraphStyle tmpStyle = newStyle;
1742 if (stce.hasAttribute("vt:paragraph-attribute-set"))
1743 {
1744 if (AttributeSets.contains(stce.attribute("vt:paragraph-attribute-set")))
1745 applyParagraphAttrs(tmpStyle, AttributeSets[stce.attribute("vt:paragraph-attribute-set")]);
1746 else if (m_Doc->styleExists(stce.attribute("vt:paragraph-attribute-set")))
1747 tmpStyle = m_Doc->paragraphStyle(stce.attribute("vt:paragraph-attribute-set"));
1748 }
1749 for (QDomNode stces = stce.firstChild(); !stces.isNull(); stces = stces.nextSibling())
1750 {
1751 QDomElement stcet = stces.toElement();
1752 if (stcet.tagName() == "vt:span")
1753 {
1754 CharStyle tmpCStyle = tmpStyle.charStyle();
1755 if (stcet.hasAttribute("vt:character-attribute-set"))
1756 applyCharacterAttrs(tmpCStyle, tmpStyle, AttributeSets[stcet.attribute("vt:character-attribute-set")]);
1757 for (QDomNode stcesp = stcet.firstChild(); !stcesp.isNull(); stcesp = stcesp.nextSibling())
1758 {
1759 QDomElement stcespt = stcesp.toElement();
1760 int count = stcespt.text().length();
1761 if (stcespt.tagName() == "vt:plain-text")
1762 itemText.insertChars(posC, stcespt.text());
1763 else if (stcespt.tagName() == "vt:lf")
1764 {
1765 count = 1;
1766 itemText.insertChars(posC, SpecialChars::LINEBREAK);
1767 }
1768 else if (stcespt.tagName() == "vt:soft-hyphen")
1769 {
1770 count = 1;
1771 itemText.insertChars(posC, SpecialChars::SHYPHEN);
1772 }
1773 else if (stcespt.tagName() == "vt:space")
1774 {
1775 if (stcespt.attribute("vt:br") == "false")
1776 {
1777 count = 1;
1778 itemText.insertChars(posC, SpecialChars::NBSPACE);
1779 }
1780 }
1781 else if (stcespt.tagName() == "vt:variable")
1782 {
1783 if (stcespt.attribute("vt:type") == "Viva Technology/Page Number")
1784 {
1785 count = 1;
1786 itemText.insertChars(posC, SpecialChars::PAGENUMBER);
1787 }
1788 else if (stcespt.attribute("vt:type") == "Viva Technology/Number of Pages")
1789 {
1790 count = 1;
1791 itemText.insertChars(posC, SpecialChars::PAGECOUNT);
1792 }
1793 /* else if (stcespt.attribute("vt:type") == "Viva Technology/TextEngine/Date")
1794 {
1795 QDomNode anc = stcespt.firstChild();
1796 QDomElement anco = anc.toElement();
1797 if (anco.tagName() == "uni:data")
1798 {
1799 QByteArray data;
1800 if (anco.hasAttribute("uni:encoder") && (anco.attribute("uni:encoder") == "base64"))
1801 data = QByteArray::fromBase64(anco.text().toLatin1());
1802 else
1803 data = anco.text().toLatin1();
1804 QByteArray decomdata;
1805 if (anco.hasAttribute("uni:compressor") && (anco.attribute("uni:compressor") == "zlib/deflate"))
1806 decomdata = qUncompress(data);
1807 else
1808 decomdata = data;
1809 }
1810 } */
1811 }
1812 else if (stcespt.tagName() == "vt:anchoring-object")
1813 {
1814 for (QDomNode anc = stcespt.firstChild(); !anc.isNull(); anc = anc.nextSibling())
1815 {
1816 QDomElement anco = anc.toElement();
1817 if (anco.tagName() == "vo:object")
1818 {
1819 PageItem* item = parseObjectXML(anco);
1820 if (item != nullptr)
1821 {
1822 item->isEmbedded = true;
1823 item->gXpos = 0;
1824 item->gYpos = 0;
1825 item->gWidth = item->width();
1826 item->gHeight = item->height();
1827 int fIndex = m_Doc->addToInlineFrames(item);
1828 itemText.insertObject(fIndex);
1829 }
1830 }
1831 }
1832 count = 1;
1833 }
1834 else if (stcespt.tagName() == "vt:tab")
1835 {
1836 count = 1;
1837 itemText.insertChars(posC, SpecialChars::TAB);
1838 }
1839 if (count != 0)
1840 {
1841 itemText.applyStyle(posC, tmpStyle);
1842 itemText.applyCharStyle(posC, count, tmpCStyle);
1843 }
1844 posC = itemText.length();
1845 }
1846 }
1847 }
1848 if (stce.attribute("vt:break") == "paragraph-break")
1849 itemText.insertChars(posC, SpecialChars::PARSEP);
1850 else if (stce.attribute("vt:break") == "layout-column-break")
1851 itemText.insertChars(posC, SpecialChars::COLBREAK);
1852 else if (stce.attribute("vt:break") == "area-break")
1853 itemText.insertChars(posC, SpecialChars::FRAMEBREAK);
1854 else
1855 itemText.insertChars(posC, SpecialChars::PARSEP);
1856 itemText.applyStyle(posC, tmpStyle);
1857 posC = itemText.length();
1858 }
1859 }
1860 }
1861 }
1862 }
1863 }
1864 }
1865 }
1866 }
1867
parseAttributeSetXML(const QDomElement & obNode,AttributeSet & attrs)1868 void VivaPlug::parseAttributeSetXML(const QDomElement& obNode, AttributeSet &attrs)
1869 {
1870 if (obNode.tagName() == "vs:template")
1871 attrs.parentStyle = obNode.text();
1872 for (QDomNode stx = obNode.firstChild(); !stx.isNull(); stx = stx.nextSibling())
1873 {
1874 QDomElement stxe = stx.toElement();
1875 if (stxe.tagName() == "vta:font")
1876 {
1877 if (stxe.hasAttribute("vta:family"))
1878 attrs.fontFamily = AttributeValue(stxe.attribute("vta:family"));
1879 if (stxe.hasAttribute("vta:style"))
1880 attrs.fontStyle = AttributeValue(stxe.attribute("vta:style"));
1881 }
1882 else if (stxe.tagName() == "vta:font-size")
1883 {
1884 if (stxe.hasAttribute("vta:value"))
1885 attrs.fontSize = AttributeValue(stxe.attribute("vta:value"));
1886 }
1887 else if (stxe.tagName() == "vta:character-color")
1888 {
1889 if (stxe.hasAttribute("vta:name"))
1890 attrs.fontColor = AttributeValue(colorTranslate[stxe.attribute("vta:name")]);
1891 }
1892 else if (stxe.tagName() == "vta:character-color-density")
1893 {
1894 if (stxe.hasAttribute("vta:value"))
1895 attrs.fontColorDensity = AttributeValue(stxe.attribute("vta:value"));
1896 }
1897 else if (stxe.tagName() == "vta:character-type")
1898 {
1899 if (stxe.hasAttribute("vta:type"))
1900 attrs.fontEffect = AttributeValue(stxe.attribute("vta:type"));
1901 }
1902 else if (stxe.tagName() == "vta:character-placement")
1903 {
1904 if (stxe.hasAttribute("vta:type"))
1905 attrs.placement = AttributeValue(stxe.attribute("vta:type"));
1906 }
1907 else if (stxe.tagName() == "vta:underline")
1908 {
1909 attrs.underline = AttributeValue("true");
1910 attrs.underlineOffset = AttributeValue(stxe.attribute("vta:offset"));
1911 QDomNode ul = stxe.firstChild();
1912 if (!ul.isNull())
1913 {
1914 QDomElement ule = ul.toElement();
1915 if (ule.tagName() == "vta:pen")
1916 attrs.underlineWidth = AttributeValue(ule.attribute("vta:width"));
1917 }
1918 }
1919 else if (stxe.tagName() == "vta:strikethrough")
1920 {
1921 attrs.strikethrough = AttributeValue("true");
1922 attrs.strikethroughOffset = AttributeValue(stxe.attribute("vta:offset"));
1923 QDomNode ul = stxe.firstChild();
1924 if (!ul.isNull())
1925 {
1926 QDomElement ule = ul.toElement();
1927 if (ule.tagName() == "vta:pen")
1928 attrs.strikethroughWidth = AttributeValue(ule.attribute("vta:width"));
1929 }
1930 }
1931 else if (stxe.tagName() == "vta:character-outline")
1932 {
1933 if (stxe.attribute("vta:active") == "true")
1934 {
1935 attrs.outline = AttributeValue("true");
1936 QDomNode ul = stxe.firstChild();
1937 if (!ul.isNull())
1938 {
1939 QDomElement ule = ul.toElement();
1940 if (ule.tagName() == "vta:pen")
1941 {
1942 attrs.outlineWidth = AttributeValue(ule.attribute("vta:width"));
1943 attrs.outlineColor = AttributeValue(colorTranslate[ule.attribute("vta:color")]);
1944 }
1945 }
1946 }
1947 }
1948 else if (stxe.tagName() == "vta:character-width-scale")
1949 {
1950 if (stxe.hasAttribute("vta:value"))
1951 attrs.widthScale = AttributeValue(stxe.attribute("vta:value"));
1952 }
1953 else if (stxe.tagName() == "vta:character-height-scale")
1954 {
1955 if (stxe.hasAttribute("vta:value"))
1956 attrs.heightScale = AttributeValue(stxe.attribute("vta:value"));
1957 }
1958 else if ((stxe.tagName() == "vta:character-spacing") || (stxe.tagName() == "vta:kerning"))
1959 {
1960 if (stxe.hasAttribute("vta:value"))
1961 attrs.spacing = AttributeValue(stxe.attribute("vta:value"));
1962 }
1963 else if (stxe.tagName() == "vta:baseline-shift")
1964 {
1965 if (stxe.hasAttribute("vta:value"))
1966 attrs.baselineOffset = AttributeValue(stxe.attribute("vta:value"));
1967 }
1968 else if (stxe.tagName() == "vta:writing-justification")
1969 {
1970 if (stxe.hasAttribute("vta:value"))
1971 attrs.justification = AttributeValue(stxe.attribute("vta:value"));
1972 }
1973 else if (stxe.tagName() == "vta:paragraph-distance-before")
1974 {
1975 if (stxe.hasAttribute("vta:value"))
1976 attrs.gapbefore = AttributeValue(stxe.attribute("vta:value"));
1977 }
1978 else if (stxe.tagName() == "vta:paragraph-distance-after")
1979 {
1980 if (stxe.hasAttribute("vta:value"))
1981 attrs.gapafter = AttributeValue(stxe.attribute("vta:value"));
1982 }
1983 else if (stxe.tagName() == "vta:line-distance")
1984 {
1985 if (stxe.hasAttribute("vta:value"))
1986 attrs.lineSpacing = AttributeValue(stxe.attribute("vta:value"));
1987 }
1988 else if (stxe.tagName() == "vta:paragraph-indent")
1989 {
1990 if (stxe.hasAttribute("vta:value"))
1991 attrs.firstLineIndent = AttributeValue(stxe.attribute("vta:value"));
1992 }
1993 else if (stxe.tagName() == "vta:paragraph-begin-indent")
1994 {
1995 if (stxe.hasAttribute("vta:value"))
1996 attrs.indent = AttributeValue(stxe.attribute("vta:value"));
1997 }
1998 else if (stxe.tagName() == "vta:paragraph-end-indent")
1999 {
2000 if (stxe.hasAttribute("vta:value"))
2001 attrs.rightIndent = AttributeValue(stxe.attribute("vta:value"));
2002 }
2003 else if (stxe.tagName() == "vta:layout-columns")
2004 {
2005 int columnCount = 0;
2006 double columnGutter = 0.0;
2007 for (QDomNode stc = stxe.firstChild(); !stc.isNull(); stc = stc.nextSibling())
2008 {
2009 QDomElement stce = stc.toElement();
2010 if (stce.tagName() == "vta:column")
2011 {
2012 columnCount++;
2013 columnGutter = qMax(columnGutter, parseUnit(stce.attribute("vta:gutter", "0")));
2014 }
2015 }
2016 if (columnCount > 0)
2017 {
2018 attrs.columnCount = AttributeValue(QString("%1").arg(columnCount));
2019 attrs.columnGutter = AttributeValue(QString("%1").arg(columnGutter));
2020 }
2021 }
2022 else if (stxe.tagName() == "vta:initials")
2023 {
2024 if (stxe.attribute("vta:active") == "true")
2025 {
2026 attrs.dropCaps = AttributeValue("true");
2027 attrs.dropCapsDist = AttributeValue(stxe.attribute("vta:distance-to-text", "0"));
2028 for (QDomNode stc = stxe.firstChild(); !stc.isNull(); stc = stc.nextSibling())
2029 {
2030 QDomElement stce = stc.toElement();
2031 if (stce.tagName() == "vta:size")
2032 {
2033 QDomNode ul = stce.firstChild();
2034 if (!ul.isNull())
2035 {
2036 QDomElement ule = ul.toElement();
2037 if (ule.tagName() == "vta:dynamic-lines")
2038 {
2039 attrs.dropCapsLines = AttributeValue(ule.attribute("vta:maximum-lines", "1"));
2040 }
2041 }
2042 }
2043 }
2044 }
2045 }
2046 else if (stxe.tagName() == "vta:tabulators")
2047 {
2048 QString tabs = "";
2049 for (QDomNode stc = stxe.firstChild(); !stc.isNull(); stc = stc.nextSibling())
2050 {
2051 QDomElement stce = stc.toElement();
2052 if (stce.tagName() == "vta:tabulator")
2053 {
2054 if (stce.hasAttribute("vta:position"))
2055 tabs += stce.attribute("vta:position");
2056 tabs += "\t";
2057 if (stce.hasAttribute("vta:alignment"))
2058 tabs += stce.attribute("vta:alignment");
2059 tabs += "\t";
2060 if (stce.hasAttribute("vta:filler"))
2061 tabs += stce.attribute("vta:filler");
2062 }
2063 tabs += "\n";
2064 }
2065 attrs.tabulators = AttributeValue(tabs);
2066 }
2067 }
2068 if ((attrs.fontFamily.valid) && (attrs.fontStyle.valid))
2069 attrs.fontFullName = AttributeValue(constructFontName(attrs.fontFamily.value, attrs.fontStyle.value));
2070 }
2071
parseAttributeSetsXML(const QDomElement & obNode)2072 void VivaPlug::parseAttributeSetsXML(const QDomElement& obNode)
2073 {
2074 for (QDomNode spo = obNode.firstChild(); !spo.isNull(); spo = spo.nextSibling())
2075 {
2076 QDomElement eo = spo.toElement();
2077 AttributeSet attrs;
2078 parseAttributeSetXML(eo, attrs);
2079 if (eo.hasAttribute("vs:paragraph-style"))
2080 attrs.applyedParStyle = AttributeValue(eo.attribute("vs:paragraph-style"));
2081 AttributeSets.insert(eo.attribute("vs:name"), attrs);
2082 }
2083 }
2084
parseStylesheetsXML(const QDomElement & obNode)2085 void VivaPlug::parseStylesheetsXML(const QDomElement& obNode)
2086 {
2087 for (QDomNode spo = obNode.firstChild(); !spo.isNull(); spo = spo.nextSibling())
2088 {
2089 QDomElement eo = spo.toElement();
2090 if (eo.tagName() == "vs:paragraphStylesheet")
2091 {
2092 ParagraphStyle newStyle;
2093 newStyle.erase();
2094 newStyle.setDefaultStyle(false);
2095 newStyle.setName(eo.attribute("vs:name"));
2096 newStyle.setParent(CommonStrings::DefaultParagraphStyle);
2097 ParagraphStyle ttx = m_Doc->paragraphStyle(CommonStrings::DefaultParagraphStyle);
2098 CharStyle nstyle = ttx.charStyle();
2099 newStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
2100 newStyle.setLineSpacing(nstyle.fontSize() / 10.0);
2101 AttributeSet attrs;
2102 for (QDomNode stx = eo.firstChild(); !stx.isNull(); stx = stx.nextSibling())
2103 {
2104 QDomElement stxe = stx.toElement();
2105 parseAttributeSetXML(stxe, attrs);
2106 }
2107 applyParagraphAttrs(newStyle, attrs);
2108 applyCharacterAttrs(newStyle.charStyle(), newStyle, attrs);
2109 StyleSet<ParagraphStyle>tmp;
2110 tmp.create(newStyle);
2111 m_Doc->redefineStyles(tmp, false);
2112 }
2113 }
2114 }
2115
applyParagraphAttrs(ParagraphStyle & newStyle,AttributeSet & pAttrs)2116 void VivaPlug::applyParagraphAttrs(ParagraphStyle &newStyle, AttributeSet &pAttrs)
2117 {
2118 if (pAttrs.applyedParStyle.valid)
2119 newStyle = m_Doc->paragraphStyle(pAttrs.applyedParStyle.value);
2120 if (pAttrs.parentStyle.valid)
2121 newStyle.setParent(pAttrs.parentStyle.value);
2122 if (pAttrs.justification.valid)
2123 {
2124 if (pAttrs.justification.value == "left")
2125 newStyle.setAlignment(ParagraphStyle::LeftAligned);
2126 else if (pAttrs.justification.value == "right")
2127 newStyle.setAlignment(ParagraphStyle::RightAligned);
2128 else if (pAttrs.justification.value == "center")
2129 newStyle.setAlignment(ParagraphStyle::Centered);
2130 else if (pAttrs.justification.value == "justified")
2131 newStyle.setAlignment(ParagraphStyle::Justified);
2132 else if (pAttrs.justification.value == "forced-justified")
2133 newStyle.setAlignment(ParagraphStyle::Extended);
2134 }
2135 if (pAttrs.gapbefore.valid)
2136 newStyle.setGapBefore(parseUnit(pAttrs.gapbefore.value));
2137 if (pAttrs.gapafter.valid)
2138 newStyle.setGapAfter(parseUnit(pAttrs.gapafter.value));
2139 if (pAttrs.lineSpacing.valid)
2140 {
2141 newStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
2142 newStyle.setLineSpacing(parseUnit(pAttrs.lineSpacing.value));
2143 }
2144 else
2145 newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
2146 if (pAttrs.firstLineIndent.valid)
2147 newStyle.setFirstIndent(parseUnit(pAttrs.firstLineIndent.value));
2148 if (pAttrs.indent.valid)
2149 {
2150 newStyle.setLeftMargin(parseUnit(pAttrs.indent.value));
2151 newStyle.setFirstIndent(newStyle.firstIndent() - parseUnit(pAttrs.indent.value));
2152 }
2153 if (pAttrs.rightIndent.valid)
2154 newStyle.setRightMargin(parseUnit(pAttrs.rightIndent.value));
2155 if (pAttrs.dropCaps.valid)
2156 {
2157 newStyle.setHasDropCap(true);
2158 if (pAttrs.dropCapsLines.valid)
2159 newStyle.setDropCapLines(pAttrs.dropCapsLines.value.toInt());
2160 if (pAttrs.dropCapsDist.valid)
2161 newStyle.setParEffectOffset(parseUnit(pAttrs.dropCapsDist.value));
2162 }
2163 if (pAttrs.tabulators.valid)
2164 {
2165 QList<ParagraphStyle::TabRecord> tbs;
2166 newStyle.resetTabValues();
2167 QStringList tabList = pAttrs.tabulators.value.split("\n");
2168 for (int a = 0; a < tabList.count(); a++)
2169 {
2170 QString tbv = tabList[a];
2171 if (!tbv.isEmpty())
2172 {
2173 ParagraphStyle::TabRecord tb;
2174 QStringList tab = tbv.split("\t");
2175 tb.tabPosition = parseUnit(tab[0]);
2176 tb.tabType = 0;
2177 if (tab[1] == "begin")
2178 tb.tabType = 0;
2179 else if (tab[1] == "center")
2180 tb.tabType = 4;
2181 else if (tab[1] == "end")
2182 tb.tabType = 1;
2183 else if (tab[1] == "character")
2184 tb.tabType = 3;
2185 tb.tabFillChar = tab[2].isEmpty() ? QChar() : tab[2][0];
2186 tbs.append(tb);
2187 }
2188 }
2189 if (tbs.count() > 0)
2190 newStyle.setTabValues(tbs);
2191 }
2192 }
2193
applyCharacterAttrs(CharStyle & tmpCStyle,ParagraphStyle & newStyle,AttributeSet & pAttrs)2194 void VivaPlug::applyCharacterAttrs(CharStyle &tmpCStyle, ParagraphStyle &newStyle, AttributeSet &pAttrs)
2195 {
2196 if (pAttrs.fontSize.valid)
2197 {
2198 tmpCStyle.setFontSize(pAttrs.fontSize.value.toDouble() * 10);
2199 if (pAttrs.lineSpacing.valid)
2200 {
2201 if (pAttrs.fontSize.value.toInt() > parseUnit(pAttrs.lineSpacing.value))
2202 newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
2203 }
2204 }
2205 if (pAttrs.fontFullName.valid)
2206 tmpCStyle.setFont((*m_Doc->AllFonts)[pAttrs.fontFullName.value]);
2207 if (pAttrs.fontColor.valid)
2208 tmpCStyle.setFillColor(pAttrs.fontColor.value);
2209 if (pAttrs.fontColorDensity.valid)
2210 {
2211 int tint = 100;
2212 if (pAttrs.fontColorDensity.value == "transparent")
2213 tint = 0;
2214 else
2215 tint = pAttrs.fontColorDensity.value.toInt();
2216 tmpCStyle.setFillShade(tint);
2217 }
2218 if (pAttrs.underline.valid)
2219 {
2220 if (pAttrs.underlineWidth.valid)
2221 tmpCStyle.setUnderlineWidth(qRound(parseUnit(pAttrs.underlineWidth.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2222 else
2223 tmpCStyle.setUnderlineWidth(-1);
2224 if (pAttrs.underlineOffset.valid)
2225 {
2226 if (parseUnit(pAttrs.underlineOffset.value) != 0)
2227 tmpCStyle.setUnderlineOffset(qRound(parseUnit(pAttrs.underlineOffset.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2228 else
2229 tmpCStyle.setUnderlineOffset(-1);
2230 }
2231 else
2232 tmpCStyle.setUnderlineOffset(-1);
2233 StyleFlag styleEffects = tmpCStyle.effects();
2234 styleEffects |= ScStyle_Underline;
2235 tmpCStyle.setFeatures(styleEffects.featureList());
2236 }
2237 if (pAttrs.strikethrough.valid)
2238 {
2239 if (pAttrs.strikethroughWidth.valid)
2240 tmpCStyle.setStrikethruWidth(qRound(parseUnit(pAttrs.strikethroughWidth.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2241 else
2242 tmpCStyle.setStrikethruWidth(-1);
2243 if (pAttrs.strikethroughOffset.valid)
2244 {
2245 if (parseUnit(pAttrs.strikethroughOffset.value) != 0)
2246 tmpCStyle.setStrikethruOffset(qRound(parseUnit(pAttrs.strikethroughOffset.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2247 else
2248 tmpCStyle.setStrikethruOffset(-1);
2249 }
2250 else
2251 tmpCStyle.setStrikethruOffset(-1);
2252 StyleFlag styleEffects = tmpCStyle.effects();
2253 styleEffects |= ScStyle_Strikethrough;
2254 tmpCStyle.setFeatures(styleEffects.featureList());
2255 }
2256 if (pAttrs.outline.valid)
2257 {
2258 if (pAttrs.outlineWidth.valid)
2259 tmpCStyle.setOutlineWidth(qRound(parseUnit(pAttrs.outlineWidth.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2260 else
2261 tmpCStyle.setOutlineWidth(-1);
2262 if (pAttrs.outlineColor.valid)
2263 tmpCStyle.setStrokeColor(pAttrs.outlineColor.value);
2264 StyleFlag styleEffects = tmpCStyle.effects();
2265 styleEffects |= ScStyle_Outline;
2266 tmpCStyle.setFeatures(styleEffects.featureList());
2267 }
2268 if (pAttrs.placement.valid)
2269 {
2270 StyleFlag styleEffects = tmpCStyle.effects();
2271 if ((pAttrs.placement.value == "superscript") || (pAttrs.placement.value == "index"))
2272 styleEffects |= ScStyle_Superscript;
2273 else if (pAttrs.placement.value == "subscript")
2274 styleEffects |= ScStyle_Subscript;
2275 tmpCStyle.setFeatures(styleEffects.featureList());
2276 }
2277 if (pAttrs.fontEffect.valid)
2278 {
2279 StyleFlag styleEffects = tmpCStyle.effects();
2280 if (pAttrs.fontEffect.value == "caps")
2281 styleEffects |= ScStyle_AllCaps;
2282 else if (pAttrs.fontEffect.value == "small-caps")
2283 styleEffects |= ScStyle_SmallCaps;
2284 tmpCStyle.setFeatures(styleEffects.featureList());
2285 }
2286 if (pAttrs.widthScale.valid)
2287 tmpCStyle.setScaleH(pAttrs.widthScale.value.toInt() * 10);
2288 if (pAttrs.heightScale.valid)
2289 tmpCStyle.setScaleV(pAttrs.heightScale.value.toInt() * 10);
2290 if (pAttrs.spacing.valid)
2291 tmpCStyle.setTracking(pAttrs.spacing.value.toInt() * 10);
2292 if (pAttrs.baselineOffset.valid)
2293 {
2294 if (parseUnit(pAttrs.baselineOffset.value) != 0)
2295 tmpCStyle.setBaselineOffset(qRound(parseUnit(pAttrs.baselineOffset.value) * 1000 / (tmpCStyle.fontSize() / 10.0)));
2296 }
2297 }
2298
constructFontName(const QString & fontBaseName,const QString & fontStyle)2299 QString VivaPlug::constructFontName(const QString& fontBaseName, const QString& fontStyle)
2300 {
2301 QString fontName = "";
2302 bool found = false;
2303 SCFontsIterator it(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts);
2304 for ( ; it.hasNext(); it.next())
2305 {
2306 if (fontBaseName.toLower() == it.current().family().toLower())
2307 {
2308 // found the font family, now go for the style
2309 QStringList slist = PrefsManager::instance().appPrefs.fontPrefs.AvailFonts.fontMap[it.current().family()];
2310 slist.sort();
2311 if (slist.count() > 0)
2312 {
2313 for (int a = 0; a < slist.count(); a++)
2314 {
2315 if (fontStyle.toLower() == slist[a].toLower())
2316 {
2317 found = true;
2318 fontName = it.current().family() + " " + slist[a];
2319 break;
2320 }
2321 }
2322 if (!found)
2323 {
2324 int reInd = slist.indexOf("Regular");
2325 if (reInd < 0)
2326 fontName = it.current().family() + " " + slist[0];
2327 else
2328 fontName = it.current().family() + " " + slist[reInd];
2329 found = true;
2330 }
2331 }
2332 else
2333 {
2334 fontName = it.current().family();
2335 found = true;
2336 }
2337 break;
2338 }
2339 }
2340 if (!found)
2341 {
2342 if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
2343 fontName = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
2344 else
2345 {
2346 QString family = fontBaseName;
2347 if (!fontStyle.isEmpty())
2348 family += " " + fontStyle;
2349 if (!PrefsManager::instance().appPrefs.fontPrefs.GFontSub.contains(family))
2350 {
2351 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
2352 MissingFont *dia = new MissingFont(nullptr, family, m_Doc);
2353 dia->exec();
2354 fontName = dia->getReplacementFont();
2355 delete dia;
2356 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
2357 PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family] = fontName;
2358 }
2359 else
2360 fontName = PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family];
2361 }
2362 }
2363 return fontName;
2364 }
2365
intersectBoundingRect(PageItem * item,QLineF gradientVector)2366 QPointF VivaPlug::intersectBoundingRect(PageItem *item, QLineF gradientVector)
2367 {
2368 QPointF interPoint;
2369 QPointF gradEnd;
2370 if (gradientVector.intersects(QLineF(0, 0, item->width(), 0), &interPoint) == QLineF::BoundedIntersection)
2371 gradEnd = interPoint;
2372 else if (gradientVector.intersects(QLineF(item->width(), 0, item->width(), item->height()), &interPoint) == QLineF::BoundedIntersection)
2373 gradEnd = interPoint;
2374 else if (gradientVector.intersects(QLineF(item->width(), item->height(), 0, item->height()), &interPoint) == QLineF::BoundedIntersection)
2375 gradEnd = interPoint;
2376 else if (gradientVector.intersects(QLineF(0, item->height(), 0, 0), &interPoint) == QLineF::BoundedIntersection)
2377 gradEnd = interPoint;
2378 return gradEnd;
2379 }
2380