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