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 : Sat Jan 14 2012
10 copyright : (C) 2012 by Franz Schmid
11 email : Franz.Schmid@altmuehlnet.de
12 ***************************************************************************/
13
14 #include <QByteArray>
15 #include <QCursor>
16 #include <QDebug>
17 #include <QDrag>
18 #include <QFile>
19 #include <QList>
20 #include <QMimeData>
21 #include <QRegExp>
22 #include <QScopedPointer>
23 #include <QStack>
24 #include <QUrl>
25
26 #if defined(_MSC_VER) && !defined(_USE_MATH_DEFINES)
27 #define _USE_MATH_DEFINES
28 #endif
29
30 #include <cstdlib>
31 #include <climits>
32 #include <limits>
33
34 #include "importidml.h"
35
36 #include "commonstrings.h"
37 #include "guidemanagercore.h"
38 #include "loadsaveplugin.h"
39 #include "pageitem_table.h"
40 #include "pagesize.h"
41 #include "prefscontext.h"
42 #include "prefsfile.h"
43 #include "prefsmanager.h"
44 #include "prefstable.h"
45 #include "rawimage.h"
46 #include "scclocale.h"
47 #include "sccolorengine.h"
48 #include "scconfig.h"
49 #include "scmimedata.h"
50 #include "scpaths.h"
51 #include "scribusXml.h"
52 #include "scribuscore.h"
53 #include "scribusdoc.h"
54 #include "scribusview.h"
55 #include "sctextstream.h"
56 #include "selection.h"
57 #include "ui/customfdialog.h"
58 #include "ui/missing.h"
59 #include "ui/multiprogressdialog.h"
60 #include "ui/propertiespalette.h"
61 #include "undomanager.h"
62 #include "util.h"
63 #include "util_formats.h"
64 #include "util_math.h"
65
IdmlPlug(ScribusDoc * doc,int flags)66 IdmlPlug::IdmlPlug(ScribusDoc* doc, int flags)
67 {
68 tmpSel = new Selection(this, false);
69 m_Doc = doc;
70 importerFlags = flags;
71 interactive = (flags & LoadSavePlugin::lfInteractive);
72 progressDialog = nullptr;
73 m_zip = nullptr;
74 }
75
getNodeValue(QDomNode & baseNode,const QString & path)76 QString IdmlPlug::getNodeValue(QDomNode &baseNode, const QString& path)
77 {
78 QString ret;
79 QStringList pathParts = path.split("/", Qt::SkipEmptyParts);
80 QDomNode n = baseNode.namedItem(pathParts[0]);
81 if (n.isNull())
82 return QString();
83
84 bool fail = false;
85 for (int a = 1; a < pathParts.count(); a++)
86 {
87 n = n.namedItem(pathParts[a]);
88 if (n.isNull())
89 {
90 fail = true;
91 break;
92 }
93 }
94 if (!fail)
95 {
96 QDomElement e = n.toElement();
97 if (!e.isNull())
98 ret = e.text();
99 }
100 return ret;
101 }
102
readThumbnail(const QString & fName)103 QImage IdmlPlug::readThumbnail(const QString& fName)
104 {
105 QImage tmp;
106 QByteArray f;
107 if ( !QFile::exists(fName) )
108 return QImage();
109 QFileInfo fi = QFileInfo(fName);
110 QString ext = fi.suffix().toLower();
111 if (ext == "idml")
112 {
113 m_zip = new ScZipHandler();
114 if (!m_zip->open(fName))
115 {
116 delete m_zip;
117 m_zip = nullptr;
118 return QImage();
119 }
120 if (m_zip->contains("designmap.xml"))
121 m_zip->read("designmap.xml", f);
122 delete m_zip;
123 m_zip = nullptr;
124 }
125 else if (ext == "idms")
126 {
127 loadRawText(fName, f);
128 }
129
130 if (f.isEmpty())
131 return QImage();
132
133 if (!designMapDom.setContent(f))
134 return QImage();
135
136 bool found = false;
137 QDomElement docElem = designMapDom.documentElement();
138 QString metaD = getNodeValue(docElem, "MetadataPacketPreference/Properties/Contents");
139 QDomDocument rdfD;
140 rdfD.setContent(metaD);
141 QDomElement docElemR = rdfD.documentElement();
142 for (QDomNode drawPag = docElemR.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
143 {
144 QDomElement dpg = drawPag.toElement();
145 if (dpg.tagName() == "rdf:RDF")
146 {
147 for (QDomNode drawPag2 = dpg.firstChild(); !drawPag2.isNull(); drawPag2 = drawPag2.nextSibling())
148 {
149 QDomElement dpg2 = drawPag2.toElement();
150 if (dpg2.hasAttribute("xmlns:xmpGImg"))
151 {
152 QByteArray imgD = getNodeValue(dpg2, "xmp:Thumbnails/rdf:Alt/rdf:li/xmpGImg:image").toLatin1();
153 QByteArray inlineImageData = QByteArray::fromBase64(imgD);
154 tmp.loadFromData(inlineImageData);
155 found = true;
156 }
157 }
158 }
159 }
160 if (!found)
161 {
162 progressDialog = nullptr;
163 QFileInfo fi = QFileInfo(fName);
164 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
165 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
166 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
167 m_Doc = new ScribusDoc();
168 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
169 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
170 m_Doc->addPage(0);
171 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
172 baseX = m_Doc->currentPage()->xOffset();
173 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
174 Elements.clear();
175 m_Doc->setLoading(true);
176 m_Doc->DoDrawing = false;
177 m_Doc->scMW()->setScriptRunning(true);
178 QString CurDirP = QDir::currentPath();
179 QDir::setCurrent(fi.path());
180 if (convert(fName))
181 {
182 tmpSel->clear();
183 QDir::setCurrent(CurDirP);
184 if (Elements.count() > 1)
185 m_Doc->groupObjectsList(Elements);
186 m_Doc->DoDrawing = true;
187 m_Doc->m_Selection->delaySignalsOn();
188 QImage tmpImage;
189 if (Elements.count() > 0)
190 {
191 for (int dre=0; dre<Elements.count(); ++dre)
192 {
193 tmpSel->addItem(Elements.at(dre), true);
194 }
195 tmpSel->setGroupRect();
196 double xs = tmpSel->width();
197 double ys = tmpSel->height();
198 tmpImage = Elements.at(0)->DrawObj_toImage(500);
199 tmpImage.setText("XSize", QString("%1").arg(xs));
200 tmpImage.setText("YSize", QString("%1").arg(ys));
201 }
202 m_Doc->scMW()->setScriptRunning(false);
203 m_Doc->setLoading(false);
204 m_Doc->m_Selection->delaySignalsOff();
205 delete m_Doc;
206 return tmpImage;
207 }
208 QDir::setCurrent(CurDirP);
209 m_Doc->DoDrawing = true;
210 m_Doc->scMW()->setScriptRunning(false);
211 delete m_Doc;
212 }
213 return tmp;
214 }
215
readColors(const QString & fileName,ColorList & colors)216 bool IdmlPlug::readColors(const QString& fileName, ColorList & colors)
217 {
218 bool success = false;
219 importedColors.clear();
220
221 QByteArray f;
222 QFileInfo fi = QFileInfo(fileName);
223 QString ext = fi.suffix().toLower();
224 if (ext == "idml")
225 {
226 m_zip = new ScZipHandler();
227 if (!m_zip->open(fileName))
228 {
229 delete m_zip;
230 m_zip = nullptr;
231 return false;
232 }
233 if (m_zip->contains("designmap.xml"))
234 m_zip->read("designmap.xml", f);
235 }
236 else if (ext == "idms")
237 {
238 loadRawText(fileName, f);
239 }
240
241 if (f.isEmpty())
242 {
243 delete m_zip;
244 m_zip = nullptr;
245 return false;
246 }
247
248 if (!designMapDom.setContent(f))
249 {
250 delete m_zip;
251 m_zip = nullptr;
252 return false;
253 }
254
255 m_Doc = new ScribusDoc();
256 m_Doc->setup(0, 1, 1, 1, 1, "Custom", "Custom");
257 m_Doc->setPage(1, 1, 0, 0, 0, 0, 0, 0, false, false);
258 m_Doc->addPage(0);
259 m_Doc->setGUI(false, ScCore->primaryMainWindow(), nullptr);
260
261 QDomElement docElem = designMapDom.documentElement();
262 if (ext == "idms")
263 {
264 parseGraphicsXMLNode(docElem);
265 }
266 else
267 {
268 for (QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
269 {
270 QDomElement dpg = drawPag.toElement();
271 if (dpg.tagName() == "idPkg:Graphic")
272 {
273 if (!parseGraphicsXML(dpg))
274 {
275 delete m_zip;
276 m_zip = nullptr;
277 return false;
278 }
279 }
280 }
281 }
282
283 delete m_zip;
284 m_zip = nullptr;
285
286 if (importedColors.count() != 0)
287 {
288 colors = m_Doc->PageColors;
289 success = true;
290 }
291 delete m_Doc;
292 return success;
293 }
294
import(const QString & fNameIn,const TransactionSettings & trSettings,int flags,bool showProgress)295 bool IdmlPlug::import(const QString& fNameIn, const TransactionSettings& trSettings, int flags, bool showProgress)
296 {
297 bool success = false;
298 interactive = (flags & LoadSavePlugin::lfInteractive);
299 importerFlags = flags;
300 cancel = false;
301 bool ret = false;
302 firstLayer = true;
303 firstPage = true;
304 pagecount = 1;
305 mpagecount = 0;
306 QFileInfo fi = QFileInfo(fNameIn);
307 if (!ScCore->usingGUI())
308 {
309 interactive = false;
310 showProgress = false;
311 }
312 baseFile = QDir::cleanPath(QDir::toNativeSeparators(fi.absolutePath()+"/"));
313 if (showProgress)
314 {
315 ScribusMainWindow* mw=(m_Doc==nullptr) ? ScCore->primaryMainWindow() : m_Doc->scMW();
316 progressDialog = new MultiProgressDialog( tr("Importing: %1").arg(fi.fileName()), CommonStrings::tr_Cancel, mw );
317 QStringList barNames, barTexts;
318 barNames << "GI";
319 barTexts << tr("Analyzing File:");
320 QList<bool> barsNumeric;
321 barsNumeric << false;
322 progressDialog->addExtraProgressBars(barNames, barTexts, barsNumeric);
323 progressDialog->setOverallTotalSteps(3);
324 progressDialog->setOverallProgress(0);
325 progressDialog->setProgress("GI", 0);
326 progressDialog->show();
327 connect(progressDialog, SIGNAL(canceled()), this, SLOT(cancelRequested()));
328 qApp->processEvents();
329 }
330 else
331 progressDialog = nullptr;
332 if (progressDialog)
333 {
334 progressDialog->setOverallProgress(1);
335 qApp->processEvents();
336 }
337 /* Set default Page to size defined in Preferences */
338 docWidth = PrefsManager::instance().appPrefs.docSetupPrefs.pageWidth;
339 docHeight = PrefsManager::instance().appPrefs.docSetupPrefs.pageHeight;
340 baseX = 0;
341 baseY = 0;
342 if (!interactive || (flags & LoadSavePlugin::lfInsertPage))
343 {
344 m_Doc->setPage(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false);
345 m_Doc->addPage(0);
346 m_Doc->view()->addPage(0, true);
347 baseX = 0;
348 baseY = 0;
349 }
350 else
351 {
352 if (!m_Doc || (flags & LoadSavePlugin::lfCreateDoc))
353 {
354 m_Doc=ScCore->primaryMainWindow()->doFileNew(docWidth, docHeight, 0, 0, 0, 0, 0, 0, false, false, 0, false, 0, 1, "Custom", true);
355 ScCore->primaryMainWindow()->HaveNewDoc();
356 ret = true;
357 baseX = 0;
358 baseY = 0;
359 baseX = m_Doc->currentPage()->xOffset();
360 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
361 }
362 }
363 if ((!ret) && (interactive))
364 {
365 baseX = m_Doc->currentPage()->xOffset();
366 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
367 }
368 if ((ret) || (!interactive))
369 {
370 if (docWidth > docHeight)
371 m_Doc->setPageOrientation(1);
372 else
373 m_Doc->setPageOrientation(0);
374 m_Doc->setPageSize("Custom");
375 }
376 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
377 m_Doc->view()->deselectItems();
378 Elements.clear();
379 m_Doc->setLoading(true);
380 m_Doc->DoDrawing = false;
381 if ((!(flags & LoadSavePlugin::lfLoadAsPattern)) && (m_Doc->view() != nullptr))
382 m_Doc->view()->updatesOn(false);
383 m_Doc->scMW()->setScriptRunning(true);
384 qApp->setOverrideCursor(QCursor(Qt::WaitCursor));
385 QString CurDirP = QDir::currentPath();
386 QDir::setCurrent(fi.path());
387 if (convert(fNameIn))
388 {
389 tmpSel->clear();
390 QDir::setCurrent(CurDirP);
391 if ((Elements.count() > 1) && (!(importerFlags & LoadSavePlugin::lfCreateDoc)))
392 m_Doc->groupObjectsList(Elements);
393 m_Doc->DoDrawing = true;
394 m_Doc->scMW()->setScriptRunning(false);
395 m_Doc->setLoading(false);
396 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
397 if ((Elements.count() > 0) && (!ret) && (interactive))
398 {
399 if (flags & LoadSavePlugin::lfScripted)
400 {
401 bool loadF = m_Doc->isLoading();
402 m_Doc->setLoading(false);
403 m_Doc->changed();
404 m_Doc->setLoading(loadF);
405 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
406 {
407 m_Doc->m_Selection->delaySignalsOn();
408 for (int dre=0; dre<Elements.count(); ++dre)
409 {
410 m_Doc->m_Selection->addItem(Elements.at(dre), true);
411 }
412 m_Doc->m_Selection->delaySignalsOff();
413 m_Doc->m_Selection->setGroupRect();
414 if (m_Doc->view() != nullptr)
415 m_Doc->view()->updatesOn(true);
416 }
417 }
418 else
419 {
420 m_Doc->DragP = true;
421 m_Doc->DraggedElem = nullptr;
422 m_Doc->DragElements.clear();
423 m_Doc->m_Selection->delaySignalsOn();
424 for (int dre=0; dre<Elements.count(); ++dre)
425 {
426 tmpSel->addItem(Elements.at(dre), true);
427 }
428 tmpSel->setGroupRect();
429 ScElemMimeData* md = ScriXmlDoc::writeToMimeData(m_Doc, tmpSel);
430 m_Doc->itemSelection_DeleteItem(tmpSel);
431 m_Doc->view()->updatesOn(true);
432 m_Doc->m_Selection->delaySignalsOff();
433 // We must copy the TransationSettings object as it is owned
434 // by handleObjectImport method afterwards
435 TransactionSettings* transacSettings = new TransactionSettings(trSettings);
436 m_Doc->view()->handleObjectImport(md, transacSettings);
437 m_Doc->DragP = false;
438 m_Doc->DraggedElem = nullptr;
439 m_Doc->DragElements.clear();
440 }
441 }
442 else
443 {
444 m_Doc->changed();
445 m_Doc->reformPages();
446 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
447 m_Doc->view()->updatesOn(true);
448 }
449 success = true;
450 }
451 else
452 {
453 QDir::setCurrent(CurDirP);
454 m_Doc->DoDrawing = true;
455 m_Doc->scMW()->setScriptRunning(false);
456 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
457 m_Doc->view()->updatesOn(true);
458 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
459 }
460 if (interactive)
461 m_Doc->setLoading(false);
462 //CB If we have a gui we must refresh it if we have used the progressbar
463 if (!(flags & LoadSavePlugin::lfLoadAsPattern))
464 {
465 if ((showProgress) && (!interactive))
466 m_Doc->view()->DrawNew();
467 }
468 qApp->restoreOverrideCursor();
469 return success;
470 }
471
~IdmlPlug()472 IdmlPlug::~IdmlPlug()
473 {
474 delete progressDialog;
475 delete tmpSel;
476 }
477
convert(const QString & fn)478 bool IdmlPlug::convert(const QString& fn)
479 {
480 Coords.resize(0);
481 Coords.svgInit();
482 importedColors.clear();
483 def_fillColor = CommonStrings::None;
484 def_strokeColor = CommonStrings::None;
485 def_fillGradient = "";
486 def_strokeGradient = "";
487 def_Blendmode = 0;
488 def_fillBlendmode = 0;
489 def_strokeBlendmode = 0;
490 def_fillTint = 100;
491 def_strokeTint = 100;
492 def_lineWidth = 0;
493 def_Opacity = 0.0;
494 def_fillOpacity = 0.0;
495 def_strokeOpacity = 0.0;
496 def_gradientAngle = 0.0;
497 def_gradientLen = 0.0;
498 def_gradientX = 0.0;
499 def_gradientY = 0.0;
500 def_gradientStrokeStartX = 0;
501 def_gradientStrokeStartY = 0;
502 def_gradientStrokeLength = 0;
503 def_gradientStrokeAngle = 0;
504 def_Extra = 0;
505 def_TExtra = 0;
506 def_BExtra = 0;
507 def_RExtra = 0;
508 def_TextFlow = PageItem::TextFlowDisabled;
509 def_TextColumnCount = 1;
510 def_TextColumnGutter = 0;
511 def_TextColumnFixedWidth = 0;
512 def_LeftLineEnd = "None";
513 def_RightLineEnd = "None";
514 frameLinks.clear();
515 frameTargets.clear();
516 importedColors.clear();
517 colorTranslate.clear();
518 importedGradients.clear();
519 gradientTranslate.clear();
520 gradientTypeMap.clear();
521 layerTranslate.clear();
522 storyMap.clear();
523 styleTranslate.clear();
524 charStyleTranslate.clear();
525 ObjectStyles.clear();
526 if (progressDialog)
527 {
528 progressDialog->setOverallProgress(2);
529 progressDialog->setLabel("GI", tr("Generating Items"));
530 qApp->processEvents();
531 }
532 colorTranslate.insert("Swatch/None", CommonStrings::None);
533 bool retVal = true;
534 bool firstSpread = true;
535
536 QByteArray f;
537 QFileInfo fi = QFileInfo(fn);
538 QString ext = fi.suffix().toLower();
539 if (ext == "idml")
540 {
541 m_zip = new ScZipHandler();
542 if (!m_zip->open(fn))
543 {
544 delete m_zip;
545 m_zip = nullptr;
546 return false;
547 }
548 if (m_zip->contains("designmap.xml"))
549 m_zip->read("designmap.xml", f);
550 }
551 else if (ext == "idms")
552 {
553 loadRawText(fn, f);
554 }
555
556 if (f.isEmpty())
557 {
558 if (progressDialog)
559 progressDialog->close();
560 delete m_zip;
561 m_zip = nullptr;
562 return false;
563 }
564
565 if (!designMapDom.setContent(f))
566 {
567 if (progressDialog)
568 progressDialog->close();
569 delete m_zip;
570 m_zip = nullptr;
571 return false;
572 }
573
574 QDomElement docElem = designMapDom.documentElement();
575 QString activeLayer = docElem.attribute("ActiveLayer");
576 if (ext == "idms")
577 {
578 for (QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
579 {
580 QDomElement dpg = drawPag.toElement();
581 if (dpg.tagName() == "Layer")
582 {
583 QString layerSelf = dpg.attribute("Self");
584 QString layerName = dpg.attribute("Name");
585 if (importerFlags & LoadSavePlugin::lfCreateDoc)
586 {
587 int currentLayer = 0;
588 if (!firstLayer)
589 currentLayer = m_Doc->addLayer(layerName);
590 else
591 m_Doc->changeLayerName(currentLayer, layerName);
592 m_Doc->setLayerVisible(currentLayer, (dpg.attribute("Visible") == "true"));
593 m_Doc->setLayerLocked(currentLayer, (dpg.attribute("Locked") == "true"));
594 m_Doc->setLayerPrintable(currentLayer, (dpg.attribute("Printable") == "true"));
595 m_Doc->setLayerFlow(currentLayer, (dpg.attribute("IgnoreWrap","") == "true"));
596 }
597 layerTranslate.insert(layerSelf, layerName);
598 firstLayer = false;
599 }
600 }
601 parseFontsXMLNode(docElem);
602 parseGraphicsXMLNode(docElem);
603 parseStylesXMLNode(docElem);
604 parsePreferencesXMLNode(docElem);
605 parseSpreadXMLNode(docElem);
606 parseStoryXMLNode(docElem);
607 }
608 else
609 {
610 for (QDomNode drawPag = docElem.firstChild(); !drawPag.isNull(); drawPag = drawPag.nextSibling())
611 {
612 QDomElement dpg = drawPag.toElement();
613 if (dpg.tagName() == "Layer")
614 {
615 QString layerSelf = dpg.attribute("Self");
616 QString layerName = dpg.attribute("Name");
617 if (importerFlags & LoadSavePlugin::lfCreateDoc)
618 {
619 int currentLayer = 0;
620 if (!firstLayer)
621 currentLayer = m_Doc->addLayer(layerName);
622 else
623 m_Doc->changeLayerName(currentLayer, layerName);
624 m_Doc->setLayerVisible(currentLayer, (dpg.attribute("Visible") == "true"));
625 m_Doc->setLayerLocked(currentLayer, (dpg.attribute("Locked") == "true"));
626 m_Doc->setLayerPrintable(currentLayer, (dpg.attribute("Printable") == "true"));
627 m_Doc->setLayerFlow(currentLayer, (dpg.attribute("IgnoreWrap","") == "true"));
628 }
629 layerTranslate.insert(layerSelf, layerName);
630 firstLayer = false;
631 }
632 if (dpg.tagName() == "idPkg:Fonts")
633 {
634 if (!parseFontsXML(dpg))
635 {
636 retVal = false;
637 break;
638 }
639 }
640 if (dpg.tagName() == "idPkg:Graphic")
641 {
642 if (!parseGraphicsXML(dpg))
643 {
644 retVal = false;
645 break;
646 }
647 }
648 if (dpg.tagName() == "idPkg:Styles")
649 {
650 if (!parseStylesXML(dpg))
651 {
652 retVal = false;
653 break;
654 }
655 }
656 if (dpg.tagName() == "idPkg:Preferences")
657 {
658 if (!parsePreferencesXML(dpg))
659 {
660 retVal = false;
661 break;
662 }
663 }
664 if (dpg.tagName() == "idPkg:MasterSpread")
665 {
666 if (importerFlags & LoadSavePlugin::lfCreateDoc)
667 {
668 if (!parseSpreadXML(dpg))
669 {
670 retVal = false;
671 break;
672 }
673 }
674 }
675 if (dpg.tagName() == "idPkg:Spread")
676 {
677 if (!(importerFlags & LoadSavePlugin::lfCreateDoc))
678 {
679 if (firstSpread)
680 {
681 parseSpreadXML(dpg);
682 firstSpread = false;
683 }
684 }
685 else if (!parseSpreadXML(dpg))
686 {
687 retVal = false;
688 break;
689 }
690 }
691 if (dpg.tagName() == "idPkg:Story")
692 {
693 if (!parseStoryXML(dpg))
694 {
695 retVal = false;
696 break;
697 }
698 }
699 }
700 }
701 if (!frameLinks.isEmpty())
702 {
703 QMap<PageItem*, QString>::Iterator lc;
704 for (lc = frameLinks.begin(); lc != frameLinks.end(); ++lc)
705 {
706 PageItem *Its = lc.key();
707 PageItem *Itn = frameTargets[lc.value()];
708 if (Its->canBeLinkedTo(Itn))
709 Its->link(Itn);
710 }
711 }
712 if (importerFlags & LoadSavePlugin::lfCreateDoc)
713 {
714 if (layerTranslate.contains(activeLayer))
715 activeLayer = layerTranslate[activeLayer];
716 else
717 activeLayer = m_Doc->layerName(0);
718 m_Doc->setActiveLayer(activeLayer);
719 }
720
721 delete m_zip;
722 m_zip = nullptr;
723
724 if (progressDialog)
725 progressDialog->close();
726 return retVal;
727 }
728
parseFontsXML(const QDomElement & grElem)729 bool IdmlPlug::parseFontsXML(const QDomElement& grElem)
730 {
731 QDomElement grNode;
732 QDomDocument grMapDom;
733 if (grElem.hasAttribute("src"))
734 {
735 QByteArray f2;
736 m_zip->read(grElem.attribute("src"), f2);
737 if (!grMapDom.setContent(f2))
738 return false;
739 grNode = grMapDom.documentElement();
740 }
741 else
742 {
743 if (!grElem.hasChildNodes())
744 return false;
745 grNode = grElem;
746 }
747 parseFontsXMLNode(grNode);
748 return true;
749 }
750
parseFontsXMLNode(const QDomElement & grNode)751 void IdmlPlug::parseFontsXMLNode(const QDomElement& grNode)
752 {
753 for (QDomNode n = grNode.firstChild(); !n.isNull(); n = n.nextSibling() )
754 {
755 QDomElement e = n.toElement();
756 if (e.tagName() == "FontFamily")
757 {
758 QString family = e.attribute("Name");
759 QMap<QString, QString> styleMap;
760 for (QDomNode gr = e.firstChild(); !gr.isNull(); gr = gr.nextSibling())
761 {
762 QDomElement grs = gr.toElement();
763 if (grs.tagName() == "Font")
764 {
765 QString styleName = grs.attribute("FontStyleName").remove("$ID/");
766 QString postName = grs.attribute("PostScriptName").remove("$ID/");
767 styleMap.insert(styleName, postName);
768 }
769 }
770 fontTranslateMap.insert(family, styleMap);
771 }
772 }
773 }
774
parseGraphicsXML(const QDomElement & grElem)775 bool IdmlPlug::parseGraphicsXML(const QDomElement& grElem)
776 {
777 QDomElement grNode;
778 QDomDocument grMapDom;
779 if (grElem.hasAttribute("src"))
780 {
781 QByteArray f2;
782 m_zip->read(grElem.attribute("src"), f2);
783 if (!grMapDom.setContent(f2))
784 return false;
785 grNode = grMapDom.documentElement();
786 }
787 else
788 {
789 if (!grElem.hasChildNodes())
790 return false;
791 grNode = grElem;
792 }
793 parseGraphicsXMLNode(grNode);
794 return true;
795 }
796
parseGraphicsXMLNode(const QDomElement & grNode)797 void IdmlPlug::parseGraphicsXMLNode(const QDomElement& grNode)
798 {
799 for (QDomNode n = grNode.firstChild(); !n.isNull(); n = n.nextSibling() )
800 {
801 QDomElement e = n.toElement();
802 if (e.tagName() == "Color")
803 {
804 QString colorSelf = e.attribute("Self");
805 QString colorName = e.attribute("Self").remove(0, 6);
806 QString colorData = e.attribute("ColorValue");
807 QString colorSpace = e.attribute("Space");
808 QString colorModel = e.attribute("Model");
809 if (colorSpace == "CMYK")
810 {
811 double c, m, y, k;
812 ScColor tmp;
813 ScTextStream Code(&colorData, QIODevice::ReadOnly);
814 Code >> c >> m >> y >> k;
815 tmp.setColorF(c / 100.0, m / 100.0, y / 100.0, k / 100.0);
816 tmp.setSpotColor(colorModel == "Spot");
817 tmp.setRegistrationColor(colorModel == "Registration");
818 QString fNam = m_Doc->PageColors.tryAddColor(colorName, tmp);
819 if (fNam == colorName)
820 importedColors.append(fNam);
821 colorTranslate.insert(colorSelf, fNam);
822 }
823 else if (colorSpace == "RGB")
824 {
825 int r, g, b;
826 ScColor tmp;
827 ScTextStream Code(&colorData, QIODevice::ReadOnly);
828 Code >> r >> g >> b;
829 tmp.setRgbColor(r, g, b);
830 tmp.setSpotColor(false);
831 tmp.setRegistrationColor(false);
832 QString fNam = m_Doc->PageColors.tryAddColor(colorName, tmp);
833 if (fNam == colorName)
834 importedColors.append(fNam);
835 colorTranslate.insert(colorSelf, fNam);
836 }
837 else if (colorSpace == "LAB")
838 {
839 double L, a, b;
840 ScColor tmp;
841 ScTextStream Code(&colorData, QIODevice::ReadOnly);
842 Code >> L >> a >> b;
843 tmp.setLabColor(L, a, b);
844 tmp.setSpotColor(false);
845 tmp.setRegistrationColor(false);
846 QString fNam = m_Doc->PageColors.tryAddColor(colorName, tmp);
847 if (fNam == colorName)
848 importedColors.append(fNam);
849 colorTranslate.insert(colorSelf, fNam);
850 }
851 }
852 else if (e.tagName() == "Gradient")
853 {
854 QString grSelf = e.attribute("Self");
855 QString grName = e.attribute("Self").remove(0, 9);
856 int grTyp = (e.attribute("Type") == "Linear") ? 6 : 7;
857 VGradient currentGradient = VGradient(VGradient::linear);
858 currentGradient.clearStops();
859 for (QDomNode gr = e.firstChild(); !gr.isNull(); gr = gr.nextSibling())
860 {
861 QDomElement grs = gr.toElement();
862 if (grs.tagName() == "GradientStop")
863 {
864 QString stopName = grs.attribute("StopColor");
865 double stop = grs.attribute("Location", "0.0").toDouble();
866 if (colorTranslate.contains(stopName))
867 stopName = colorTranslate[stopName];
868 else
869 stopName = "Black";
870 const ScColor& gradC = m_Doc->PageColors[stopName];
871 currentGradient.addStop( ScColorEngine::getRGBColor(gradC, m_Doc), stop / 100.0, 0.5, 1.0, stopName, 100 );
872 }
873 }
874 if (m_Doc->addGradient(grName, currentGradient))
875 importedGradients.append(grName);
876 gradientTranslate.insert(grSelf, grName);
877 gradientTypeMap.insert(grSelf, grTyp);
878 }
879 else if (e.tagName() == "Tint")
880 {
881 QString colorSelf = e.attribute("Self");
882 QString colorName = e.attribute("Self").remove(0, 5);
883 QString baseName = e.attribute("BaseColor", "Black");
884 double tint = e.attribute("TintValue", "100").toDouble() / 100.0;
885 if (colorTranslate.contains(baseName))
886 {
887 ScColor tmp = m_Doc->PageColors[colorTranslate[baseName]];
888 ScColor res;
889 if (tmp.getColorModel() == colorModelCMYK)
890 {
891 double c, m, y, k;
892 tmp.getCMYK(&c, &m, &y, &k);
893 res.setColorF(c * tint, m * tint, y * tint, k * tint);
894 }
895 else
896 {
897 double r, g, b;
898 tmp.getRGB(&r, &g, &b);
899 res.setRgbColorF(r * tint, g * tint, b * tint);
900 }
901 res.setSpotColor(false);
902 res.setRegistrationColor(false);
903 QString fNam = m_Doc->PageColors.tryAddColor(colorName, res);
904 if (fNam == colorName)
905 importedColors.append(fNam);
906 colorTranslate.insert(colorSelf, fNam);
907 }
908 }
909 }
910 }
911
parseStylesXML(const QDomElement & sElem)912 bool IdmlPlug::parseStylesXML(const QDomElement& sElem)
913 {
914 QDomElement sNode;
915 QDomDocument sMapDom;
916 if (sElem.hasAttribute("src"))
917 {
918 QByteArray f2;
919 m_zip->read(sElem.attribute("src"), f2);
920 if (!sMapDom.setContent(f2))
921 return false;
922 sNode = sMapDom.documentElement();
923 }
924 else
925 {
926 if (!sElem.hasChildNodes())
927 return false;
928 sNode = sElem;
929 }
930 parseStylesXMLNode(sNode);
931 return true;
932 }
933
parseStylesXMLNode(const QDomElement & sNode)934 void IdmlPlug::parseStylesXMLNode(const QDomElement& sNode)
935 {
936 for (QDomNode n = sNode.firstChild(); !n.isNull(); n = n.nextSibling() )
937 {
938 QDomElement e = n.toElement();
939 if (e.tagName() == "RootCharacterStyleGroup")
940 {
941 for (QDomNode it = e.firstChild(); !it.isNull(); it = it.nextSibling())
942 {
943 QDomElement itpg = it.toElement();
944 if (itpg.tagName() == "CharacterStyle")
945 parseCharacterStyle(itpg);
946 else if (itpg.tagName() == "CharacterStyleGroup")
947 {
948 for (QDomNode its = itpg.firstChild(); !its.isNull(); its = its.nextSibling())
949 {
950 QDomElement itp = its.toElement();
951 if (itp.tagName() == "CharacterStyle")
952 parseCharacterStyle(itp);
953 }
954 }
955 }
956 }
957 if (e.tagName() == "RootParagraphStyleGroup")
958 {
959 for (QDomNode it = e.firstChild(); !it.isNull(); it = it.nextSibling())
960 {
961 QDomElement itpg = it.toElement();
962 if (itpg.tagName() == "ParagraphStyle")
963 parseParagraphStyle(itpg);
964 else if (itpg.tagName() == "ParagraphStyleGroup")
965 {
966 for (QDomNode its = itpg.firstChild(); !its.isNull(); its = its.nextSibling())
967 {
968 QDomElement itp = its.toElement();
969 if (itp.tagName() == "ParagraphStyle")
970 parseParagraphStyle(itp);
971 }
972 }
973 }
974 }
975 if (e.tagName() == "RootObjectStyleGroup")
976 {
977 for (QDomNode it = e.firstChild(); !it.isNull(); it = it.nextSibling())
978 {
979 QDomElement itpg = it.toElement();
980 if (itpg.tagName() == "ObjectStyle")
981 parseObjectStyle(itpg);
982 else if (itpg.tagName() == "ObjectStyleGroup")
983 {
984 for (QDomNode its = itpg.firstChild(); !its.isNull(); its = its.nextSibling())
985 {
986 QDomElement itp = its.toElement();
987 if (itp.tagName() == "ObjectStyle")
988 parseObjectStyle(itp);
989 }
990 }
991 }
992 }
993 }
994 }
995
parseObjectStyle(const QDomElement & styleElem)996 void IdmlPlug::parseObjectStyle(const QDomElement& styleElem)
997 {
998 ObjectStyle nstyle;
999 nstyle.fillColor = def_fillColor;
1000 nstyle.strokeColor = def_strokeColor;
1001 nstyle.fillGradient = "";
1002 nstyle.gradientFillStart = QPointF(def_gradientX, def_gradientY);
1003 nstyle.gradientFillLength = def_gradientLen;
1004 nstyle.gradientFillAngle = def_gradientAngle;
1005 nstyle.strokeGradient = "";
1006 nstyle.gradientStrokeStart = QPointF(def_gradientStrokeStartX, def_gradientStrokeStartY);
1007 nstyle.gradientStrokeLength = def_gradientStrokeLength;
1008 nstyle.gradientStrokeAngle = def_gradientStrokeAngle;
1009 nstyle.lineWidth = def_lineWidth;
1010 nstyle.fillTint = def_fillTint;
1011 nstyle.strokeTint = def_strokeTint;
1012 nstyle.Opacity = def_Opacity;
1013 nstyle.blendMode = def_Blendmode;
1014 nstyle.parentStyle = "";
1015 nstyle.Extra = def_Extra;
1016 nstyle.TExtra = def_TExtra;
1017 nstyle.BExtra = def_BExtra;
1018 nstyle.RExtra = def_RExtra;
1019 nstyle.TextColumnCount = def_TextColumnCount;
1020 nstyle.TextColumnGutter = def_TextColumnGutter;
1021 nstyle.TextFlow = def_TextFlow;
1022 nstyle.LeftLineEnd = def_LeftLineEnd;
1023 nstyle.RightLineEnd = def_RightLineEnd;
1024 for (QDomNode itp = styleElem.firstChild(); !itp.isNull(); itp = itp.nextSibling())
1025 {
1026 QDomElement itpr = itp.toElement();
1027 if (itpr.tagName() == "Properties")
1028 {
1029 for (QDomNode itpp = itpr.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1030 {
1031 QDomElement i = itpp.toElement();
1032 if (i.tagName() == "BasedOn")
1033 {
1034 QString ps = i.text();
1035 if (ps != "$ID/[None]")
1036 nstyle.parentStyle = ps;
1037 }
1038 }
1039 }
1040 if (itpr.tagName() == "TextWrapPreference")
1041 {
1042 if (itpr.hasAttribute("TextWrapMode"))
1043 {
1044 if (itpr.attribute("TextWrapMode") == "None")
1045 nstyle.TextFlow = PageItem::TextFlowDisabled;
1046 else if (itpr.attribute("TextWrapMode") == "BoundingBoxTextWrap")
1047 nstyle.TextFlow = PageItem::TextFlowUsesBoundingBox;
1048 else if (itpr.attribute("TextWrapMode") == "Contour")
1049 nstyle.TextFlow = PageItem::TextFlowUsesFrameShape;
1050 }
1051 }
1052 else if (itpr.tagName() == "TextFramePreference")
1053 {
1054 if (itpr.hasAttribute("TextColumnCount"))
1055 nstyle.TextColumnCount = itpr.attribute("TextColumnCount").toInt();
1056 if (itpr.hasAttribute("TextColumnGutter"))
1057 nstyle.TextColumnGutter = itpr.attribute("TextColumnGutter").toDouble();
1058 if (itpr.hasAttribute("TextColumnFixedWidth"))
1059 nstyle.TextColumnFixedWidth = itpr.attribute("TextColumnFixedWidth").toDouble();
1060 for (QDomNode itpp = itpr.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1061 {
1062 QDomElement i = itpp.toElement();
1063 if (i.tagName() == "Properties")
1064 {
1065 for (QDomNode it = i.firstChild(); !it.isNull(); it = it.nextSibling())
1066 {
1067 QDomElement itx = it.toElement();
1068 if (itx.tagName() == "InsetSpacing")
1069 {
1070 if (itx.attribute("type") == "unit")
1071 nstyle.Extra = nstyle.TExtra = nstyle.BExtra = nstyle.RExtra = itx.text().toDouble();
1072 else if (itx.attribute("type") == "list")
1073 {
1074 int cc = 0;
1075 for (QDomNode ity = itx.firstChild(); !ity.isNull(); ity = ity.nextSibling())
1076 {
1077 QDomElement itxx = ity.toElement();
1078 if (itxx.tagName() == "ListItem")
1079 {
1080 double val = itxx.text().toDouble();
1081 if (cc == 0)
1082 nstyle.Extra = val;
1083 else if (cc == 1)
1084 nstyle.TExtra = val;
1085 else if (cc == 2)
1086 nstyle.RExtra = val;
1087 else if (cc == 3)
1088 nstyle.BExtra = val;
1089 cc++;
1090 }
1091 }
1092 }
1093 }
1094 }
1095 }
1096 }
1097 }
1098 }
1099 if (styleElem.hasAttribute("StrokeColor"))
1100 {
1101 QString strokeColor = styleElem.attribute("StrokeColor");
1102 if (colorTranslate.contains(strokeColor))
1103 nstyle.strokeColor = colorTranslate[strokeColor];
1104 else
1105 {
1106 if (gradientTranslate.contains(strokeColor))
1107 nstyle.strokeGradient = gradientTranslate[strokeColor];
1108 }
1109 }
1110 if (styleElem.hasAttribute("FillColor"))
1111 {
1112 QString fillColor = styleElem.attribute("FillColor");
1113 if (colorTranslate.contains(fillColor))
1114 nstyle.fillColor = colorTranslate[fillColor];
1115 else
1116 {
1117 if (gradientTranslate.contains(fillColor))
1118 nstyle.fillGradient = gradientTranslate[fillColor];
1119 }
1120 }
1121 if (styleElem.hasAttribute("FillTint"))
1122 {
1123 int fillShade = styleElem.attribute("FillTint").toInt();
1124 if (fillShade != -1)
1125 nstyle.fillTint = fillShade;
1126 }
1127 if (styleElem.hasAttribute("StrokeTint"))
1128 {
1129 int strokeShade = styleElem.attribute("StrokeTint").toInt();
1130 if (strokeShade != -1)
1131 nstyle.strokeTint = strokeShade;
1132 }
1133 if (styleElem.hasAttribute("StrokeWeight"))
1134 nstyle.lineWidth = styleElem.attribute("StrokeWeight", "0").toDouble();
1135 if (styleElem.hasAttribute("GradientFillStart"))
1136 {
1137 QString fillGStart = styleElem.attribute("GradientFillStart");
1138 ScTextStream Code(&fillGStart, QIODevice::ReadOnly);
1139 double gstX, gstY;
1140 Code >> gstX >> gstY;
1141 nstyle.gradientFillStart = QPointF(gstX, gstY);
1142 }
1143 if (styleElem.hasAttribute("GradientFillLength"))
1144 nstyle.gradientFillLength = styleElem.attribute("GradientFillLength").toDouble();
1145 if (styleElem.hasAttribute("GradientFillAngle"))
1146 nstyle.gradientFillAngle = styleElem.attribute("GradientFillAngle").toDouble();
1147 if (styleElem.hasAttribute("GradientStrokeStart"))
1148 {
1149 QString fillGStart = styleElem.attribute("GradientStrokeStart");
1150 ScTextStream Code(&fillGStart, QIODevice::ReadOnly);
1151 double gstX, gstY;
1152 Code >> gstX >> gstY;
1153 nstyle.gradientStrokeStart = QPointF(gstX, gstY);
1154 }
1155 if (styleElem.hasAttribute("GradientStrokeLength"))
1156 nstyle.gradientStrokeLength = styleElem.attribute("GradientStrokeLength").toDouble();
1157 if (styleElem.hasAttribute("GradientStrokeAngle"))
1158 nstyle.gradientStrokeAngle = styleElem.attribute("GradientStrokeAngle").toDouble();
1159 if (styleElem.hasAttribute("RightLineEnd"))
1160 nstyle.RightLineEnd = styleElem.attribute("RightLineEnd");
1161 if (styleElem.hasAttribute("LeftLineEnd"))
1162 nstyle.LeftLineEnd = styleElem.attribute("LeftLineEnd");
1163 QString itemName = styleElem.attribute("Self");
1164 ObjectStyles.insert(itemName, nstyle);
1165 }
1166
parseCharacterStyle(const QDomElement & styleElem)1167 void IdmlPlug::parseCharacterStyle(const QDomElement& styleElem)
1168 {
1169 CharStyle newStyle;
1170 newStyle.setDefaultStyle(false);
1171 newStyle.setName(styleElem.attribute("Name").remove("$ID/"));
1172 newStyle.setParent(CommonStrings::DefaultCharacterStyle);
1173 QString fontName = m_Doc->itemToolPrefs().textFont;
1174 QString fontBaseName = "";
1175 QString fontStyle = styleElem.attribute("FontStyle", "");
1176 for (QDomNode itp = styleElem.firstChild(); !itp.isNull(); itp = itp.nextSibling())
1177 {
1178 QDomElement itpr = itp.toElement();
1179 if (itpr.tagName() == "Properties")
1180 {
1181 for (QDomNode itpp = itpr.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1182 {
1183 QDomElement i = itpp.toElement();
1184 if (i.tagName() == "AppliedFont")
1185 fontBaseName = i.text();
1186 else if (i.tagName() == "BasedOn")
1187 {
1188 QString parentStyle = i.text().remove("$ID/");
1189 if (charStyleTranslate.contains(parentStyle))
1190 parentStyle = charStyleTranslate[parentStyle];
1191 if (m_Doc->styleExists(parentStyle))
1192 newStyle.setParent(parentStyle);
1193 }
1194 }
1195 }
1196 }
1197 if ((!fontBaseName.isEmpty()) && (!fontStyle.isEmpty()))
1198 fontName = constructFontName(fontBaseName, fontStyle);
1199 newStyle.setFont((*m_Doc->AllFonts)[fontName]);
1200 readCharStyleAttributes(newStyle, styleElem);
1201 StyleSet<CharStyle> temp;
1202 temp.create(newStyle);
1203 m_Doc->redefineCharStyles(temp, false);
1204 charStyleTranslate.insert(styleElem.attribute("Self").remove("$ID/"), styleElem.attribute("Name").remove("$ID/"));
1205 }
1206
parseParagraphStyle(const QDomElement & styleElem)1207 void IdmlPlug::parseParagraphStyle(const QDomElement& styleElem)
1208 {
1209 ParagraphStyle newStyle;
1210 newStyle.erase();
1211 newStyle.setDefaultStyle(false);
1212 newStyle.setName(styleElem.attribute("Name").remove("$ID/"));
1213 newStyle.setParent(CommonStrings::DefaultParagraphStyle);
1214 QString fontName = m_Doc->itemToolPrefs().textFont;
1215 QString fontBaseName = "";
1216 QString fontStyle = styleElem.attribute("FontStyle", "");
1217 newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
1218 for (QDomNode itp = styleElem.firstChild(); !itp.isNull(); itp = itp.nextSibling())
1219 {
1220 QDomElement itpr = itp.toElement();
1221 if (itpr.tagName() == "Properties")
1222 {
1223 for (QDomNode itpp = itpr.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1224 {
1225 QDomElement i = itpp.toElement();
1226 if (i.tagName() == "AppliedFont")
1227 fontBaseName = i.text();
1228 else if (i.tagName() == "BasedOn")
1229 {
1230 QString parentStyle = i.text().remove("$ID/");
1231 if (styleTranslate.contains(parentStyle))
1232 parentStyle = styleTranslate[parentStyle];
1233 else
1234 {
1235 QString pSty = parentStyle.remove("ParagraphStyle/");
1236 if (styleParents.contains(pSty))
1237 styleParents[pSty].append(newStyle.name());
1238 else
1239 styleParents.insert(pSty, QStringList() << newStyle.name());
1240 }
1241 if (m_Doc->styleExists(parentStyle))
1242 newStyle.setParent(parentStyle);
1243 }
1244 else if (i.tagName() == "Leading")
1245 {
1246 if (i.attribute("type") == "unit")
1247 {
1248 int lead = i.text().toDouble();
1249 if (lead != 0)
1250 {
1251 newStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
1252 newStyle.setLineSpacing(lead);
1253 }
1254 }
1255 }
1256 else if (i.tagName() == "TabList")
1257 {
1258 QList<ParagraphStyle::TabRecord> tbs;
1259 newStyle.resetTabValues();
1260 for (QDomNode tabl = i.firstChild(); !tabl.isNull(); tabl = tabl.nextSibling())
1261 {
1262 QDomElement ta = tabl.toElement();
1263 if (ta.tagName() == "ListItem")
1264 {
1265 ParagraphStyle::TabRecord tb;
1266 for (QDomNode tal = ta.firstChild(); !tal.isNull(); tal = tal.nextSibling())
1267 {
1268 QDomElement tab = tal.toElement();
1269 QString tabVal = tab.text();
1270 if (tab.tagName() == "Alignment")
1271 {
1272 tb.tabType = 0;
1273 if (tabVal == "LeftAlign")
1274 tb.tabType = 0;
1275 else if (tabVal == "CenterAlign")
1276 tb.tabType = 4;
1277 else if (tabVal == "RightAlign")
1278 tb.tabType = 1;
1279 else if (tabVal == "Spreadsheet")
1280 tb.tabType = 3;
1281 }
1282 else if (tab.tagName() == "Position")
1283 {
1284 tb.tabPosition = tabVal.toDouble();
1285 }
1286 else if (tab.tagName() == "Leader")
1287 {
1288 tb.tabFillChar = tabVal.isEmpty() ? QChar() : tabVal[0];
1289 }
1290 else if (tab.tagName() == "AlignmentCharacter")
1291 {
1292 if (tb.tabType == 3)
1293 {
1294 if (tabVal.startsWith(","))
1295 tb.tabType = 4;
1296 }
1297 }
1298 }
1299 tbs.append(tb);
1300
1301 }
1302 }
1303 if (tbs.count() > 0)
1304 newStyle.setTabValues(tbs);
1305 }
1306 }
1307 }
1308 }
1309 if ((!fontBaseName.isEmpty()) && (!fontStyle.isEmpty()))
1310 fontName = constructFontName(fontBaseName, fontStyle);
1311 newStyle.charStyle().setFont((*m_Doc->AllFonts)[fontName]);
1312 readCharStyleAttributes(newStyle.charStyle(), styleElem);
1313 readParagraphStyleAttributes(newStyle, styleElem);
1314 StyleSet<ParagraphStyle>tmp;
1315 tmp.create(newStyle);
1316 m_Doc->redefineStyles(tmp, false);
1317 styleTranslate.insert(styleElem.attribute("Self").remove("$ID/"), styleElem.attribute("Name").remove("$ID/"));
1318 if (styleParents.contains(newStyle.name()))
1319 {
1320 QStringList desList = styleParents[newStyle.name()];
1321 for (int a = 0; a < desList.count(); a++)
1322 {
1323 ParagraphStyle old = m_Doc->paragraphStyle(desList[a]);
1324 old.setParent(newStyle.name());
1325 StyleSet<ParagraphStyle>tmp2;
1326 tmp2.create(old);
1327 m_Doc->redefineStyles(tmp2, false);
1328 }
1329 }
1330 }
1331
parsePreferencesXML(const QDomElement & prElem)1332 bool IdmlPlug::parsePreferencesXML(const QDomElement& prElem)
1333 {
1334 QDomElement prNode;
1335 QDomDocument prMapDom;
1336 if (prElem.hasAttribute("src"))
1337 {
1338 QByteArray f2;
1339 m_zip->read(prElem.attribute("src"), f2);
1340 if (!prMapDom.setContent(f2))
1341 return false;
1342 prNode = prMapDom.documentElement();
1343 }
1344 else
1345 {
1346 if (!prElem.hasChildNodes())
1347 return false;
1348 prNode = prElem;
1349 }
1350 parsePreferencesXMLNode(prNode);
1351 return true;
1352 }
1353
parsePreferencesXMLNode(const QDomElement & prNode)1354 void IdmlPlug::parsePreferencesXMLNode(const QDomElement& prNode)
1355 {
1356 double topMargin = m_Doc->marginsVal().top();
1357 double leftMargin = m_Doc->marginsVal().left();
1358 double rightMargin = m_Doc->marginsVal().right();
1359 double bottomMargin = m_Doc->marginsVal().bottom();
1360 double pgCols = m_Doc->PageSp;
1361 double pgGap = m_Doc->PageSpa;
1362 double bleedTop = m_Doc->bleeds()->top();
1363 double bleedLeft = m_Doc->bleeds()->left();
1364 double bleedRight = m_Doc->bleeds()->right();
1365 double bleedBottom = m_Doc->bleeds()->bottom();
1366 facingPages = false;
1367 for (QDomNode n = prNode.firstChild(); !n.isNull(); n = n.nextSibling() )
1368 {
1369 QDomElement e = n.toElement();
1370 if (e.tagName() == "DocumentPreference")
1371 {
1372 if (importerFlags & LoadSavePlugin::lfCreateDoc)
1373 {
1374 docWidth = e.attribute("PageWidth").toDouble();
1375 docHeight = e.attribute("PageHeight").toDouble();
1376 bleedTop = e.attribute("DocumentBleedTopOffset").toDouble();
1377 bleedLeft = e.attribute("DocumentBleedInsideOrLeftOffset").toDouble();
1378 bleedRight = e.attribute("DocumentBleedOutsideOrRightOffset").toDouble();
1379 bleedBottom = e.attribute("DocumentBleedBottomOffset").toDouble();
1380 facingPages = e.attribute("FacingPages","") == "true";
1381 }
1382 }
1383 if (e.tagName() == "MarginPreference")
1384 {
1385 topMargin = e.attribute("Top").toDouble();
1386 leftMargin = e.attribute("Left").toDouble();
1387 rightMargin = e.attribute("Right").toDouble();
1388 bottomMargin = e.attribute("Bottom").toDouble();
1389 pgCols = e.attribute("ColumnCount").toDouble();
1390 pgGap = e.attribute("ColumnGutter").toDouble();
1391 }
1392 if (e.tagName() == "TransparencyDefaultContainerObject")
1393 {
1394 for (QDomNode it = e.firstChild(); !it.isNull(); it = it.nextSibling())
1395 {
1396 QDomElement itpg = it.toElement();
1397 for (QDomNode itp = itpg.firstChild(); !itp.isNull(); itp = itp.nextSibling())
1398 {
1399 QDomElement itpr = itp.toElement();
1400 if (itpr.tagName() == "TransparencySetting")
1401 {
1402 def_Opacity = 1.0 - (itpr.attribute("Opacity", "100").toDouble() / 100.0);
1403 def_Blendmode = convertBlendMode(itpr.attribute("BlendMode", "Normal"));
1404 }
1405 if (itpr.tagName() == "StrokeTransparencySetting")
1406 {
1407 def_strokeOpacity = 1.0 - (itpr.attribute("Opacity", "100").toDouble() / 100.0);
1408 def_strokeBlendmode = convertBlendMode(itpr.attribute("BlendMode", "Normal"));
1409 }
1410 if (itpr.tagName() == "FillTransparencySetting")
1411 {
1412 def_fillOpacity = 1.0 - (itpr.attribute("Opacity", "100").toDouble() / 100.0);
1413 def_fillBlendmode = convertBlendMode(itpr.attribute("BlendMode", "Normal"));
1414 }
1415 }
1416 }
1417 }
1418 if (e.tagName() == "PageItemDefault")
1419 {
1420 QString strokeColor = e.attribute("StrokeColor");
1421 if (colorTranslate.contains(strokeColor))
1422 def_strokeColor = colorTranslate[strokeColor];
1423 else
1424 {
1425 if (gradientTranslate.contains(strokeColor))
1426 {
1427 def_strokeGradient = gradientTranslate[strokeColor];
1428 }
1429 }
1430 QString strokeGStart = e.attribute("GradientStrokeStart", "0 0");
1431 ScTextStream Code2(&strokeGStart, QIODevice::ReadOnly);
1432 Code2 >> def_gradientStrokeStartX >> def_gradientStrokeStartY;
1433 def_gradientStrokeLength = e.attribute("GradientStrokeLength", "0").toDouble();
1434 def_gradientStrokeAngle = e.attribute("GradientStrokeAngle", "0").toDouble();
1435 int strokeShade = e.attribute("StrokeTint", "100").toInt();
1436 if (strokeShade != -1)
1437 def_strokeTint = strokeShade;
1438 else
1439 def_strokeTint = 100;
1440 QString fillColor = e.attribute("FillColor");
1441 if (colorTranslate.contains(fillColor))
1442 def_fillColor = colorTranslate[fillColor];
1443 else
1444 {
1445 if (gradientTranslate.contains(fillColor))
1446 {
1447 def_fillGradient = gradientTranslate[fillColor];
1448 }
1449 }
1450 QString fillGStart = e.attribute("GradientFillStart", "0 0");
1451 ScTextStream Code(&fillGStart, QIODevice::ReadOnly);
1452 Code >> def_gradientX >> def_gradientY;
1453 def_gradientLen = e.attribute("GradientFillLength", "0").toDouble();
1454 def_gradientAngle = e.attribute("GradientFillAngle", "0").toDouble();
1455 int fillShade = e.attribute("FillTint", "100").toInt();
1456 if (fillShade != -1)
1457 def_fillTint = fillShade;
1458 else
1459 def_fillTint = 100;
1460 def_lineWidth = e.attribute("StrokeWeight", "0").toDouble();
1461 if (e.hasAttribute("RightLineEnd"))
1462 def_RightLineEnd = e.attribute("RightLineEnd");
1463 if (e.hasAttribute("LeftLineEnd"))
1464 def_LeftLineEnd = e.attribute("LeftLineEnd");
1465 }
1466 if (e.tagName() == "TextWrapPreference")
1467 {
1468 if (e.attribute("TextWrapMode") == "None")
1469 def_TextFlow = PageItem::TextFlowDisabled;
1470 else if (e.attribute("TextWrapMode") == "BoundingBoxTextWrap")
1471 def_TextFlow = PageItem::TextFlowUsesBoundingBox;
1472 else if (e.attribute("TextWrapMode") == "Contour")
1473 def_TextFlow = PageItem::TextFlowUsesFrameShape;
1474 }
1475 if (e.tagName() == "TextFramePreference")
1476 {
1477 if (e.hasAttribute("TextColumnCount"))
1478 def_TextColumnCount = e.attribute("TextColumnCount").toInt();
1479 if (e.hasAttribute("TextColumnGutter"))
1480 def_TextColumnGutter = e.attribute("TextColumnGutter").toDouble();
1481 if (e.hasAttribute("TextColumnFixedWidth"))
1482 def_TextColumnFixedWidth = e.attribute("TextColumnFixedWidth").toDouble();
1483 for (QDomNode itpp = e.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1484 {
1485 QDomElement i = itpp.toElement();
1486 if (i.tagName() == "Properties")
1487 {
1488 for (QDomNode it = i.firstChild(); !it.isNull(); it = it.nextSibling())
1489 {
1490 QDomElement itx = it.toElement();
1491 if (itx.tagName() == "InsetSpacing")
1492 {
1493 if (itx.attribute("type") == "unit")
1494 def_Extra = def_TExtra = def_BExtra = def_RExtra = itx.text().toDouble();
1495 else if (itx.attribute("type") == "list")
1496 {
1497 int cc = 0;
1498 for (QDomNode ity = itx.firstChild(); !ity.isNull(); ity = ity.nextSibling())
1499 {
1500 QDomElement itxx = ity.toElement();
1501 if (itxx.tagName() == "ListItem")
1502 {
1503 double val = itxx.text().toDouble();
1504 if (cc == 0)
1505 def_Extra = val;
1506 else if (cc == 1)
1507 def_TExtra = val;
1508 else if (cc == 2)
1509 def_RExtra = val;
1510 else if (cc == 3)
1511 def_BExtra = val;
1512 cc++;
1513 }
1514 }
1515 }
1516 }
1517 }
1518 }
1519 }
1520 }
1521 }
1522 if (importerFlags & LoadSavePlugin::lfCreateDoc)
1523 {
1524 m_Doc->setPage(docWidth, docHeight, topMargin, leftMargin, rightMargin, bottomMargin, pgCols, pgGap, false, facingPages);
1525 m_Doc->setPageSize("Custom");
1526 m_Doc->bleeds()->set(bleedTop, bleedLeft, bleedBottom, bleedRight);
1527 m_Doc->currentPage()->setSize("Custom");
1528 m_Doc->currentPage()->setInitialHeight(docHeight);
1529 m_Doc->currentPage()->setInitialWidth(docWidth);
1530 m_Doc->currentPage()->setHeight(docHeight);
1531 m_Doc->currentPage()->setWidth(docWidth);
1532 m_Doc->currentPage()->initialMargins.setTop(topMargin);
1533 m_Doc->currentPage()->initialMargins.setBottom(bottomMargin);
1534 m_Doc->currentPage()->initialMargins.setLeft(leftMargin);
1535 m_Doc->currentPage()->initialMargins.setRight(rightMargin);
1536 m_Doc->reformPages(true);
1537 baseX = m_Doc->currentPage()->xOffset();
1538 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
1539 }
1540 }
1541
parseSpreadXML(const QDomElement & spElem)1542 bool IdmlPlug::parseSpreadXML(const QDomElement& spElem)
1543 {
1544 QDomElement spNode;
1545 QDomDocument spMapDom;
1546 if (spElem.hasAttribute("src"))
1547 {
1548 QByteArray f2;
1549 m_zip->read(spElem.attribute("src"), f2);
1550 if (!spMapDom.setContent(f2))
1551 return false;
1552 spNode = spMapDom.documentElement();
1553 }
1554 else
1555 {
1556 if (!spElem.hasChildNodes())
1557 return false;
1558 spNode = spElem;
1559 }
1560 parseSpreadXMLNode(spNode);
1561 return true;
1562 }
1563
parseSpreadXMLNode(const QDomElement & spNode)1564 void IdmlPlug::parseSpreadXMLNode(const QDomElement& spNode)
1565 {
1566 for (QDomNode n = spNode.firstChild(); !n.isNull(); n = n.nextSibling())
1567 {
1568 QDomElement e = n.toElement();
1569 if (e.tagName() == "Spread")
1570 {
1571 for (QDomNode sp = e.firstChild(); !sp.isNull(); sp = sp.nextSibling())
1572 {
1573 QDomElement spe = sp.toElement();
1574 if (spe.tagName() == "Page")
1575 {
1576 if ((importerFlags & LoadSavePlugin::lfCreateDoc) && (!firstPage))
1577 {
1578 m_Doc->addPage(pagecount);
1579 m_Doc->currentPage()->setMasterPageNameNormal();
1580 m_Doc->currentPage()->setSize("Custom");
1581 m_Doc->currentPage()->setInitialHeight(docHeight);
1582 m_Doc->currentPage()->setInitialWidth(docWidth);
1583 m_Doc->currentPage()->setHeight(docHeight);
1584 m_Doc->currentPage()->setWidth(docWidth);
1585 m_Doc->view()->addPage(pagecount, true);
1586 pagecount++;
1587 }
1588 baseX = m_Doc->currentPage()->xOffset();
1589 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
1590 firstPage = false;
1591 if ((importerFlags & LoadSavePlugin::lfCreateDoc) && spe.hasAttribute("AppliedMaster"))
1592 {
1593 QString mSpr = spe.attribute("AppliedMaster");
1594 if (masterSpreads.contains(mSpr))
1595 {
1596 QString mp = CommonStrings::trMasterPageNormal;
1597 if (facingPages)
1598 {
1599 if ((pagecount % 2 == 0) && (masterSpreads[mSpr].count() > 0))
1600 mp = mSpr + "_" + masterSpreads[mSpr][0];
1601 if ((pagecount % 2 == 1) && (masterSpreads[mSpr].count() > 1))
1602 mp = mSpr + "_" + masterSpreads[mSpr][1];
1603 }
1604 else
1605 {
1606 if ((masterSpreads[mSpr].count() > 0))
1607 mp = mSpr + "_" + masterSpreads[mSpr][0];
1608 }
1609 m_Doc->applyMasterPage(mp, m_Doc->currentPageNumber());
1610 }
1611 }
1612 for (QDomNode pageNode = spe.firstChild(); !pageNode.isNull(); pageNode = pageNode.nextSibling())
1613 {
1614 QDomElement pageElement = pageNode.toElement();
1615 if (pageElement.tagName() == "Guide" && pageElement.hasAttribute("Location") && pageElement.hasAttribute("Orientation"))
1616 {
1617 bool convOk = false;
1618 double location = pageElement.attribute("Location").toDouble(&convOk);
1619 if (!convOk)
1620 continue;
1621 QString orientation = pageElement.attribute("Orientation");
1622 if (orientation == "Horizontal")
1623 m_Doc->currentPage()->guides.addHorizontal(location, GuideManagerCore::Standard);
1624 else if (pageElement.attribute("Orientation") == "Vertical")
1625 m_Doc->currentPage()->guides.addVertical(location, GuideManagerCore::Standard);
1626 }
1627 }
1628 }
1629 }
1630 if ((facingPages) && (pagecount % 2 == 0))
1631 {
1632 baseX = m_Doc->currentPage()->xOffset() + m_Doc->currentPage()->width();
1633 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
1634 }
1635 if (!facingPages)
1636 {
1637 baseX = m_Doc->currentPage()->xOffset() + m_Doc->currentPage()->width() / 2.0;
1638 baseY = m_Doc->currentPage()->yOffset() + m_Doc->currentPage()->height() / 2.0;
1639 }
1640 for (QDomNode sp = e.firstChild(); !sp.isNull(); sp = sp.nextSibling())
1641 {
1642 QDomElement spe = sp.toElement();
1643 if ((spe.tagName() == "Rectangle") || (spe.tagName() == "Oval") || (spe.tagName() == "GraphicLine") || (spe.tagName() == "Polygon") || (spe.tagName() == "TextFrame") || (spe.tagName() == "Group") || (spe.tagName() == "Button"))
1644 {
1645 QList<PageItem*> el = parseItemXML(spe);
1646 for (int ec = 0; ec < el.count(); ++ec)
1647 {
1648 m_Doc->Items->append(el.at(ec));
1649 Elements.append(el.at(ec));
1650 }
1651 }
1652 }
1653 }
1654 else if (e.tagName() == "MasterSpread")
1655 {
1656 m_Doc->setMasterPageMode(true);
1657 QString pageNam = e.attribute("Self");
1658 QStringList pages;
1659 ScPage *oldCur = m_Doc->currentPage();
1660 for (QDomNode sp = e.firstChild(); !sp.isNull(); sp = sp.nextSibling())
1661 {
1662 QDomElement spe = sp.toElement();
1663 if (spe.tagName() == "Page")
1664 {
1665 QString itemTrans = spe.attribute("ItemTransform");
1666 ScTextStream list(&itemTrans, QIODevice::ReadOnly);
1667 double a, b, c, d, e1, f;
1668 list >> a >> b >> c >> d >> e1 >> f;
1669 /* Adding the values directly */
1670 QTransform transformation(a, b, c, d, e1, f);
1671 ScPage *addedPage = m_Doc->addMasterPage(mpagecount, pageNam + "_" + spe.attribute("Self"));
1672 m_Doc->setCurrentPage(addedPage);
1673 pages.append(spe.attribute("Self"));
1674 addedPage->clearMasterPageName();
1675 m_Doc->view()->addPage(mpagecount, true);
1676 baseX = addedPage->xOffset();
1677 baseY = addedPage->yOffset() + addedPage->height() / 2.0;
1678 if (!facingPages)
1679 baseX = addedPage->xOffset() + addedPage->width() / 2.0;
1680 else
1681 baseX = addedPage->xOffset() - transformation.dx();
1682 for (QDomNode spp = e.firstChild(); !spp.isNull(); spp = spp.nextSibling())
1683 {
1684 QDomElement spe = spp.toElement();
1685 if ((spe.tagName() == "Rectangle") || (spe.tagName() == "Oval") || (spe.tagName() == "GraphicLine") || (spe.tagName() == "Polygon") || (spe.tagName() == "TextFrame") || (spe.tagName() == "Group") || (spe.tagName() == "Button"))
1686 {
1687 QList<PageItem*> el = parseItemXML(spe);
1688 for (int ec = 0; ec < el.count(); ++ec)
1689 {
1690 PageItem* ite = el.at(ec);
1691 int pgi = m_Doc->OnPage(ite);
1692 if (pgi != -1)
1693 {
1694 m_Doc->Items->append(ite);
1695 Elements.append(ite);
1696 }
1697 }
1698 }
1699 }
1700 mpagecount++;
1701 }
1702 }
1703 masterSpreads.insert(pageNam, pages);
1704 m_Doc->setCurrentPage(oldCur);
1705 m_Doc->setMasterPageMode(false);
1706 }
1707 }
1708 }
1709
parseItemXML(const QDomElement & itElem,const QTransform & pTrans)1710 QList<PageItem*> IdmlPlug::parseItemXML(const QDomElement& itElem, const QTransform& pTrans)
1711 {
1712 QList<PageItem*> GElements;
1713 FPointArray GCoords;
1714 GCoords.resize(0);
1715 GCoords.svgInit();
1716 QString itemTrans = itElem.attribute("ItemTransform");
1717 ScTextStream list(&itemTrans, QIODevice::ReadOnly);
1718 double a, b, c, d, e, f;
1719 list >> a >> b >> c >> d >> e >> f;
1720 /* Adding the values directly */
1721 QTransform transformation(a, b, c, d, e, f);
1722 QString itemName = itElem.attribute("Self");
1723 QString fillColor = def_fillColor;
1724 QString fillGradient = "";
1725 double gstX = def_gradientX;
1726 double gstY = def_gradientY;
1727 double gLen = def_gradientLen;
1728 double gAngle = def_gradientAngle;
1729 int fillGradientTyp = 6;
1730 QString strokeColor = def_strokeColor;
1731 QString strokeGradient = "";
1732 double gstSX = def_gradientStrokeStartX;
1733 double gstSY = def_gradientStrokeStartY;
1734 double gSLen = def_gradientStrokeLength;
1735 double gSAngle = def_gradientStrokeAngle;
1736 int strokeGradientTyp = 6;
1737 double lineWidth = def_lineWidth;
1738 int fillShade = def_fillTint;
1739 int strokeShade = def_strokeTint;
1740 double Opacity = def_Opacity;
1741 int blendMode = def_Blendmode;
1742 double Extra = def_Extra;
1743 double TExtra = def_TExtra;
1744 double BExtra = def_BExtra;
1745 double RExtra = def_RExtra;
1746 int TextColumnCount = def_TextColumnCount;
1747 double TextColumnGutter = def_TextColumnGutter;
1748 //double TextColumnFixedWidth = def_TextColumnFixedWidth;
1749 QString LeftLineEnd = def_LeftLineEnd;
1750 QString RightLineEnd = def_RightLineEnd;
1751 QString imageFit = "None";
1752 PageItem::TextFlowMode textFlow = def_TextFlow;
1753 if (itElem.hasAttribute("AppliedObjectStyle"))
1754 {
1755 QString os = itElem.attribute("AppliedObjectStyle");
1756 if (os != "n")
1757 {
1758 ObjectStyle nstyle;
1759 nstyle.fillColor = def_fillColor;
1760 nstyle.strokeColor = def_strokeColor;
1761 nstyle.fillGradient = "";
1762 nstyle.gradientFillStart = QPointF(def_gradientX, def_gradientY);
1763 nstyle.gradientFillLength = def_gradientLen;
1764 nstyle.gradientFillAngle = def_gradientAngle;
1765 nstyle.strokeGradient = "";
1766 nstyle.gradientStrokeStart = QPointF(def_gradientStrokeStartX, def_gradientStrokeStartY);
1767 nstyle.gradientStrokeAngle = def_gradientStrokeAngle;
1768 nstyle.gradientStrokeLength = def_gradientStrokeLength;
1769 nstyle.lineWidth = def_lineWidth;
1770 nstyle.fillTint = def_fillTint;
1771 nstyle.strokeTint = def_strokeTint;
1772 nstyle.Opacity = def_Opacity;
1773 nstyle.blendMode = def_Blendmode;
1774 nstyle.Extra = def_Extra;
1775 nstyle.TExtra = def_TExtra;
1776 nstyle.BExtra = def_BExtra;
1777 nstyle.RExtra = def_RExtra;
1778 nstyle.TextColumnCount = def_TextColumnCount;
1779 nstyle.TextColumnGutter = def_TextColumnGutter;
1780 nstyle.TextColumnFixedWidth = def_TextColumnFixedWidth;
1781 nstyle.TextFlow = def_TextFlow;
1782 nstyle.parentStyle = "";
1783 resolveObjectStyle(nstyle, os);
1784 fillColor = nstyle.fillColor;
1785 if (!nstyle.fillGradient.isEmpty())
1786 {
1787 fillGradient = nstyle.fillGradient;
1788 fillGradientTyp = gradientTypeMap[fillColor];
1789 }
1790 gstX = nstyle.gradientFillStart.x();
1791 gstY = nstyle.gradientFillStart.y();
1792 gLen = nstyle.gradientFillLength;
1793 gAngle = nstyle.gradientFillAngle;
1794 strokeColor = nstyle.strokeColor;
1795 if (!nstyle.strokeGradient.isEmpty())
1796 {
1797 strokeGradient = nstyle.strokeGradient;
1798 strokeGradientTyp = gradientTypeMap[strokeColor];
1799 }
1800 gstSX = nstyle.gradientStrokeStart.x();
1801 gstSY = nstyle.gradientStrokeStart.y();
1802 gSLen = nstyle.gradientStrokeLength;
1803 gSAngle = nstyle.gradientStrokeAngle;
1804 lineWidth = nstyle.lineWidth;
1805 fillShade = nstyle.fillTint;
1806 strokeShade = nstyle.strokeTint;
1807 Opacity = nstyle.Opacity;
1808 blendMode = nstyle.blendMode;
1809 Extra = nstyle.Extra;
1810 TExtra = nstyle.TExtra;
1811 BExtra = nstyle.BExtra;
1812 RExtra = nstyle.RExtra;
1813 TextColumnCount = nstyle.TextColumnCount;
1814 TextColumnGutter = nstyle.TextColumnGutter;
1815 // TextColumnFixedWidth = nstyle.TextColumnFixedWidth;
1816 textFlow = nstyle.TextFlow;
1817 LeftLineEnd = nstyle.LeftLineEnd;
1818 RightLineEnd = nstyle.RightLineEnd;
1819 }
1820 }
1821 if (itElem.hasAttribute("FillColor"))
1822 {
1823 fillColor = itElem.attribute("FillColor");
1824 if (colorTranslate.contains(fillColor))
1825 fillColor = colorTranslate[fillColor];
1826 else
1827 {
1828 if (gradientTranslate.contains(fillColor))
1829 {
1830 fillGradientTyp = gradientTypeMap[fillColor];
1831 fillGradient = gradientTranslate[fillColor];
1832 }
1833 }
1834 }
1835 if (itElem.hasAttribute("GradientFillStart"))
1836 {
1837 QString fillGStart = itElem.attribute("GradientFillStart");
1838 ScTextStream Code(&fillGStart, QIODevice::ReadOnly);
1839 Code >> gstX >> gstY;
1840 gLen = itElem.attribute("GradientFillLength").toDouble();
1841 gAngle = itElem.attribute("GradientFillAngle").toDouble();
1842 }
1843 if (itElem.hasAttribute("StrokeColor"))
1844 {
1845 strokeColor = itElem.attribute("StrokeColor");
1846 if (colorTranslate.contains(strokeColor))
1847 strokeColor = colorTranslate[strokeColor];
1848 else
1849 {
1850 if (gradientTranslate.contains(strokeColor))
1851 {
1852 strokeGradientTyp = gradientTypeMap[strokeColor];
1853 strokeGradient = gradientTranslate[strokeColor];
1854 }
1855 }
1856 }
1857 if (itElem.hasAttribute("GradientStrokeStart"))
1858 {
1859 QString fillGStart = itElem.attribute("GradientStrokeStart");
1860 ScTextStream Code(&fillGStart, QIODevice::ReadOnly);
1861 Code >> gstSX >> gstSY;
1862 gSLen = itElem.attribute("GradientStrokeLength").toDouble();
1863 gSAngle = itElem.attribute("GradientStrokeAngle").toDouble();
1864 }
1865 if (itElem.hasAttribute("StrokeWeight"))
1866 lineWidth = itElem.attribute("StrokeWeight").toDouble();
1867 if (itElem.hasAttribute("FillTint"))
1868 {
1869 if (itElem.attribute("FillTint").toInt() != -1)
1870 fillShade = itElem.attribute("FillTint").toInt();
1871 }
1872 if (fillShade < 0)
1873 fillShade = 100;
1874 if (itElem.hasAttribute("StrokeTint"))
1875 {
1876 if (itElem.attribute("StrokeTint").toInt() != -1)
1877 strokeShade = itElem.attribute("StrokeTint").toInt();
1878 }
1879 if (strokeShade < 0)
1880 strokeShade = 100;
1881 if (itElem.hasAttribute("RightLineEnd"))
1882 RightLineEnd = itElem.attribute("RightLineEnd");
1883 if (itElem.hasAttribute("LeftLineEnd"))
1884 LeftLineEnd = itElem.attribute("LeftLineEnd");
1885 QString forLayer = itElem.attribute("ItemLayer");
1886 if (layerTranslate.contains(forLayer))
1887 forLayer = layerTranslate[forLayer];
1888 else
1889 forLayer = m_Doc->layerName(0);
1890 int layerNum = 0;
1891 ScLayers::iterator itend = m_Doc->Layers.end();
1892 ScLayers::iterator it;
1893 for (it = m_Doc->Layers.begin(); it != itend; ++it)
1894 {
1895 if (it->Name == forLayer)
1896 {
1897 layerNum = it->ID;
1898 break;
1899 }
1900 }
1901 bool isOpen = false;
1902 bool isGroup = false;
1903 bool realGroup = false;
1904 bool isImage = false;
1905 bool isPathText = false;
1906 if (itElem.tagName() == "Group")
1907 realGroup = true;
1908 QString imageType = "";
1909 QByteArray imageData = "";
1910 QString imageFileName = "";
1911 QTransform imageTransform;
1912 double imageDX = 0;
1913 double imageDY = 0;
1914 QString storyForPath = "";
1915 int pathTextType = 0;
1916 double pathTextStart = 0;
1917 for (QDomNode it = itElem.firstChild(); !it.isNull(); it = it.nextSibling())
1918 {
1919 QDomElement ite = it.toElement();
1920 if (ite.tagName() == "Properties")
1921 {
1922 for (QDomNode itp = ite.firstChild(); !itp.isNull(); itp = itp.nextSibling())
1923 {
1924 QDomElement itpg = itp.toElement();
1925 if (itpg.tagName() == "PathGeometry")
1926 {
1927 for (QDomNode itg = itpg.firstChild(); !itg.isNull(); itg = itg.nextSibling())
1928 {
1929 QDomElement itgg = itg.toElement();
1930 if (itgg.tagName() == "GeometryPathType")
1931 {
1932 isOpen = (itgg.attribute("PathOpen") == "true");
1933 for (QDomNode itpp = itgg.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
1934 {
1935 QDomElement itpa = itpp.toElement();
1936 if (itpa.tagName() == "PathPointArray")
1937 {
1938 bool firstPoint = true;
1939 QPointF firstBezPoint;
1940 QPointF firstAncPoint;
1941 QList<QPointF> pointList;
1942 for (QDomNode itpap = itpa.firstChild(); !itpap.isNull(); itpap = itpap.nextSibling())
1943 {
1944 QDomElement itpo = itpap.toElement();
1945 if (itpo.tagName() == "PathPointType")
1946 {
1947 double x1, y1, x2, y2, x3, y3;
1948 QString anchor = itpo.attribute("Anchor");
1949 QString lDir = itpo.attribute("LeftDirection");
1950 QString rDir = itpo.attribute("RightDirection");
1951 ScTextStream an(&anchor, QIODevice::ReadOnly);
1952 an >> x1 >> y1;
1953 QPointF aP = QPointF(x1, y1);
1954 ScTextStream lr(&lDir, QIODevice::ReadOnly);
1955 lr >> x2 >> y2;
1956 QPointF lP = QPointF(x2, y2);
1957 ScTextStream rr(&rDir, QIODevice::ReadOnly);
1958 rr >> x3 >> y3;
1959 QPointF rP = QPointF(x3, y3);
1960
1961 if (firstPoint)
1962 {
1963 firstBezPoint = lP;
1964 firstAncPoint = aP;
1965 pointList.append(aP);
1966 pointList.append(rP);
1967 firstPoint = false;
1968 }
1969 else
1970 {
1971 if (itElem.tagName() == "GraphicLine")
1972 {
1973 pointList.append(lP);
1974 pointList.append(aP);
1975 }
1976 else
1977 {
1978 pointList.append(lP);
1979 pointList.append(aP);
1980 pointList.append(rP);
1981 }
1982 }
1983 }
1984 }
1985 if (itElem.tagName() == "GraphicLine")
1986 {
1987 if (pointList.count() > 1)
1988 {
1989 GCoords.svgMoveTo(pointList[0].x(), pointList[0].y());
1990 QPointF p1 = pointList[1];
1991 QPointF p2 = pointList[2];
1992 QPointF p3 = pointList[3];
1993 GCoords.svgCurveToCubic(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
1994 }
1995 }
1996 else
1997 {
1998 if (isOpen)
1999 {
2000 pointList.removeLast();
2001 }
2002 else
2003 {
2004 pointList.append(firstBezPoint);
2005 pointList.append(firstAncPoint);
2006 }
2007 if (pointList.count() > 1)
2008 {
2009 GCoords.svgMoveTo(pointList[0].x(), pointList[0].y());
2010 for (int a = 1; a < pointList.count(); a += 3)
2011 {
2012 QPointF p1 = pointList[a];
2013 QPointF p2 = pointList[a+1];
2014 QPointF p3 = pointList[a+2];
2015 GCoords.svgCurveToCubic(p1.x(), p1.y(), p2.x(), p2.y(), p3.x(), p3.y());
2016 }
2017 }
2018 }
2019 }
2020 }
2021 if (!isOpen)
2022 GCoords.svgClosePath();
2023 }
2024 }
2025 }
2026 }
2027 }
2028 else if ((ite.tagName() == "Rectangle") || (ite.tagName() == "Oval") || (ite.tagName() == "GraphicLine") || (ite.tagName() == "Polygon") || (ite.tagName() == "TextFrame") || (ite.tagName() == "Group") || (ite.tagName() == "Button"))
2029 {
2030 isGroup = true;
2031 QList<PageItem*> el = parseItemXML(ite, transformation * pTrans);
2032 for (int ec = 0; ec < el.count(); ++ec)
2033 {
2034 GElements.append(el.at(ec));
2035 }
2036 }
2037 else if (ite.tagName() == "FrameFittingOption")
2038 {
2039 if (ite.hasAttribute("FittingOnEmptyFrame"))
2040 imageFit = ite.attribute("FittingOnEmptyFrame");
2041 if (ite.hasAttribute("LeftCrop"))
2042 imageDX = ite.attribute("LeftCrop").toDouble();
2043 if (ite.hasAttribute("TopCrop"))
2044 imageDY = ite.attribute("TopCrop").toDouble();
2045 }
2046 else if (ite.tagName() == "TransparencySetting")
2047 {
2048 for (QDomNode itp = ite.firstChild(); !itp.isNull(); itp = itp.nextSibling())
2049 {
2050 QDomElement itpg = itp.toElement();
2051 if (itpg.tagName() == "BlendingSetting")
2052 {
2053 Opacity = 1.0 - (itpg.attribute("Opacity", "100").toDouble() / 100.0);
2054 blendMode = convertBlendMode(itpg.attribute("BlendMode", "Normal"));
2055 }
2056 }
2057 }
2058 else if (ite.tagName() == "TextWrapPreference")
2059 {
2060 if (ite.attribute("TextWrapMode") == "None")
2061 textFlow = PageItem::TextFlowDisabled;
2062 else if (ite.attribute("TextWrapMode") == "BoundingBoxTextWrap")
2063 textFlow = PageItem::TextFlowUsesBoundingBox;
2064 else if (ite.attribute("TextWrapMode") == "Contour")
2065 textFlow = PageItem::TextFlowUsesFrameShape;
2066 }
2067 else if (ite.tagName() == "TextFramePreference")
2068 {
2069 if (ite.hasAttribute("TextColumnCount"))
2070 TextColumnCount = ite.attribute("TextColumnCount").toInt();
2071 if (ite.hasAttribute("TextColumnGutter"))
2072 TextColumnGutter = ite.attribute("TextColumnGutter").toDouble();
2073 // if (ite.hasAttribute("TextColumnFixedWidth"))
2074 // TextColumnFixedWidth = ite.attribute("TextColumnFixedWidth").toDouble();
2075 for (QDomNode itpp = ite.firstChild(); !itpp.isNull(); itpp = itpp.nextSibling())
2076 {
2077 QDomElement i = itpp.toElement();
2078 if (i.tagName() == "Properties")
2079 {
2080 for (QDomNode it = i.firstChild(); !it.isNull(); it = it.nextSibling())
2081 {
2082 QDomElement itx = it.toElement();
2083 if (itx.tagName() == "InsetSpacing")
2084 {
2085 if (itx.attribute("type") == "unit")
2086 Extra = TExtra = BExtra = RExtra = itx.text().toDouble();
2087 else if (itx.attribute("type") == "list")
2088 {
2089 int cc = 0;
2090 for (QDomNode ity = itx.firstChild(); !ity.isNull(); ity = ity.nextSibling())
2091 {
2092 QDomElement itxx = ity.toElement();
2093 if (itxx.tagName() == "ListItem")
2094 {
2095 double val = itxx.text().toDouble();
2096 if (cc == 0)
2097 Extra = val;
2098 else if (cc == 1)
2099 TExtra = val;
2100 else if (cc == 2)
2101 RExtra = val;
2102 else if (cc == 3)
2103 BExtra = val;
2104 cc++;
2105 }
2106 }
2107 }
2108 }
2109 }
2110 }
2111 }
2112 }
2113 else if ((ite.tagName() == "Image") || (ite.tagName() == "EPS") || (ite.tagName() == "PDF") || (ite.tagName() == "PICT"))
2114 {
2115 imageType = ite.attribute("ImageTypeName");
2116 isImage = true;
2117 QString imageTrans = ite.attribute("ItemTransform", "1 0 0 1 0 0");
2118 ScTextStream list(&imageTrans, QIODevice::ReadOnly);
2119 double a, b, c, d, e, f;
2120 list >> a >> b >> c >> d >> e >> f;
2121 imageTransform = QTransform(a, b, c, d, e, f) * transformation;
2122 for (QDomNode itp = ite.firstChild(); !itp.isNull(); itp = itp.nextSibling())
2123 {
2124 QDomElement itpg = itp.toElement();
2125 if (itpg.tagName() == "Properties")
2126 imageData = QByteArray::fromBase64(getNodeValue(itpg, "Contents").toLatin1());
2127 if (itpg.tagName() == "Link")
2128 {
2129 if (itpg.hasAttribute("LinkResourceURI"))
2130 imageFileName = itpg.attribute("LinkResourceURI");
2131 }
2132 }
2133 }
2134 else if (ite.tagName() == "WMF")
2135 {
2136 qDebug() << "WMF";
2137 }
2138 else if (ite.tagName() == "ImportedPage")
2139 {
2140 qDebug() << "ImportedPage";
2141 }
2142 else if (ite.tagName() == "TextPath")
2143 {
2144 isPathText = true;
2145 storyForPath = ite.attribute("ParentStory");
2146 if (ite.attribute("PathEffect") == "RainbowPathEffect")
2147 pathTextType = 0;
2148 else if (ite.attribute("PathEffect") == "StairStepPathEffect")
2149 pathTextType = 1;
2150 else if (ite.attribute("PathEffect") == "SkewPathEffect")
2151 pathTextType = 2;
2152 else if (ite.attribute("PathEffect") == "RibbonPathEffect") // not implemented in PathText yet
2153 pathTextType = 0;
2154 else if (ite.attribute("PathEffect") == "GravityPathEffect") // not implemented in PathText yet
2155 pathTextType = 0;
2156 if (ite.hasAttribute("StartBracket"))
2157 pathTextStart = ite.attribute("StartBracket").toDouble();
2158 }
2159 }
2160 if (!GCoords.empty())
2161 {
2162 int z;
2163 QTransform finalMat = transformation * pTrans;
2164 double scX, scY, rot, dx, dy;
2165 getTransformValuesFromMatrix(finalMat, scX, scY, rot, dx, dy);
2166 if ((finalMat.m11() < 0) && (finalMat.m12() == 0) && (finalMat.m21() == 0))
2167 {
2168 QLineF line = QLineF(0.0, 0.0, 1.0, 0.0);
2169 line.setAngle(rot);
2170 QTransform matrix;
2171 matrix.scale(-1, 0);
2172 line = matrix.map(line);
2173 rot = line.angle();
2174 scX *= -1;
2175 }
2176 if ((finalMat.m22() < 0) && (finalMat.m12() == 0) && (finalMat.m21() == 0))
2177 {
2178 scY *= -1;
2179 }
2180 FPoint grOffset(getMinClipF(&GCoords));
2181 GCoords.map(finalMat);
2182 if (isGroup)
2183 {
2184 QString pre = "";
2185 FPointArray gClip;
2186 if (!realGroup)
2187 {
2188 pre = "Group_";
2189 if (!fillGradient.isEmpty())
2190 fillColor = CommonStrings::None;
2191 if (itElem.tagName() == "TextFrame")
2192 {
2193 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2194 PageItem* item = m_Doc->Items->at(z);
2195 QString story = itElem.attribute("ParentStory");
2196 if (!storyMap.contains(story))
2197 storyMap.insert(story, item);
2198 if (itElem.hasAttribute("NextTextFrame"))
2199 {
2200 if (itElem.attribute("NextTextFrame") != "n")
2201 frameLinks.insert(item, itElem.attribute("NextTextFrame"));
2202 }
2203 frameTargets.insert(itemName, item);
2204 item->setTextToFrameDistLeft(Extra);
2205 item->setTextToFrameDistTop(TExtra);
2206 item->setTextToFrameDistRight(RExtra);
2207 item->setTextToFrameDistBottom(BExtra);
2208 item->setColumns(TextColumnCount);
2209 item->setColumnGap(TextColumnGutter);
2210 }
2211 else if (isPathText)
2212 {
2213 z = m_Doc->itemAdd(PageItem::PathText, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, strokeColor);
2214 if (!storyMap.contains(storyForPath))
2215 storyMap.insert(storyForPath, m_Doc->Items->at(z));
2216 PageItem* item = m_Doc->Items->at(z);
2217 item->setPathTextType(pathTextType);
2218 item->setTextToFrameDistLeft(pathTextStart);
2219 }
2220 else if (isImage)
2221 {
2222 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2223 }
2224 else
2225 {
2226 if (isOpen)
2227 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2228 else
2229 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2230 }
2231 PageItem* item = m_Doc->Items->at(z);
2232 item->PoLine = GCoords.copy();
2233 double dx = 0;
2234 double dy = 0;
2235 if (rot != 0)
2236 {
2237 QTransform mr;
2238 FPoint grOffset2(getMinClipF(&item->PoLine));
2239 mr.translate(-grOffset2.x(), -grOffset2.y());
2240 mr.rotate(rot);
2241 mr.translate(grOffset2.x(), grOffset2.y());
2242 item->PoLine.map(mr);
2243 FPoint grOffset3(getMinClipF(&item->PoLine));
2244 dx = grOffset2.x() - grOffset3.x();
2245 dy = grOffset2.y() - grOffset3.y();
2246 }
2247 item->ClipEdited = true;
2248 item->FrameType = 3;
2249 item->setFillColor(fillColor);
2250 item->setLineColor(strokeColor);
2251 item->setFillShade(fillShade);
2252 item->setLineShade(strokeShade);
2253 item->setFillEvenOdd(false);
2254 if (!fillGradient.isEmpty())
2255 {
2256 QLineF gradientVector = QLineF(gstX, gstY, gstX+1, gstY);
2257 gradientVector.setLength(gLen);
2258 gradientVector.setAngle(gAngle);
2259 gradientVector.translate(-grOffset.x(), -grOffset.y());
2260 item->fill_gradient = m_Doc->docGradients[fillGradient];
2261 item->setGradientVector(gradientVector.x1(), gradientVector.y1(), gradientVector.x2(), gradientVector.y2(), gradientVector.x1(), gradientVector.y1(), 1, 0);
2262 item->setGradient(fillGradient);
2263 item->setGradientType(fillGradientTyp);
2264 }
2265 if (!strokeGradient.isEmpty())
2266 {
2267 QLineF gradientVector = QLineF(gstSX, gstSY, gstSX+1, gstSY);
2268 gradientVector.setLength(gSLen);
2269 gradientVector.setAngle(gSAngle);
2270 gradientVector.translate(-grOffset.x(), -grOffset.y());
2271 item->stroke_gradient = m_Doc->docGradients[strokeGradient];
2272 item->setStrokeGradientVector(gradientVector.x1(), gradientVector.y1(), gradientVector.x2(), gradientVector.y2(), gradientVector.x1(), gradientVector.y1(), 1, 0);
2273 item->setStrokeGradient(strokeGradient);
2274 item->setStrokeGradientType(strokeGradientTyp);
2275 }
2276 FPoint wh = getMaxClipF(&item->PoLine);
2277 item->setWidthHeight(wh.x(),wh.y());
2278 item->setTextFlowMode(textFlow);
2279 m_Doc->adjustItemSize(item);
2280 item->setRotation(-rot, true);
2281 item->moveBy(dx, dy, true);
2282 if (isPathText)
2283 {
2284 if (isOpen)
2285 {
2286 if (scX < 0)
2287 {
2288 item->PoLine.reverse();
2289 }
2290 }
2291 else
2292 {
2293 if (scX > 0)
2294 {
2295 double totalCurveLen = 0;
2296 for (int segs = 0; segs < item->PoLine.size()-3; segs += 4)
2297 {
2298 totalCurveLen += item->PoLine.lenPathSeg(segs);
2299 }
2300 item->setTextToFrameDistLeft(totalCurveLen - pathTextStart);
2301 item->PoLine.reverse();
2302 }
2303 }
2304 }
2305 item->OldB2 = item->width();
2306 item->OldH2 = item->height();
2307 if (item->isPolyLine())
2308 {
2309 if (LeftLineEnd != "None")
2310 {
2311 if (LeftLineEnd == "SimpleArrowHead")
2312 item->setStartArrowIndex(2);
2313 else if (LeftLineEnd == "SimpleWideArrowHead")
2314 item->setStartArrowIndex(2);
2315 else if (LeftLineEnd == "TriangleArrowHead")
2316 item->setStartArrowIndex(8);
2317 else if (LeftLineEnd == "TriangleWideArrowHead")
2318 item->setStartArrowIndex(8);
2319 else if (LeftLineEnd == "BarbedArrowHead")
2320 item->setStartArrowIndex(23);
2321 else if (LeftLineEnd == "CurvedArrowHead")
2322 item->setStartArrowIndex(26);
2323 else if (LeftLineEnd == "CircleArrowHead")
2324 item->setStartArrowIndex(17);
2325 else if (LeftLineEnd == "CircleSolidArrowHead")
2326 item->setStartArrowIndex(17);
2327 else if (LeftLineEnd == "Square-ArrowHead")
2328 item->setStartArrowIndex(5);
2329 else if (LeftLineEnd == "SquareSolid-ArrowHead")
2330 item->setStartArrowIndex(5);
2331 else if (LeftLineEnd == "BarArrowHead")
2332 item->setStartArrowIndex(35);
2333 }
2334 if (RightLineEnd != "None")
2335 {
2336 if (RightLineEnd == "SimpleArrowHead")
2337 item->setEndArrowIndex(2);
2338 else if (RightLineEnd == "SimpleWideArrowHead")
2339 item->setEndArrowIndex(2);
2340 else if (RightLineEnd == "TriangleArrowHead")
2341 item->setEndArrowIndex(8);
2342 else if (RightLineEnd == "TriangleWideArrowHead")
2343 item->setEndArrowIndex(8);
2344 else if (RightLineEnd == "BarbedArrowHead")
2345 item->setEndArrowIndex(23);
2346 else if (RightLineEnd == "CurvedArrowHead")
2347 item->setEndArrowIndex(26);
2348 else if (RightLineEnd == "CircleArrowHead")
2349 item->setEndArrowIndex(17);
2350 else if (RightLineEnd == "CircleSolidArrowHead")
2351 item->setEndArrowIndex(17);
2352 else if (RightLineEnd == "Square-ArrowHead")
2353 item->setEndArrowIndex(7);
2354 else if (RightLineEnd == "SquareSolid-ArrowHead")
2355 item->setEndArrowIndex(7);
2356 else if (RightLineEnd == "BarArrowHead")
2357 item->setEndArrowIndex(35);
2358 }
2359 }
2360 item->updateClip();
2361 item->setItemName(itemName);
2362 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2363 item->setLayer(layerNum);
2364 if ((itElem.tagName() == "Rectangle") && (itElem.attribute("CornerOption") == "RoundedCorner"))
2365 {
2366 item->SetRectFrame();
2367 item->setCornerRadius(itElem.attribute("CornerRadius", "0").toDouble());
2368 item->SetFrameRound();
2369 gClip = item->PoLine.copy();
2370 }
2371 item->OwnPage = m_Doc->OnPage(item);
2372 item->ContourLine = item->PoLine.copy();
2373 GElements.prepend(m_Doc->Items->takeAt(z));
2374 }
2375 z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, baseX, baseY, 10, 10, 0, CommonStrings::None, CommonStrings::None);
2376 PageItem *itemg = m_Doc->Items->at(z);
2377 double dx = 0;
2378 double dy = 0;
2379 if (rot != 0)
2380 {
2381 QTransform mr;
2382 FPoint grOffset2(getMinClipF(&GCoords));
2383 mr.translate(-grOffset2.x(), -grOffset2.y());
2384 mr.rotate(rot);
2385 mr.translate(grOffset2.x(), grOffset2.y());
2386 GCoords.map(mr);
2387 FPoint grOffset3(getMinClipF(&GCoords));
2388 dx = grOffset2.x() - grOffset3.x();
2389 dy = grOffset2.y() - grOffset3.y();
2390 }
2391 itemg->PoLine = GCoords.copy();
2392 itemg->ClipEdited = true;
2393 itemg->FrameType = 3;
2394 FPoint wh = getMaxClipF(&itemg->PoLine);
2395 itemg->setWidthHeight(wh.x(),wh.y());
2396 itemg->setTextFlowMode(textFlow);
2397 m_Doc->adjustItemSize(itemg, true);
2398 itemg->moveBy(dx, dy, true);
2399 itemg->setRotation(-rot, true);
2400 itemg->OldB2 = itemg->width();
2401 itemg->OldH2 = itemg->height();
2402 if (!gClip.isEmpty())
2403 itemg->PoLine = gClip.copy();
2404 itemg->updateClip();
2405 itemg->setItemName(pre+itemName);
2406 itemg->setFillTransparency(Opacity);
2407 itemg->setLineTransparency(Opacity);
2408 itemg->setLineBlendmode(blendMode);
2409 itemg->setFillBlendmode(blendMode);
2410 itemg->setFillEvenOdd(false);
2411 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2412 itemg->setLayer(layerNum);
2413 itemg->OwnPage = m_Doc->OnPage(itemg);
2414 itemg->ContourLine = itemg->PoLine.copy();
2415 m_Doc->Items->takeAt(z);
2416 m_Doc->groupObjectsToItem(itemg, GElements);
2417 m_Doc->GroupOnPage(itemg);
2418 }
2419 else
2420 {
2421 if (!fillGradient.isEmpty())
2422 fillColor = CommonStrings::None;
2423 if (itElem.tagName() == "TextFrame")
2424 {
2425 z = m_Doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2426 PageItem* item = m_Doc->Items->at(z);
2427 QString story = itElem.attribute("ParentStory");
2428 if (!storyMap.contains(story))
2429 storyMap.insert(story, item);
2430 if (itElem.hasAttribute("NextTextFrame"))
2431 {
2432 if (itElem.attribute("NextTextFrame") != "n")
2433 frameLinks.insert(item, itElem.attribute("NextTextFrame"));
2434 }
2435 frameTargets.insert(itemName, item);
2436 item->setTextToFrameDistLeft(Extra);
2437 item->setTextToFrameDistTop(TExtra);
2438 item->setTextToFrameDistRight(RExtra);
2439 item->setTextToFrameDistBottom(BExtra);
2440 item->setColumns(TextColumnCount);
2441 item->setColumnGap(TextColumnGutter);
2442 }
2443 else if (isPathText)
2444 {
2445 z = m_Doc->itemAdd(PageItem::PathText, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, CommonStrings::None, strokeColor);
2446 if (!storyMap.contains(storyForPath))
2447 storyMap.insert(storyForPath, m_Doc->Items->at(z));
2448 PageItem* item = m_Doc->Items->at(z);
2449 item->setPathTextType(pathTextType);
2450 item->setTextToFrameDistLeft(pathTextStart);
2451 }
2452 else if (isImage)
2453 {
2454 z = m_Doc->itemAdd(PageItem::ImageFrame, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2455 }
2456 else
2457 {
2458 if (isOpen)
2459 z = m_Doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2460 else
2461 z = m_Doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, baseX, baseY, 10, 10, lineWidth, fillColor, strokeColor);
2462 }
2463 PageItem* item = m_Doc->Items->at(z);
2464 double dx = 0;
2465 double dy = 0;
2466 if (rot != 0)
2467 {
2468 QTransform mr;
2469 FPoint grOffset2(getMinClipF(&GCoords));
2470 mr.translate(-grOffset2.x(), -grOffset2.y());
2471 mr.rotate(rot);
2472 mr.translate(grOffset2.x(), grOffset2.y());
2473 GCoords.map(mr);
2474 FPoint grOffset3(getMinClipF(&GCoords));
2475 dx = grOffset2.x() - grOffset3.x();
2476 dy = grOffset2.y() - grOffset3.y();
2477 }
2478 item->PoLine = GCoords.copy();
2479 item->ClipEdited = true;
2480 item->FrameType = 3;
2481 item->setFillColor(fillColor);
2482 item->setLineColor(strokeColor);
2483 item->setFillShade(fillShade);
2484 item->setLineShade(strokeShade);
2485 item->setFillTransparency(Opacity);
2486 item->setLineTransparency(Opacity);
2487 item->setLineBlendmode(blendMode);
2488 item->setFillBlendmode(blendMode);
2489 item->setFillEvenOdd(false);
2490 if (!fillGradient.isEmpty())
2491 {
2492 QLineF gradientVector = QLineF(gstX, gstY, gstX+1, gstY);
2493 gradientVector.setLength(gLen);
2494 gradientVector.setAngle(gAngle);
2495 gradientVector.translate(-grOffset.x(), -grOffset.y());
2496 item->fill_gradient = m_Doc->docGradients[fillGradient];
2497 item->setGradientVector(gradientVector.x1(), gradientVector.y1(), gradientVector.x2(), gradientVector.y2(), gradientVector.x1(), gradientVector.y1(), 1, 0);
2498 item->setGradient(fillGradient);
2499 item->setGradientType(fillGradientTyp);
2500 }
2501 if (!strokeGradient.isEmpty())
2502 {
2503 QLineF gradientVector = QLineF(gstSX, gstSY, gstSX+1, gstSY);
2504 gradientVector.setLength(gSLen);
2505 gradientVector.setAngle(gSAngle);
2506 gradientVector.translate(-grOffset.x(), -grOffset.y());
2507 item->stroke_gradient = m_Doc->docGradients[strokeGradient];
2508 item->setStrokeGradientVector(gradientVector.x1(), gradientVector.y1(), gradientVector.x2(), gradientVector.y2(), gradientVector.x1(), gradientVector.y1(), 1, 0);
2509 item->setStrokeGradient(strokeGradient);
2510 item->setStrokeGradientType(strokeGradientTyp);
2511 }
2512 FPoint wh = getMaxClipF(&item->PoLine);
2513 item->setWidthHeight(wh.x(),wh.y());
2514 item->setTextFlowMode(textFlow);
2515 m_Doc->adjustItemSize(item);
2516 item->moveBy(dx, dy, true);
2517 if (isPathText)
2518 {
2519 if (isOpen)
2520 {
2521 if (scX < 0)
2522 {
2523 item->PoLine.reverse();
2524 }
2525 }
2526 else
2527 {
2528 if (scX > 0)
2529 {
2530 double totalCurveLen = 0;
2531 for (int segs = 0; segs < item->PoLine.size()-3; segs += 4)
2532 {
2533 totalCurveLen += item->PoLine.lenPathSeg(segs);
2534 }
2535 item->setTextToFrameDistLeft(totalCurveLen - pathTextStart);
2536 item->PoLine.reverse();
2537 }
2538 }
2539 }
2540 QRectF br = QRectF(0, 0, item->width(), item->height());
2541 QTransform ma;
2542 ma.rotate(-rot);
2543 QRectF br2 = ma.mapRect(br);
2544 item->moveBy(br.x() - br2.x(), br.y() - br2.y(), true);
2545 item->setRotation(-rot, true);
2546 item->OldB2 = item->width();
2547 item->OldH2 = item->height();
2548 if (item->isPolyLine())
2549 {
2550 if (LeftLineEnd != "None")
2551 {
2552 if (LeftLineEnd == "SimpleArrowHead")
2553 item->setStartArrowIndex(2);
2554 else if (LeftLineEnd == "SimpleWideArrowHead")
2555 item->setStartArrowIndex(2);
2556 else if (LeftLineEnd == "TriangleArrowHead")
2557 item->setStartArrowIndex(8);
2558 else if (LeftLineEnd == "TriangleWideArrowHead")
2559 item->setStartArrowIndex(8);
2560 else if (LeftLineEnd == "BarbedArrowHead")
2561 item->setStartArrowIndex(23);
2562 else if (LeftLineEnd == "CurvedArrowHead")
2563 item->setStartArrowIndex(26);
2564 else if (LeftLineEnd == "CircleArrowHead")
2565 item->setStartArrowIndex(17);
2566 else if (LeftLineEnd == "CircleSolidArrowHead")
2567 item->setStartArrowIndex(17);
2568 else if (LeftLineEnd == "Square-ArrowHead")
2569 item->setStartArrowIndex(5);
2570 else if (LeftLineEnd == "SquareSolid-ArrowHead")
2571 item->setStartArrowIndex(5);
2572 else if (LeftLineEnd == "BarArrowHead")
2573 item->setStartArrowIndex(35);
2574 }
2575 if (RightLineEnd != "None")
2576 {
2577 if (RightLineEnd == "SimpleArrowHead")
2578 item->setEndArrowIndex(2);
2579 else if (RightLineEnd == "SimpleWideArrowHead")
2580 item->setEndArrowIndex(2);
2581 else if (RightLineEnd == "TriangleArrowHead")
2582 item->setEndArrowIndex(8);
2583 else if (RightLineEnd == "TriangleWideArrowHead")
2584 item->setEndArrowIndex(8);
2585 else if (RightLineEnd == "BarbedArrowHead")
2586 item->setEndArrowIndex(23);
2587 else if (RightLineEnd == "CurvedArrowHead")
2588 item->setEndArrowIndex(26);
2589 else if (RightLineEnd == "CircleArrowHead")
2590 item->setEndArrowIndex(17);
2591 else if (RightLineEnd == "CircleSolidArrowHead")
2592 item->setEndArrowIndex(17);
2593 else if (RightLineEnd == "Square-ArrowHead")
2594 item->setEndArrowIndex(7);
2595 else if (RightLineEnd == "SquareSolid-ArrowHead")
2596 item->setEndArrowIndex(7);
2597 else if (RightLineEnd == "BarArrowHead")
2598 item->setEndArrowIndex(35);
2599 }
2600 }
2601 item->updateClip();
2602 item->setItemName(itemName);
2603 item->OwnPage = m_Doc->OnPage(item);
2604 item->ContourLine = item->PoLine.copy();
2605 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2606 item->setLayer(layerNum);
2607 if ((itElem.tagName() == "Rectangle") && (itElem.attribute("CornerOption") == "RoundedCorner"))
2608 {
2609 item->SetRectFrame();
2610 item->setCornerRadius(itElem.attribute("CornerRadius", "0").toDouble());
2611 item->SetFrameRound();
2612 }
2613 if (isImage)
2614 {
2615 double scXi, scYi, roti, dxi, dyi;
2616 getTransformValuesFromMatrix(imageTransform, scXi, scYi, roti, dxi, dyi);
2617 if (imageData.count() > 0)
2618 {
2619 QString imgExt = "";
2620 if (imageType.contains("EPS", Qt::CaseInsensitive))
2621 imgExt = "eps";
2622 else if (imageType.contains("GIF", Qt::CaseInsensitive))
2623 imgExt = "gif";
2624 else if (imageType.contains("JPEG", Qt::CaseInsensitive))
2625 imgExt = "jpg";
2626 else if (imageType.contains("PDF", Qt::CaseInsensitive))
2627 imgExt = "pdf";
2628 else if (imageType.contains("PICT", Qt::CaseInsensitive))
2629 imgExt = "pict";
2630 else if (imageType.contains("PNG", Qt::CaseInsensitive))
2631 imgExt = "png";
2632 else if (imageType.contains("PSD", Qt::CaseInsensitive))
2633 imgExt = "psd";
2634 else if (imageType.contains("Photoshop", Qt::CaseInsensitive))
2635 imgExt = "psd";
2636 else if (imageType.contains("TIFF", Qt::CaseInsensitive))
2637 imgExt = "tif";
2638 QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_idml_XXXXXX." + imgExt);
2639 tempFile->setAutoRemove(false);
2640 if (tempFile->open())
2641 {
2642 QString fileName = getLongPathName(tempFile->fileName());
2643 if (!fileName.isEmpty())
2644 {
2645 tempFile->write(imageData);
2646 tempFile->close();
2647 item->isInlineImage = true;
2648 item->isTempFile = true;
2649 item->AspectRatio = true;
2650 if (imageFit == "None")
2651 item->ScaleType = true;
2652 else if (imageFit == "ContentToFrame")
2653 item->ScaleType = false;
2654 else if (imageFit == "Proportionally")
2655 {
2656 item->ScaleType = false;
2657 item->AspectRatio = false;
2658 }
2659 m_Doc->loadPict(fileName, item);
2660 item->setImageXYScale(scXi / item->pixm.imgInfo.xres * 72, scYi / item->pixm.imgInfo.xres * 72);
2661 item->setImageXYOffset(-imageDX * scXi / item->imageXScale(), -imageDY * scXi / item->imageYScale());
2662 item->setImageRotation(-roti);
2663 item->adjustPictScale();
2664 }
2665 }
2666 delete tempFile;
2667 }
2668 else
2669 {
2670 QUrl url = QUrl(imageFileName);
2671 QString fiNam = url.toLocalFile();
2672 QFileInfo fi(fiNam);
2673 QByteArray fileName;
2674 if (fi.exists())
2675 fileName = url.toLocalFile().toLocal8Bit();
2676 else
2677 {
2678 fileName = fi.fileName().toLocal8Bit();
2679 fileName.prepend("./Links/");
2680 QFileInfo fi2(fileName);
2681 if (!fi2.exists())
2682 fileName = fi.fileName().toLocal8Bit();
2683 }
2684 item->AspectRatio = true;
2685 if (imageFit == "None")
2686 item->ScaleType = true;
2687 else if (imageFit == "ContentToFrame")
2688 item->ScaleType = false;
2689 else if (imageFit == "Proportionally")
2690 {
2691 item->ScaleType = false;
2692 item->AspectRatio = false;
2693 }
2694 m_Doc->loadPict(QUrl::fromPercentEncoding(fileName), item);
2695 item->setImageXYScale(scXi / item->pixm.imgInfo.xres * 72, scYi / item->pixm.imgInfo.xres * 72);
2696 item->setImageXYOffset(-imageDX * scXi / item->imageXScale(), -imageDY * scXi / item->imageYScale());
2697 item->setImageRotation(-roti);
2698 if (imageFit != "None")
2699 item->adjustPictScale();
2700 }
2701 }
2702 GElements.append(m_Doc->Items->takeAt(z));
2703 }
2704 }
2705 else
2706 {
2707 if (GElements.count() > 0)
2708 {
2709 double minx = std::numeric_limits<double>::max();
2710 double miny = std::numeric_limits<double>::max();
2711 double maxx = -std::numeric_limits<double>::max();
2712 double maxy = -std::numeric_limits<double>::max();
2713 for (int ep = 0; ep < GElements.count(); ++ep)
2714 {
2715 PageItem* currItem = GElements.at(ep);
2716 double x1, x2, y1, y2;
2717 currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
2718 minx = qMin(minx, x1);
2719 miny = qMin(miny, y1);
2720 maxx = qMax(maxx, x2);
2721 maxy = qMax(maxy, y2);
2722 }
2723 double gx = minx;
2724 double gy = miny;
2725 double gw = maxx - minx;
2726 double gh = maxy - miny;
2727 int z = m_Doc->itemAdd(PageItem::Group, PageItem::Rectangle, gx, gy, gw, gh, 0, CommonStrings::None, CommonStrings::None);
2728 PageItem *item = m_Doc->Items->at(z);
2729 item->setTextFlowMode(textFlow);
2730 m_Doc->adjustItemSize(item);
2731 item->OldB2 = item->width();
2732 item->OldH2 = item->height();
2733 item->updateClip();
2734 item->setItemName(itemName);
2735 item->setFillTransparency(Opacity);
2736 item->setLineTransparency(Opacity);
2737 item->setLineBlendmode(blendMode);
2738 item->setFillBlendmode(blendMode);
2739 item->setFillEvenOdd(false);
2740 if (importerFlags & LoadSavePlugin::lfCreateDoc)
2741 item->setLayer(layerNum);
2742 item->OwnPage = m_Doc->OnPage(item);
2743 m_Doc->Items->takeAt(z);
2744 m_Doc->groupObjectsToItem(item, GElements);
2745 m_Doc->GroupOnPage(item);
2746 }
2747 }
2748 return GElements;
2749 }
2750
parseStoryXML(const QDomElement & stElem)2751 bool IdmlPlug::parseStoryXML(const QDomElement& stElem)
2752 {
2753 QDomElement stNode;
2754 QDomDocument stMapDom;
2755 if (stElem.hasAttribute("src"))
2756 {
2757 QByteArray f2;
2758 m_zip->read(stElem.attribute("src"), f2);
2759 if (!stMapDom.setContent(f2))
2760 return false;
2761 stNode = stMapDom.documentElement();
2762 }
2763 else
2764 {
2765 if (!stElem.hasChildNodes())
2766 return false;
2767 stNode = stElem;
2768 }
2769 parseStoryXMLNode(stNode);
2770 return true;
2771 }
2772
parseStoryXMLNode(const QDomElement & stNode)2773 void IdmlPlug::parseStoryXMLNode(const QDomElement& stNode)
2774 {
2775 for (QDomNode n = stNode.firstChild(); !n.isNull(); n = n.nextSibling() )
2776 {
2777 QDomElement e = n.toElement();
2778 if (e.tagName() == "Story")
2779 {
2780 QString storyName = e.attribute("Self");
2781 PageItem *item = nullptr;
2782 if (!storyMap.contains(storyName))
2783 return;
2784 item = storyMap[storyName];
2785 for (QDomNode st = e.firstChild(); !st.isNull(); st = st.nextSibling())
2786 {
2787 QDomElement ste = st.toElement();
2788 if (ste.tagName() == "ParagraphStyleRange")
2789 parseParagraphStyleRange(ste, item);
2790 else if (ste.tagName() == "XMLElement")
2791 {
2792 for (QDomNode stx = ste.firstChild(); !stx.isNull(); stx = stx.nextSibling())
2793 {
2794 QDomElement stxe = stx.toElement();
2795 if (stxe.tagName() == "ParagraphStyleRange")
2796 parseParagraphStyleRange(stxe, item);
2797 }
2798 }
2799 }
2800 item->itemText.trim();
2801 }
2802 }
2803 }
2804
parseParagraphStyleRange(QDomElement & ste,PageItem * item)2805 void IdmlPlug::parseParagraphStyleRange(QDomElement &ste, PageItem* item)
2806 {
2807 QString pStyle = CommonStrings::DefaultParagraphStyle;
2808 if (ste.hasAttribute("AppliedParagraphStyle"))
2809 {
2810 pStyle = ste.attribute("AppliedParagraphStyle").remove("$ID/");
2811 if (styleTranslate.contains(pStyle))
2812 pStyle = styleTranslate[pStyle];
2813 else
2814 pStyle = CommonStrings::DefaultParagraphStyle;
2815 }
2816 ParagraphStyle newStyle;
2817 newStyle.setParent(pStyle);
2818 newStyle.setLineSpacingMode(ParagraphStyle::AutomaticLineSpacing);
2819 // Apply possible override of paragraph style
2820 readParagraphStyleAttributes(newStyle, ste);
2821 ParagraphStyle ttx = m_Doc->paragraphStyle(pStyle);
2822 QString fontBase = ttx.charStyle().font().family();
2823 QString fontStyle = ttx.charStyle().font().style();
2824 for (QDomNode stc = ste.firstChild(); !stc.isNull(); stc = stc.nextSibling())
2825 {
2826 QDomElement stt = stc.toElement();
2827 if (stt.tagName() == "CharacterStyleRange")
2828 parseCharacterStyleRange(stt, item, fontBase, fontStyle, newStyle, item->itemText.length());
2829 else if (stt.tagName() == "XMLElement")
2830 {
2831 for (QDomNode stx = stt.firstChild(); !stx.isNull(); stx = stx.nextSibling())
2832 {
2833 QDomElement stxe = stx.toElement();
2834 if (stxe.tagName() == "CharacterStyleRange")
2835 parseCharacterStyleRange(stxe, item, fontBase, fontStyle, newStyle, item->itemText.length());
2836 else if (stxe.tagName() == "XMLElement")
2837 {
2838 for (QDomNode stxx = stxe.firstChild(); !stxx.isNull(); stxx = stxx.nextSibling())
2839 {
2840 QDomElement stxxe = stxx.toElement();
2841 if (stxxe.tagName() == "CharacterStyleRange")
2842 parseCharacterStyleRange(stxxe, item, fontBase, fontStyle, newStyle, item->itemText.length());
2843 }
2844 }
2845 }
2846 }
2847 }
2848 int posT = item->itemText.length();
2849 if (posT > 0)
2850 {
2851 if ((item->itemText.text(posT - 1) != SpecialChars::PARSEP))
2852 item->itemText.insertChars(posT, SpecialChars::PARSEP);
2853 }
2854 item->itemText.applyStyle(posT, newStyle);
2855 }
2856
parseCharacterStyleRange(QDomElement & stt,PageItem * item,QString fontBase,QString fontStyle,ParagraphStyle & newStyle,int posC)2857 void IdmlPlug::parseCharacterStyleRange(QDomElement &stt, PageItem* item, QString fontBase, QString fontStyle, ParagraphStyle &newStyle, int posC)
2858 {
2859 QString data = "";
2860 bool hasChangedFont = false;
2861 for (QDomNode stcp = stt.firstChild(); !stcp.isNull(); stcp = stcp.nextSibling())
2862 {
2863 QDomElement sp = stcp.toElement();
2864 if (sp.tagName() == "Properties")
2865 {
2866 for (QDomNode spa = sp.firstChild(); !spa.isNull(); spa = spa.nextSibling())
2867 {
2868 QDomElement spf = spa.toElement();
2869 if (spf.tagName() == "AppliedFont")
2870 {
2871 fontBase = spf.text();
2872 hasChangedFont = true;
2873 }
2874 }
2875 }
2876 else if (sp.tagName() == "Leading")
2877 {
2878 if (sp.attribute("type") == "unit")
2879 {
2880 int lead = sp.text().toDouble();
2881 if (lead != 0)
2882 {
2883 newStyle.setLineSpacingMode(ParagraphStyle::FixedLineSpacing);
2884 newStyle.setLineSpacing(lead);
2885 }
2886 }
2887 }
2888 }
2889 // Apply possible override of character style
2890 CharStyle nstyle = newStyle.charStyle();
2891 if (stt.hasAttribute("FontStyle"))
2892 {
2893 fontStyle = stt.attribute("FontStyle", "");
2894 hasChangedFont = true;
2895 }
2896 if (stt.hasAttribute("AppliedCharacterStyle"))
2897 {
2898 QString cStyle = stt.attribute("AppliedCharacterStyle").remove("$ID/");
2899 if (cStyle != "CharacterStyle/[No character style]")
2900 {
2901 if (charStyleTranslate.contains(cStyle))
2902 {
2903 QString pst = nstyle.name();
2904 cStyle = charStyleTranslate[cStyle];
2905 nstyle = m_Doc->charStyle(cStyle);
2906 nstyle.setParent(pst);
2907 }
2908 }
2909 }
2910 if (hasChangedFont)
2911 {
2912 if ((!fontBase.isEmpty()) && (!fontStyle.isEmpty()))
2913 {
2914 QString fontName = constructFontName(fontBase, fontStyle);
2915 nstyle.setFont((*m_Doc->AllFonts)[fontName]);
2916 }
2917 }
2918 readCharStyleAttributes(nstyle, stt);
2919 for (QDomNode stch = stt.firstChild(); !stch.isNull(); stch = stch.nextSibling())
2920 {
2921 QDomElement s = stch.toElement();
2922 if (s.tagName() == "Content")
2923 {
2924 QString ch = "";
2925 for (QDomNode sh = s.firstChild(); !sh.isNull(); sh = sh.nextSibling())
2926 {
2927 QString p = sh.nodeValue();
2928 if (sh.nodeName() == "#text")
2929 ch += p;
2930 else if (p == "18")
2931 ch += SpecialChars::PAGENUMBER;
2932 }
2933 if (!ch.isEmpty())
2934 {
2935 for (int tt = 0; tt < ch.length(); ++tt)
2936 {
2937 QChar c = ch.at(tt);
2938 if (c.unicode() == 0x2028)
2939 ch[tt] = SpecialChars::LINEBREAK;
2940 if (c.unicode() == 0x202F)
2941 ch[tt] = SpecialChars::NBSPACE;
2942 }
2943 data += ch;
2944 }
2945 else
2946 data += " ";
2947 }
2948 else if (s.tagName() == "Br")
2949 {
2950 data += SpecialChars::PARSEP;
2951 item->itemText.insertChars(posC, data);
2952 item->itemText.applyStyle(posC, newStyle);
2953 item->itemText.applyCharStyle(posC, data.length(), nstyle);
2954 data = "";
2955 posC = item->itemText.length();
2956 }
2957 else if ((s.tagName() == "Rectangle") || (s.tagName() == "Oval") || (s.tagName() == "GraphicLine") || (s.tagName() == "Polygon") || (s.tagName() == "TextFrame") || (s.tagName() == "Group") || (s.tagName() == "Button"))
2958 {
2959 QTransform m;
2960 QList<PageItem*> el = parseItemXML(s, m);
2961 for (int ec = 0; ec < el.count(); ++ec)
2962 {
2963 PageItem* currItem = el.at(ec);
2964 currItem->isEmbedded = true;
2965 currItem->gXpos = 0;
2966 currItem->gYpos = 0;
2967 currItem->gWidth = currItem->width();
2968 currItem->gHeight = currItem->height();
2969 int fIndex = m_Doc->addToInlineFrames(currItem);
2970 item->itemText.insertObject(fIndex);
2971 item->itemText.applyStyle(posC, newStyle);
2972 data = "";
2973 posC = item->itemText.length();
2974 }
2975 }
2976 else if (s.tagName() == "Table")
2977 {
2978 QList<double> rowHeights;
2979 QList<double> colWidths;
2980 double twidth = 0.0;
2981 double theight = 0.0;
2982 for (QDomNode st = s.firstChild(); !st.isNull(); st = st.nextSibling())
2983 {
2984 QDomElement sr = st.toElement();
2985 if (sr.tagName() == "Row")
2986 {
2987 theight += sr.attribute("SingleRowHeight", "0").toDouble();
2988 rowHeights.append(sr.attribute("SingleRowHeight", "0").toDouble());
2989 }
2990 if (sr.tagName() == "Column")
2991 {
2992 twidth += sr.attribute("SingleColumnWidth", "0").toDouble();
2993 colWidths.append(sr.attribute("SingleColumnWidth", "0").toDouble());
2994 }
2995 }
2996 m_Doc->dontResize = true;
2997 int z = m_Doc->itemAdd(PageItem::Table, PageItem::Unspecified, 0, 0, qMin(item->width() - 2, twidth), qMin(item->height() - 2, theight), 0.0, CommonStrings::None, CommonStrings::None);
2998 PageItem_Table* currItem = m_Doc->Items->takeAt(z)->asTable();
2999 currItem->insertRows(0, rowHeights.count()-1);
3000 m_Doc->dontResize = true;
3001 currItem->insertColumns(0, colWidths.count()-1);
3002 m_Doc->dontResize = true;
3003 for (int i = 0; i < rowHeights.count(); i++)
3004 {
3005 currItem->resizeRow(i, rowHeights[i]);
3006 }
3007 m_Doc->dontResize = true;
3008 for (int i = 0; i < colWidths.count(); i++)
3009 {
3010 currItem->resizeColumn(i, colWidths[i]);
3011 }
3012 m_Doc->dontResize = true;
3013 for (QDomNode st = s.firstChild(); !st.isNull(); st = st.nextSibling())
3014 {
3015 QDomElement sr = st.toElement();
3016 if (sr.tagName() == "Cell")
3017 {
3018 QStringList pos = sr.attribute("Name", "0:0").split(":");
3019 PageItem* itText = currItem->cellAt(pos[1].toInt(), pos[0].toInt()).textFrame();
3020 if (itText)
3021 {
3022 m_Doc->dontResize = true;
3023 for (QDomNode sct = sr.firstChild(); !sct.isNull(); sct = sct.nextSibling())
3024 {
3025 QDomElement spf = sct.toElement();
3026 if (spf.tagName() == "XMLElement")
3027 {
3028 for (QDomNode sctx = spf.firstChild(); !sctx.isNull(); sctx = sctx.nextSibling())
3029 {
3030 QDomElement spfx = sctx.toElement();
3031 if (spfx.tagName() == "ParagraphStyleRange")
3032 parseParagraphStyleRange(spfx, itText);
3033 }
3034 }
3035 else if (spf.tagName() == "ParagraphStyleRange")
3036 parseParagraphStyleRange(spf, itText);
3037 }
3038 }
3039 }
3040 }
3041 m_Doc->dontResize = true;
3042 currItem->adjustTableToFrame();
3043 currItem->adjustFrameToTable();
3044 currItem->isEmbedded = true;
3045 currItem->gXpos = 0;
3046 currItem->gYpos = 0;
3047 currItem->gWidth = currItem->width();
3048 currItem->gHeight = currItem->height();
3049 m_Doc->dontResize = false;
3050 int fIndex = m_Doc->addToInlineFrames(currItem);
3051 item->itemText.insertObject(fIndex);
3052 item->itemText.applyStyle(posC, newStyle);
3053 data = "";
3054 posC = item->itemText.length();
3055 }
3056 else if (s.tagName() == "XMLElement")
3057 {
3058 // for (QDomNode stx = s.firstChild(); !stx.isNull(); stx = stx.nextSibling())
3059 // {
3060 parseCharacterStyleRange(s, item, fontBase, fontStyle, newStyle, posC);
3061 // }
3062 }
3063 }
3064 if (data.count() > 0)
3065 {
3066 item->itemText.insertChars(posC, data);
3067 item->itemText.applyStyle(posC, newStyle);
3068 item->itemText.applyCharStyle(posC, data.length(), nstyle);
3069 posC = item->itemText.length();
3070 }
3071 }
3072
readCharStyleAttributes(CharStyle & newStyle,const QDomElement & styleElem)3073 void IdmlPlug::readCharStyleAttributes(CharStyle &newStyle, const QDomElement &styleElem)
3074 {
3075 if (styleElem.hasAttribute("BaselineShift"))
3076 newStyle.setBaselineOffset(qRound((styleElem.attribute("BaselineShift","0").toDouble()) * 10));
3077 if (styleElem.hasAttribute("UnderlineOffset"))
3078 {
3079 double offs = styleElem.attribute("UnderlineOffset","0").toDouble();
3080 if (offs >= 0)
3081 newStyle.setUnderlineOffset(qRound(offs * 10));
3082 else
3083 newStyle.setUnderlineOffset(-1);
3084 }
3085 if (styleElem.hasAttribute("UnderlineWidth"))
3086 {
3087 double offs = styleElem.attribute("UnderlineWidth","0").toDouble();
3088 if (offs >= 0)
3089 newStyle.setUnderlineWidth(qRound(offs * 10));
3090 else
3091 newStyle.setUnderlineWidth(-1);
3092 }
3093 if (styleElem.hasAttribute("StrikeThroughOffset"))
3094 {
3095 double offs = styleElem.attribute("StrikeThroughOffset","0").toDouble();
3096 if (offs >= 0)
3097 newStyle.setStrikethruOffset(qRound(offs * 10));
3098 else
3099 newStyle.setStrikethruOffset(-1);
3100 }
3101 if (styleElem.hasAttribute("StrikeThroughWidth"))
3102 {
3103 double offs = styleElem.attribute("StrikeThroughWidth","0").toDouble();
3104 if (offs >= 0)
3105 newStyle.setStrikethruWidth(qRound(offs * 10));
3106 else
3107 newStyle.setStrikethruWidth(-1);
3108 }
3109 if (styleElem.hasAttribute("PointSize"))
3110 {
3111 int pointSize = qRound(styleElem.attribute("PointSize", "12").toDouble() * 10);
3112 if (pointSize > 0)
3113 newStyle.setFontSize(pointSize);
3114 }
3115 if (styleElem.hasAttribute("FillColor"))
3116 {
3117 QString fillColor = styleElem.attribute("FillColor");
3118 if (colorTranslate.contains(fillColor))
3119 newStyle.setFillColor(colorTranslate[fillColor]);
3120 }
3121 if (styleElem.hasAttribute("FillTint"))
3122 {
3123 int fillTint = styleElem.attribute("FillTint", "100").toInt();
3124 if (fillTint != -1)
3125 newStyle.setFillShade(fillTint);
3126 }
3127 StyleFlag styleEffects = newStyle.effects();
3128 if (styleElem.attribute("Underline") == "true")
3129 styleEffects |= ScStyle_Underline;
3130 if (styleElem.attribute("StrikeThru") == "true")
3131 styleEffects |= ScStyle_Strikethrough;
3132 if (styleElem.hasAttribute("Capitalization"))
3133 {
3134 QString ca = styleElem.attribute("Capitalization");
3135 if (ca == "AllCaps")
3136 styleEffects |= ScStyle_AllCaps;
3137 else if (ca == "SmallCaps")
3138 styleEffects |= ScStyle_SmallCaps;
3139 }
3140 if (styleElem.hasAttribute("Position"))
3141 {
3142 QString pa = styleElem.attribute("Position");
3143 if ((pa == "Superscript") || (pa == "OTSuperscript"))
3144 styleEffects |= ScStyle_Superscript;
3145 else if ((pa == "Subscript") || (pa == "OTSubscript"))
3146 styleEffects |= ScStyle_Subscript;
3147 }
3148 newStyle.setFeatures(styleEffects.featureList());
3149 }
3150
readParagraphStyleAttributes(ParagraphStyle & newStyle,const QDomElement & styleElem)3151 void IdmlPlug::readParagraphStyleAttributes(ParagraphStyle &newStyle, const QDomElement &styleElem)
3152 {
3153 if (styleElem.hasAttribute("LeftIndent"))
3154 newStyle.setLeftMargin(styleElem.attribute("LeftIndent", "0").toDouble());
3155 if (styleElem.hasAttribute("FirstLineIndent"))
3156 newStyle.setFirstIndent(styleElem.attribute("FirstLineIndent", "0").toDouble());
3157 if (styleElem.hasAttribute("RightIndent"))
3158 newStyle.setRightMargin(styleElem.attribute("RightIndent", "0").toDouble());
3159 if (styleElem.hasAttribute("SpaceBefore"))
3160 newStyle.setGapBefore(styleElem.attribute("SpaceBefore", "0").toDouble());
3161 if (styleElem.hasAttribute("SpaceAfter"))
3162 newStyle.setGapAfter(styleElem.attribute("SpaceAfter", "0").toDouble());
3163 if (styleElem.hasAttribute("DropCapCharacters"))
3164 {
3165 newStyle.setHasDropCap(styleElem.attribute("DropCapCharacters", "0").toInt() != 0);
3166 if (styleElem.hasAttribute("DropCapLines"))
3167 newStyle.setDropCapLines(styleElem.attribute("DropCapLines", "2").toInt());
3168 }
3169 if (styleElem.hasAttribute("Justification"))
3170 {
3171 QString align = styleElem.attribute("Justification", "LeftAlign");
3172 if (align == "LeftAlign")
3173 newStyle.setAlignment(ParagraphStyle::LeftAligned);
3174 else if (align == "CenterAlign")
3175 newStyle.setAlignment(ParagraphStyle::Centered);
3176 else if (align == "RightAlign")
3177 newStyle.setAlignment(ParagraphStyle::RightAligned);
3178 else if ((align == "LeftJustified") || (align == "CenterJustified") || (align == "RightJustified"))
3179 newStyle.setAlignment(ParagraphStyle::Justified);
3180 else if (align == "FullyJustified")
3181 newStyle.setAlignment(ParagraphStyle::Extended);
3182 }
3183 /*
3184 if (styleElem.hasAttribute("MinimumGlyphScaling"))
3185 newStyle.setMinGlyphExtension(styleElem.attribute("MinimumGlyphScaling", "100").toDouble());
3186 if (styleElem.hasAttribute("MaximumGlyphScaling"))
3187 newStyle.setMaxGlyphExtension(styleElem.attribute("MaximumGlyphScaling", "100").toDouble());
3188 if (styleElem.hasAttribute("MinimumWordSpacing"))
3189 newStyle.setMinWordTracking(styleElem.attribute("MinimumWordSpacing", "100").toDouble());
3190 if (styleElem.hasAttribute("DesiredWordSpacing"))
3191 newStyle.charStyle().setWordTracking(styleElem.attribute("DesiredWordSpacing", "100").toDouble());
3192 */
3193 }
3194
convertBlendMode(const QString & blendName)3195 int IdmlPlug::convertBlendMode(const QString& blendName)
3196 {
3197 int mode = 0;
3198 if (blendName == "Normal")
3199 mode = 0;
3200 else if (blendName == "Darken")
3201 mode = 1;
3202 else if (blendName == "Lighten")
3203 mode = 2;
3204 else if (blendName == "Multiply")
3205 mode = 3;
3206 else if (blendName == "Screen")
3207 mode = 4;
3208 else if (blendName == "Overlay")
3209 mode = 5;
3210 else if (blendName == "HardLight")
3211 mode = 6;
3212 else if (blendName == "SoftLight")
3213 mode = 7;
3214 else if (blendName == "Difference")
3215 mode = 8;
3216 else if (blendName == "Exclusion")
3217 mode = 9;
3218 else if (blendName == "ColorDodge")
3219 mode = 10;
3220 else if (blendName == "ColorBurn")
3221 mode = 11;
3222 else if (blendName == "Hue")
3223 mode = 12;
3224 else if (blendName == "Saturation")
3225 mode = 13;
3226 else if (blendName == "Color")
3227 mode = 14;
3228 else if (blendName == "Luminosity")
3229 mode = 15;
3230 return mode;
3231 }
3232
resolveObjectStyle(ObjectStyle & nstyle,const QString & baseStyleName)3233 void IdmlPlug::resolveObjectStyle(ObjectStyle &nstyle, const QString& baseStyleName)
3234 {
3235 QStringList styles;
3236 styles.prepend(baseStyleName);
3237 ObjectStyle style = ObjectStyles[baseStyleName];
3238 while (!style.parentStyle.isEmpty())
3239 {
3240 styles.prepend(style.parentStyle);
3241 style = ObjectStyles[style.parentStyle];
3242 }
3243 for (int a = 0; a < styles.count(); ++a)
3244 {
3245 style = ObjectStyles[styles[a]];
3246 if (style.fillColor != def_fillColor)
3247 nstyle.fillColor = style.fillColor;
3248 if (style.strokeColor != def_strokeColor)
3249 nstyle.strokeColor = style.strokeColor;
3250 if (style.fillGradient != "")
3251 nstyle.fillGradient = style.fillGradient;
3252 if (style.gradientFillStart != QPointF(def_gradientX, def_gradientY))
3253 nstyle.gradientFillStart = style.gradientFillStart;
3254 if (style.gradientFillLength != def_gradientLen)
3255 nstyle.gradientFillLength = style.gradientFillLength;
3256 if (style.gradientFillAngle != def_gradientAngle)
3257 nstyle.gradientFillAngle = style.gradientFillAngle;
3258 if (style.strokeGradient != "")
3259 nstyle.strokeGradient = style.strokeGradient;
3260 if (style.gradientStrokeStart != QPointF(def_gradientStrokeStartX, def_gradientStrokeStartY))
3261 nstyle.gradientStrokeStart = style.gradientStrokeStart;
3262 if (style.gradientStrokeLength != def_gradientStrokeLength)
3263 nstyle.gradientStrokeLength = style.gradientStrokeLength;
3264 if (style.gradientStrokeAngle != def_gradientStrokeAngle)
3265 nstyle.gradientStrokeAngle = style.gradientStrokeAngle;
3266 if (style.lineWidth != def_lineWidth)
3267 nstyle.lineWidth = style.lineWidth;
3268 if (style.fillTint != def_fillTint)
3269 nstyle.fillTint = style.fillTint;
3270 if (style.strokeTint != def_strokeTint)
3271 nstyle.strokeTint = style.strokeTint;
3272 if (style.Opacity != def_Opacity)
3273 nstyle.Opacity = style.Opacity;
3274 if (style.blendMode != def_Blendmode)
3275 nstyle.blendMode = style.blendMode;
3276 if (style.Extra != def_Extra)
3277 nstyle.Extra = style.Extra;
3278 if (style.TExtra != def_TExtra)
3279 nstyle.TExtra = style.TExtra;
3280 if (style.BExtra != def_BExtra)
3281 nstyle.BExtra = style.BExtra;
3282 if (style.RExtra != def_RExtra)
3283 nstyle.RExtra = style.RExtra;
3284 if (style.TextColumnCount != def_TextColumnCount)
3285 nstyle.TextColumnCount = style.TextColumnCount;
3286 if (style.TextColumnGutter != def_TextColumnGutter)
3287 nstyle.TextColumnGutter = style.TextColumnGutter;
3288 if (style.TextColumnFixedWidth != def_TextColumnFixedWidth)
3289 nstyle.TextColumnFixedWidth = style.TextColumnFixedWidth;
3290 if (style.TextFlow != def_TextFlow)
3291 nstyle.TextFlow = style.TextFlow;
3292 if (style.LeftLineEnd != def_LeftLineEnd)
3293 nstyle.LeftLineEnd = style.LeftLineEnd;
3294 if (style.RightLineEnd != def_RightLineEnd)
3295 nstyle.RightLineEnd = style.RightLineEnd;
3296 }
3297 }
3298
constructFontName(const QString & fontBaseName,const QString & fontStyle)3299 QString IdmlPlug::constructFontName(const QString& fontBaseName, const QString& fontStyle)
3300 {
3301 QString fontName = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
3302 if (fontTranslateMap.contains(fontBaseName))
3303 {
3304 QMap<QString, QString> styleMap = fontTranslateMap[fontBaseName];
3305 if (styleMap.contains(fontStyle))
3306 {
3307 QString postName = styleMap[fontStyle];
3308 bool found = false;
3309 SCFontsIterator it(PrefsManager::instance().appPrefs.fontPrefs.AvailFonts);
3310 for ( ; it.hasNext(); it.next())
3311 {
3312 if (it.current().psName() == postName)
3313 {
3314 fontName = it.current().scName();
3315 found = true;
3316 break;
3317 }
3318 }
3319 if (!found)
3320 {
3321 if (importerFlags & LoadSavePlugin::lfCreateThumbnail)
3322 fontName = PrefsManager::instance().appPrefs.itemToolPrefs.textFont;
3323 else
3324 {
3325 QString family = fontBaseName + " " + fontStyle;
3326 family = family.remove("$ID/");
3327 if (!PrefsManager::instance().appPrefs.fontPrefs.GFontSub.contains(family))
3328 {
3329 qApp->changeOverrideCursor(QCursor(Qt::ArrowCursor));
3330 MissingFont *dia = new MissingFont(nullptr, family, m_Doc);
3331 dia->exec();
3332 fontName = dia->getReplacementFont();
3333 delete dia;
3334 qApp->changeOverrideCursor(QCursor(Qt::WaitCursor));
3335 PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family] = fontName;
3336 }
3337 else
3338 fontName = PrefsManager::instance().appPrefs.fontPrefs.GFontSub[family];
3339 }
3340 }
3341 }
3342 }
3343 return fontName;
3344 }
3345