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 #include "scribus150format.h"
8 #include "scribus150formatimpl.h"
9 
10 #include <algorithm>
11 
12 #include <QApplication>
13 #include <QByteArray>
14 #include <QCursor>
15 // #include <QDebug>
16 #include <QDir>
17 #include <QFileInfo>
18 #include <QList>
19 #include <QScopedPointer>
20 
21 #include "../../formatidlist.h"
22 #include "commonstrings.h"
23 #include "hyphenator.h"
24 #include "langmgr.h"
25 #include "notesstyles.h"
26 #include "pageitem_arc.h"
27 #include "pageitem_latexframe.h"
28 #include "pageitem_noteframe.h"
29 #ifdef HAVE_OSG
30 	#include "pageitem_osgframe.h"
31 #endif
32 #include "pageitem_regularpolygon.h"
33 #include "pageitem_spiral.h"
34 #include "pageitem_table.h"
35 #include "pagestructs.h"
36 #include "pageitem_line.h"
37 #include "pagesize.h"
38 #include "prefsmanager.h"
39 #include "qtiocompressor.h"
40 #include "scclocale.h"
41 #include "scconfig.h"
42 #include "sccolorengine.h"
43 #include "scpattern.h"
44 #include "scribuscore.h"
45 #include "scribusdoc.h"
46 #include "sctextstream.h"
47 #include "scxmlstreamreader.h"
48 #include "undomanager.h"
49 #include "ui/missing.h"
50 #include "units.h"
51 #include "util.h"
52 #include "util_color.h"
53 #include "util_math.h"
54 #include "util_printer.h"
55 #include "util_text.h"
56 
57 // See scplugin.h and pluginmanager.{cpp,h} for detail on what these methods
58 // do. That documentatation is not duplicated here.
59 // Please don't implement the functionality of your plugin here; do that
60 // in scribus150formatimpl.h and scribus150formatimpl.cpp .
61 
Scribus150Format()62 Scribus150Format::Scribus150Format()
63 {
64 	// Set action info in languageChange, so we only have to do
65 	// it in one place. This includes registering file formats.
66 	registerFormats();
67 	languageChange();
68 }
69 
~Scribus150Format()70 Scribus150Format::~Scribus150Format()
71 {
72 	unregisterAll();
73 }
74 
languageChange()75 void Scribus150Format::languageChange()
76 {
77 	FileFormat* fmt = getFormatByID(FORMATID_SLA150IMPORT);
78 	fmt->trName = tr("Scribus 1.5.0+ Document");
79 	fmt->filter = fmt->trName + " (*.sla *.SLA *.sla.gz *.SLA.GZ *.scd *.SCD *.scd.gz *.SCD.GZ)";
80 }
81 
fullTrName() const82 QString Scribus150Format::fullTrName() const
83 {
84 	return QObject::tr("Scribus 1.5.0+ Support");
85 }
86 
getAboutData() const87 const ScActionPlugin::AboutData* Scribus150Format::getAboutData() const
88 {
89 	AboutData* about = new AboutData;
90 	Q_CHECK_PTR(about);
91 	about->authors = QString::fromUtf8(
92 			"Franz Schmid <franz@scribus.info>, "
93 			"The Scribus Team");
94 	about->shortDescription = tr("Scribus 1.5.0+ File Format Support");
95 	about->description = tr("Allows Scribus to read Scribus 1.5.0 and higher formatted files.");
96 	// about->version
97 	// about->releaseDate
98 	// about->copyright
99 	about->license = "GPL";
100 	return about;
101 }
102 
deleteAboutData(const AboutData * about) const103 void Scribus150Format::deleteAboutData(const AboutData* about) const
104 {
105 	Q_ASSERT(about);
106 	delete about;
107 }
108 
registerFormats()109 void Scribus150Format::registerFormats()
110 {
111 	FileFormat fmt(this);
112 	fmt.trName = tr("Scribus 1.5.0+ Document");
113 	fmt.formatId = FORMATID_SLA150IMPORT;
114 	fmt.load = true;
115 	fmt.save = true;
116 	fmt.colorReading = true;
117 	fmt.filter = fmt.trName + " (*.sla *.SLA *.sla.gz *.SLA.GZ *.scd *.SCD *.scd.gz *.SCD.GZ)";
118 	fmt.mimeTypes = QStringList();
119 	fmt.mimeTypes.append("application/x-scribus");
120 	fmt.fileExtensions = QStringList() << "sla" << "sla.gz" << "scd" << "scd.gz";
121 	fmt.priority = 64;
122 	fmt.nativeScribus = true;
123 	registerFormat(fmt);
124 }
125 
fileSupported(QIODevice *,const QString & fileName) const126 bool Scribus150Format::fileSupported(QIODevice* /* file */, const QString & fileName) const
127 {
128 	QByteArray docBytes("");
129 	if (fileName.right(2) == "gz")
130 	{
131 		QFile file(fileName);
132 		QtIOCompressor compressor(&file);
133 		compressor.setStreamFormat(QtIOCompressor::GzipFormat);
134 		compressor.open(QIODevice::ReadOnly);
135 		docBytes = compressor.read(1024);
136 		compressor.close();
137 		if (docBytes.isEmpty())
138 			return false;
139 	}
140 	else
141 	{
142 		// Not gzip encoded, just load it
143 		loadRawBytes(fileName, docBytes, 1024);
144 	}
145 
146 	QRegExp regExp150("Version=\"1.5.[0-9]");
147 	int startElemPos = docBytes.left(512).indexOf("<SCRIBUSUTF8NEW ");
148 	if (startElemPos >= 0)
149 	{
150 		bool is150 = (regExp150.indexIn(docBytes.mid(startElemPos, 64)) >= 0);
151 		return is150;
152 	}
153 	return false;
154 }
155 
paletteSupported(QIODevice *,const QString & fileName) const156 bool Scribus150Format::paletteSupported(QIODevice* /* file */, const QString & fileName) const
157 {
158 	QByteArray docBytes("");
159 	if (fileName.right(2) == "gz")
160 	{
161 		QFile file(fileName);
162 		QtIOCompressor compressor(&file);
163 		compressor.setStreamFormat(QtIOCompressor::GzipFormat);
164 		compressor.open(QIODevice::ReadOnly);
165 		docBytes = compressor.read(1024);
166 		compressor.close();
167 		if (docBytes.isEmpty())
168 			return false;
169 	}
170 	else
171 	{
172 		// Not gzip encoded, just load it
173 		loadRawBytes(fileName, docBytes, 1024);
174 	}
175 
176 	int startElemPos = docBytes.indexOf("<SCRIBUSCOLORS");
177 	return (startElemPos >= 0);
178 }
179 
storySupported(const QByteArray & storyData) const180 bool Scribus150Format::storySupported(const QByteArray& storyData) const
181 {
182 	QRegExp regExp150("Version=\"1.5.[0-9]");
183 	int startElemPos = storyData.left(512).indexOf("<ScribusStory ");
184 	if (startElemPos >= 0)
185 	{
186 		bool is150 = (regExp150.indexIn(storyData.mid(startElemPos, 64)) >= 0);
187 		return is150;
188 	}
189 	return false;
190 }
191 
slaReader(const QString & fileName)192 QIODevice* Scribus150Format::slaReader(const QString & fileName)
193 {
194 	if (!fileSupported(nullptr, fileName))
195 		return nullptr;
196 
197 	QIODevice* ioDevice = nullptr;
198 	if (fileName.right(2) == "gz")
199 	{
200 		aFile.setFileName(fileName);
201 		QtIOCompressor *compressor = new QtIOCompressor(&aFile);
202 		compressor->setStreamFormat(QtIOCompressor::GzipFormat);
203 		if (!compressor->open(QIODevice::ReadOnly))
204 		{
205 			delete compressor;
206 			return nullptr;
207 		}
208 		ioDevice = compressor;
209 	}
210 	else
211 	{
212 		ioDevice = new QFile(fileName);
213 		if (!ioDevice->open(QIODevice::ReadOnly))
214 		{
215 			delete ioDevice;
216 			return nullptr;
217 		}
218 	}
219 	return ioDevice;
220 }
221 
paletteReader(const QString & fileName)222 QIODevice* Scribus150Format::paletteReader(const QString & fileName)
223 {
224 	if (!paletteSupported(nullptr, fileName))
225 		return nullptr;
226 
227 	QIODevice* ioDevice = nullptr;
228 	if (fileName.right(2) == "gz")
229 	{
230 		aFile.setFileName(fileName);
231 		QtIOCompressor *compressor = new QtIOCompressor(&aFile);
232 		compressor->setStreamFormat(QtIOCompressor::GzipFormat);
233 		if (!compressor->open(QIODevice::ReadOnly))
234 		{
235 			delete compressor;
236 			return nullptr;
237 		}
238 		ioDevice = compressor;
239 	}
240 	else
241 	{
242 		ioDevice = new QFile(fileName);
243 		if (!ioDevice->open(QIODevice::ReadOnly))
244 		{
245 			delete ioDevice;
246 			return nullptr;
247 		}
248 	}
249 	return ioDevice;
250 }
251 
getReplacedFontData(bool & getNewReplacement,QMap<QString,QString> & getReplacedFonts,QList<ScFace> & getDummyScFaces)252 void Scribus150Format::getReplacedFontData(bool & getNewReplacement, QMap<QString,QString> &getReplacedFonts, QList<ScFace> &getDummyScFaces)
253 {
254 	getNewReplacement = false;
255 	getReplacedFonts.clear();
256 }
257 
loadElements(const QString & data,const QString & fileDir,int toLayer,double Xp_in,double Yp_in,bool loc)258 bool Scribus150Format::loadElements(const QString& data, const QString& fileDir, int toLayer, double Xp_in, double Yp_in, bool loc)
259 {
260 	isNewFormat = false;
261 	LayerToPaste = toLayer;
262 	Xp = Xp_in;
263 	Yp = Yp_in;
264 	GrX = 0.0;
265 	GrY = 0.0;
266 
267 	QList<PageItem*> TableItems;
268 	QList<PageItem*> TableItemsF;
269 	QList<PageItem*> TableItemsM;
270 	QList<PageItem*> WeldItems;
271 	QMap<int, PageItem*> TableID;
272 	QMap<int, PageItem*> TableIDF;
273 	QMap<int, PageItem*> TableIDM;
274 	QMap<int, PageItem*> WeldID;
275 	QStack< QList<PageItem*> > groupStackFI;
276 	QStack< QList<PageItem*> > groupStackMI;
277 	QStack< QList<PageItem*> > groupStackPI;
278 	QStack< QList<PageItem*> > groupStackF;
279 	QStack< QList<PageItem*> > groupStackM;
280 	QStack< QList<PageItem*> > groupStackP;
281 	QStack<int> groupStackFI2;
282 	QStack<int> groupStackMI2;
283 	QStack<int> groupStackPI2;
284 
285 	parStyleMap.clear();
286 	charStyleMap.clear();
287 	itemRemap.clear();
288 	itemNext.clear();
289 	itemCount = 0;
290 	itemRemapM.clear();
291 	itemNextM.clear();
292 	itemCountM = 0;
293 	itemRemapF.clear();
294 	itemNextF.clear();
295 	FrameItems.clear();
296 	LinkID.clear();
297 
298 	markeredItemsMap.clear();
299 	markeredMarksMap.clear();
300 	nsetRangeItemNamesMap.clear();
301 	notesFramesData.clear();
302 	notesMasterMarks.clear();
303 	notesNSets.clear();
304 
305 	bool firstElement = true;
306 	bool success = true;
307 
308 	ReadObjectParams readObjectParams;
309 	readObjectParams.baseDir = fileDir;
310 	readObjectParams.itemKind = PageItem::StandardItem;
311 	readObjectParams.loadingPage = true;
312 
313 	ScXmlStreamReader reader(data);
314 	ScXmlStreamAttributes attrs;
315 	while (!reader.atEnd() && !reader.hasError())
316 	{
317 		QXmlStreamReader::TokenType tType = reader.readNext();
318 		if (tType != QXmlStreamReader::StartElement)
319 			continue;
320 		QStringRef tagName = reader.name();
321 		attrs = reader.scAttributes();
322 
323 		if (firstElement)
324 		{
325 			if (tagName == "SCRIBUSELEM" || tagName == "SCRIBUSELEMUTF8")
326 			{
327 				if (!loc)
328 				{
329 					GrX = attrs.valueAsDouble("XP");
330 					GrY = attrs.valueAsDouble("YP");
331 				}
332 			}
333 			else
334 			{
335 				success = false;
336 				break;
337 			}
338 			firstElement = false;
339 		}
340 		// 10/25/2004 pv - None is "reserved" color. cannot be defined in any file...
341 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
342 		{
343 			QString colorName = attrs.valueAsString("NAME");
344 			if (m_Doc->PageColors.contains(colorName))
345 				continue;
346 			readColor(m_Doc->PageColors, attrs);
347 		}
348 		if (tagName == "Gradient")
349 		{
350 			VGradient gra;
351 			QString grName = attrs.valueAsString("Name");
352 			success = readGradient(m_Doc, gra, reader);
353 			if (!success)
354 				break;
355 			gra.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("Ext", VGradient::pad)));
356 			if (!grName.isEmpty() && !m_Doc->docGradients.contains(grName))
357 				m_Doc->docGradients.insert(grName, gra);
358 		}
359 		if (tagName == "STYLE")
360 		{
361 			ParagraphStyle pstyle;
362 			getStyle(pstyle, reader, nullptr, m_Doc, true);
363 		}
364 		if (tagName == "CHARSTYLE")
365 		{
366 			CharStyle cstyle;
367 			getStyle(cstyle, reader, nullptr, m_Doc, true);
368 		}
369 		if (tagName == "TableStyle")
370 		{
371 			TableStyle tstyle;
372 			readTableStyle(m_Doc, reader, tstyle);
373 			// FIXME: import style under new name if existing
374 			// Do not break current doc for now
375 			if (m_Doc->tableStyles().contains(tstyle.name()))
376 				continue;
377 			StyleSet<TableStyle> temp;
378 			temp.create(tstyle);
379 			m_Doc->redefineTableStyles(temp, false);
380 		}
381 		if (tagName == "CellStyle")
382 		{
383 			CellStyle tstyle;
384 			readCellStyle(m_Doc, reader, tstyle);
385 			// FIXME: import style under new name if existing
386 			// Do not break current doc for now
387 			if (m_Doc->cellStyles().contains(tstyle.name()))
388 				continue;
389 			StyleSet<CellStyle> temp;
390 			temp.create(tstyle);
391 			m_Doc->redefineCellStyles(temp, false);
392 		}
393 		if (tagName == "Arrows")
394 		{
395 			success = readArrows(m_Doc, attrs);
396 			if (!success) break;
397 		}
398 		if (tagName == "MultiLine")
399 		{
400 			multiLine ml;
401 			QString mlName = attrs.valueAsString("Name");
402 			success = readMultiline(ml, reader);
403 			if (!success)
404 				break;
405 			if (!mlName.isEmpty() && !m_Doc->docLineStyles.contains(mlName))
406 				m_Doc->docLineStyles.insert(mlName, ml);
407 		}
408 		if ((tagName == "ITEM") || (tagName == "PAGEOBJECT") || (tagName == "FRAMEOBJECT"))
409 		{
410 			ItemInfo itemInfo;
411 			success = readObject(m_Doc, reader, readObjectParams, itemInfo);
412 			if (!success)
413 				break;
414 			itemInfo.item->m_layerID = LayerToPaste;
415 			if (isNewFormat)
416 			{
417 				if (itemInfo.nextItem != -1)
418 					itemNext[itemInfo.itemID] = itemInfo.nextItem;
419 				if (itemInfo.item->isTableItem)
420 					TableItems.append(itemInfo.item);
421 				if (itemInfo.isWeldFlag)
422 					WeldItems.append(itemInfo.item);
423 			}
424 			else
425 			{
426 			// first of linked chain?
427 				if (tagName == "ITEM")
428 				{
429 					if (itemInfo.nextItem != -1)
430 						itemNext[itemInfo.ownNr] = itemInfo.nextItem;
431 				}
432 				if (itemInfo.item->isTableItem)
433 				{
434 					if (tagName == "ITEM")
435 					{
436 						TableItems.append(itemInfo.item);
437 						TableID.insert(itemInfo.ownLink, itemInfo.item);
438 					}
439 				}
440 				if (itemInfo.isWeldFlag)
441 				{
442 					if (tagName == "ITEM")
443 					{
444 						WeldItems.append(itemInfo.item);
445 						WeldID.insert(itemInfo.ownWeld, itemInfo.item);
446 					}
447 				}
448 			}
449 
450 			if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
451 			{
452 				groupStackPI.top().append(itemInfo.item);
453 				while (itemInfo.ownNr == groupStackPI2.top())
454 				{
455 					groupStackP.push(groupStackPI.pop());
456 					groupStackPI2.pop();
457 					if (groupStackPI2.count() == 0)
458 						break;
459 				}
460 			}
461 			else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
462 			{
463 				groupStackFI.top().append(itemInfo.item);
464 				while (itemInfo.ownNr == groupStackFI2.top())
465 				{
466 					groupStackF.push(groupStackFI.pop());
467 					groupStackFI2.pop();
468 					if (groupStackFI2.count() == 0)
469 						break;
470 				}
471 			}
472 			else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
473 			{
474 				groupStackMI.top().append(itemInfo.item);
475 				while (itemInfo.ownNr == groupStackMI2.top())
476 				{
477 					groupStackM.push(groupStackMI.pop());
478 					groupStackMI2.pop();
479 					if (groupStackMI2.count() == 0)
480 						break;
481 				}
482 			}
483 
484 			if (itemInfo.isGroupFlag)
485 			{
486 				QList<PageItem*> groupItems;
487 				groupItems.append(itemInfo.item);
488 				if (tagName == "PAGEOBJECT")
489 				{
490 					groupStackPI.push(groupItems);
491 					groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
492 				}
493 				else if (tagName == "FRAMEOBJECT")
494 				{
495 					groupStackFI.push(groupItems);
496 					groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
497 				}
498 				else
499 				{
500 					groupStackMI.push(groupItems);
501 					groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
502 				}
503 			}
504 		}
505 		if (tagName == "Pattern")
506 		{
507 			success = readPattern(m_Doc, reader, fileDir);
508 			if (!success) break;
509 		}
510 		if (tagName == "NotesStyles")
511 		{
512 			success = readNotesStyles(m_Doc, reader);
513 			if (!success) break;
514 		}
515 		if (tagName == "NotesFrames")
516 		{
517 			success = readNotesFrames(reader);
518 			if (!success) break;
519 		}
520 		if (tagName == "Notes")
521 		{
522 			success = readNotes(m_Doc, reader);
523 			if (!success) break;
524 		}
525 		if (tagName == "Marks")
526 		{
527 			success = readMarks(m_Doc, reader);
528 			if (!success) break;
529 		}
530 	}
531 	if (reader.hasError())
532 	{
533 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
534 		return false;
535 	}
536 	if (isNewFormat)
537 	{
538 		if (TableItems.count() != 0)
539 		{
540 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
541 			{
542 				PageItem* ta = TableItems.at(ttc);
543 				if (ta->TopLinkID != -1)
544 					ta->m_topLink = LinkID[ta->TopLinkID];
545 				else
546 					ta->m_topLink = nullptr;
547 				if (ta->LeftLinkID != -1)
548 					ta->m_leftLink = LinkID[ta->LeftLinkID];
549 				else
550 					ta->m_leftLink = nullptr;
551 				if (ta->RightLinkID != -1)
552 					ta->m_rightLink = LinkID[ta->RightLinkID];
553 				else
554 					ta->m_rightLink = nullptr;
555 				if (ta->BottomLinkID != -1)
556 					ta->m_bottomLink = LinkID[ta->BottomLinkID];
557 				else
558 					ta->m_bottomLink = nullptr;
559 			}
560 		}
561 		if (WeldItems.count() != 0)
562 		{
563 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
564 			{
565 				PageItem* ta = WeldItems.at(ttc);
566 				for (int i = 0; i < ta->weldList.count(); ++i)
567 				{
568 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
569 					ta->weldList[i].weldItem   = LinkID.value(wInf.weldID, 0);
570 					if (ta->weldList[i].weldItem == nullptr)
571 						ta->weldList.removeAt(i--);
572 				}
573 			}
574 		}
575 
576 		//update names to pointers
577 		updateNames2Ptr();
578 
579 		if (itemNext.count() != 0)
580 		{
581 			QMap<int,int>::Iterator lc;
582 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
583 			{
584 				if (lc.value() >= 0)
585 				{
586 					PageItem * Its = LinkID[lc.key()];
587 					PageItem * Itn = LinkID[lc.value()];
588 					if (!Its->canBeLinkedTo(Itn))
589 					{
590 						qDebug() << "scribus150format: corruption in linked textframes detected";
591 						continue;
592 					}
593 					Its->link(Itn);
594 				}
595 			}
596 		}
597 	}
598 	else
599 	{
600 		if (TableItemsF.count() != 0)
601 		{
602 			for (int ttc = 0; ttc < TableItemsF.count(); ++ttc)
603 			{
604 				PageItem* ta = TableItemsF.at(ttc);
605 				if (ta->TopLinkID != -1)
606 					ta->m_topLink = TableIDF[ta->TopLinkID];
607 				else
608 					ta->m_topLink = nullptr;
609 				if (ta->LeftLinkID != -1)
610 					ta->m_leftLink = TableIDF[ta->LeftLinkID];
611 				else
612 					ta->m_leftLink = nullptr;
613 				if (ta->RightLinkID != -1)
614 					ta->m_rightLink = TableIDF[ta->RightLinkID];
615 				else
616 					ta->m_rightLink = nullptr;
617 				if (ta->BottomLinkID != -1)
618 					ta->m_bottomLink = TableIDF[ta->BottomLinkID];
619 				else
620 					ta->m_bottomLink = nullptr;
621 			}
622 		}
623 		if (TableItemsM.count() != 0)
624 		{
625 			for (int ttc = 0; ttc < TableItemsM.count(); ++ttc)
626 			{
627 				PageItem* ta = TableItemsM.at(ttc);
628 				if (ta->TopLinkID != -1)
629 					ta->m_topLink = TableIDM[ta->TopLinkID];
630 				else
631 					ta->m_topLink = nullptr;
632 				if (ta->LeftLinkID != -1)
633 					ta->m_leftLink = TableIDM[ta->LeftLinkID];
634 				else
635 					ta->m_leftLink = nullptr;
636 				if (ta->RightLinkID != -1)
637 					ta->m_rightLink = TableIDM[ta->RightLinkID];
638 				else
639 					ta->m_rightLink = nullptr;
640 				if (ta->BottomLinkID != -1)
641 					ta->m_bottomLink = TableIDM[ta->BottomLinkID];
642 				else
643 					ta->m_bottomLink = nullptr;
644 			}
645 		}
646 		if (TableItems.count() != 0)
647 		{
648 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
649 			{
650 				PageItem* ta = TableItems.at(ttc);
651 				if (ta->TopLinkID != -1)
652 					ta->m_topLink = TableID[ta->TopLinkID];
653 				else
654 					ta->m_topLink = nullptr;
655 				if (ta->LeftLinkID != -1)
656 					ta->m_leftLink = TableID[ta->LeftLinkID];
657 				else
658 					ta->m_leftLink = nullptr;
659 				if (ta->RightLinkID != -1)
660 					ta->m_rightLink = TableID[ta->RightLinkID];
661 				else
662 					ta->m_rightLink = nullptr;
663 				if (ta->BottomLinkID != -1)
664 					ta->m_bottomLink = TableID[ta->BottomLinkID];
665 				else
666 					ta->m_bottomLink = nullptr;
667 			}
668 		}
669 		if (WeldItems.count() != 0)
670 		{
671 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
672 			{
673 				PageItem* ta = WeldItems.at(ttc);
674 				for (int i = 0 ; i < ta->weldList.count(); ++i)
675 				{
676 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
677 					ta->weldList[i].weldItem = WeldID.value(wInf.weldID, 0);
678 					if (ta->weldList[i].weldItem == nullptr)
679 						ta->weldList.removeAt(i--);
680 				}
681 			}
682 		}
683 
684 		//update names to pointers
685 		updateNames2Ptr();
686 
687 		// reestablish textframe links
688 		if (itemNext.count() != 0)
689 		{
690 			QMap<int,int>::Iterator lc;
691 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
692 			{
693 				if (lc.value() >= 0)
694 				{
695 					PageItem *Its(nullptr), *Itn(nullptr);
696 					if (lc.key() < m_Doc->DocItems.count())
697 						Its = m_Doc->DocItems.at(lc.key());
698 					if (lc.value() < m_Doc->DocItems.count())
699 						Itn = m_Doc->DocItems.at(lc.value());
700 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
701 					{
702 						qDebug() << "scribus150format: corruption in linked textframes detected";
703 						continue;
704 					}
705 					Its->link(Itn);
706 				}
707 			}
708 		}
709 	}
710 
711 	while (groupStackP.count() > 0)
712 	{
713 		bool isTableIt = false;
714 		QList<PageItem*> gpL = groupStackP.pop();
715 		PageItem* gItem = gpL.takeFirst();
716 		for (int id = 0; id < gpL.count(); id++)
717 		{
718 			PageItem* cItem = gpL.at(id);
719 			isTableIt = cItem->isTableItem;
720 			cItem->gXpos = cItem->xPos() - gItem->xPos();
721 			cItem->gYpos = cItem->yPos() - gItem->yPos();
722 			cItem->Parent = gItem;
723 			if (gItem->rotation() != 0)
724 			{
725 				QTransform ma;
726 				ma.rotate(-gItem->rotation());
727 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
728 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
729 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
730 				cItem->setRotation(cItem->rotation() - gItem->rotation());
731 				cItem->oldRot = cItem->rotation();
732 			}
733 			m_Doc->DocItems.removeOne(cItem);
734 		}
735 		bool converted = false;
736 		if (isTableIt)
737 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
738 		if (!converted)
739 			gItem->groupItemList = gpL;
740 	}
741 
742 	while (groupStackF.count() > 0)
743 	{
744 		bool isTableIt = false;
745 		QList<PageItem*> gpL = groupStackF.pop();
746 		PageItem* gItem = gpL.takeFirst();
747 		for (int id = 0; id < gpL.count(); id++)
748 		{
749 			PageItem* cItem = gpL.at(id);
750 			isTableIt = cItem->isTableItem;
751 			cItem->gXpos = cItem->xPos() - gItem->xPos();
752 			cItem->gYpos = cItem->yPos() - gItem->yPos();
753 			cItem->Parent = gItem;
754 			if (gItem->rotation() != 0)
755 			{
756 				QTransform ma;
757 				ma.rotate(-gItem->rotation());
758 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
759 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
760 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
761 				cItem->setRotation(cItem->rotation() - gItem->rotation());
762 				cItem->oldRot = cItem->rotation();
763 			}
764 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
765 		}
766 		bool converted = false;
767 		if (isTableIt)
768 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
769 		if (!converted)
770 			gItem->groupItemList = gpL;
771 	}
772 
773 	while (groupStackM.count() > 0)
774 	{
775 		bool isTableIt = false;
776 		QList<PageItem*> gpL = groupStackM.pop();
777 		PageItem* gItem = gpL.takeFirst();
778 		for (int id = 0; id < gpL.count(); id++)
779 		{
780 			PageItem* cItem = gpL.at(id);
781 			isTableIt = cItem->isTableItem;
782 			cItem->gXpos = cItem->xPos() - gItem->xPos();
783 			cItem->gYpos = cItem->yPos() - gItem->yPos();
784 			cItem->Parent = gItem;
785 			if (gItem->rotation() != 0)
786 			{
787 				QTransform ma;
788 				ma.rotate(-gItem->rotation());
789 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
790 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
791 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
792 				cItem->setRotation(cItem->rotation() - gItem->rotation());
793 				cItem->oldRot = cItem->rotation();
794 			}
795 			m_Doc->MasterItems.removeOne(cItem);
796 		}
797 		bool converted = false;
798 		if (isTableIt)
799 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
800 		if (!converted)
801 			gItem->groupItemList = gpL;
802 	}
803 
804 	return true;
805 }
806 
loadStory(const QByteArray & data,StoryText & story,PageItem * item)807 bool Scribus150Format::loadStory(const QByteArray& data, StoryText& story, PageItem* item)
808 {
809 	isNewFormat = false;
810 
811 	parStyleMap.clear();
812 	charStyleMap.clear();
813 	itemRemap.clear();
814 	itemNext.clear();
815 	itemCount = 0;
816 	itemRemapM.clear();
817 	itemNextM.clear();
818 	itemCountM = 0;
819 	itemRemapF.clear();
820 	itemNextF.clear();
821 	FrameItems.clear();
822 	LinkID.clear();
823 
824 	markeredItemsMap.clear();
825 	markeredMarksMap.clear();
826 	nsetRangeItemNamesMap.clear();
827 	notesFramesData.clear();
828 	notesMasterMarks.clear();
829 	notesNSets.clear();
830 
831 	bool firstElement = true;
832 	bool success = true;
833 
834 	ReadObjectParams readObjectParams;
835 	readObjectParams.baseDir = QString() /*fileDir*/; //FIXME
836 	readObjectParams.itemKind = PageItem::InlineItem;
837 	readObjectParams.loadingPage = true;
838 
839 	ScXmlStreamReader reader(data);
840 	ScXmlStreamAttributes attrs;
841 	while (!reader.atEnd() && !reader.hasError())
842 	{
843 		QXmlStreamReader::TokenType tType = reader.readNext();
844 		if (tType != QXmlStreamReader::StartElement)
845 			continue;
846 		QStringRef tagName = reader.name();
847 		attrs = reader.scAttributes();
848 
849 		if (firstElement)
850 		{
851 			if (tagName != "ScribusStory")
852 			{
853 				success = false;
854 				break;
855 			}
856 			firstElement = false;
857 		}
858 
859 		// 10/25/2004 pv - None is "reserved" color. cannot be defined in any file...
860 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
861 		{
862 			QString colorName = attrs.valueAsString("NAME");
863 			if (m_Doc->PageColors.contains(colorName))
864 				continue;
865 			readColor(m_Doc->PageColors, attrs);
866 		}
867 		if (tagName == "Gradient")
868 		{
869 			VGradient gra;
870 			QString grName = attrs.valueAsString("Name");
871 			success = readGradient(m_Doc, gra, reader);
872 			if (!success)
873 				break;
874 			gra.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("Ext", VGradient::pad)));
875 			if (!grName.isEmpty() && !m_Doc->docGradients.contains(grName))
876 				m_Doc->docGradients.insert(grName, gra);
877 		}
878 		if (tagName == "STYLE")
879 		{
880 			ParagraphStyle pstyle;
881 			readParagraphStyle(m_Doc, reader, pstyle);
882 			// FIXME: import style under new name if existing
883 			// Do not break current doc for now
884 			if (m_Doc->paragraphStyles().contains(pstyle.name()))
885 				continue;
886 			StyleSet<ParagraphStyle> tmp;
887 			tmp.create(pstyle);
888 			m_Doc->redefineStyles(tmp, false);
889 		}
890 		if (tagName == "CHARSTYLE")
891 		{
892 			CharStyle cstyle;
893 			ScXmlStreamAttributes attrs = reader.scAttributes();
894 			readNamedCharacterStyleAttrs(m_Doc, attrs, cstyle);
895 			// FIXME: import style under new name if existing
896 			// Do not break current doc for now
897 			if (m_Doc->charStyles().contains(cstyle.name()))
898 				continue;
899 			StyleSet<CharStyle> temp;
900 			temp.create(cstyle);
901 			m_Doc->redefineCharStyles(temp, false);
902 		}
903 		if (tagName == "TableStyle")
904 		{
905 			TableStyle tstyle;
906 			readTableStyle(m_Doc, reader, tstyle);
907 			// FIXME: import style under new name if existing
908 			// Do not break current doc for now
909 			if (m_Doc->tableStyles().contains(tstyle.name()))
910 				continue;
911 			StyleSet<TableStyle> temp;
912 			temp.create(tstyle);
913 			m_Doc->redefineTableStyles(temp, false);
914 		}
915 		if (tagName == "CellStyle")
916 		{
917 			CellStyle tstyle;
918 			readCellStyle(m_Doc, reader, tstyle);
919 			// FIXME: import style under new name if existing
920 			// Do not break current doc for now
921 			if (m_Doc->cellStyles().contains(tstyle.name()))
922 				continue;
923 			StyleSet<CellStyle> temp;
924 			temp.create(tstyle);
925 			m_Doc->redefineCellStyles(temp, false);
926 		}
927 		if (tagName == "Arrows")
928 		{
929 			success = readArrows(m_Doc, attrs);
930 			if (!success) break;
931 		}
932 		if (tagName == "MultiLine")
933 		{
934 			multiLine ml;
935 			QString mlName = attrs.valueAsString("Name");
936 			success = readMultiline(ml, reader);
937 			if (!success)
938 				break;
939 			if (!mlName.isEmpty() && !m_Doc->docLineStyles.contains(mlName))
940 				m_Doc->docLineStyles.insert(mlName, ml);
941 		}
942 		if (tagName == "FRAMEOBJECT")
943 		{
944 			ItemInfo itemInfo;
945 			success = readObject(m_Doc, reader, readObjectParams, itemInfo);
946 			if (!success)
947 				break;
948 			itemInfo.item->m_layerID = LayerToPaste;
949 		}
950 		if (tagName == "StoryText")
951 		{
952 			readStoryText(m_Doc, reader, story, item);
953 		}
954 		if (tagName == "Pattern") // FIXME
955 		{
956 			/*success = readPattern(m_Doc, reader, fileDir);
957 			if (!success) break;*/
958 		}
959 		if (tagName == "NotesStyles")
960 		{
961 			success = readNotesStyles(m_Doc, reader);
962 			if (!success) break;
963 		}
964 		if (tagName == "Notes")
965 		{
966 			success = readNotes(m_Doc, reader);
967 			if (!success) break;
968 		}
969 		if (tagName == "Marks")
970 		{
971 			success = readMarks(m_Doc, reader);
972 			if (!success) break;
973 		}
974 	}
975 
976 	if (reader.hasError())
977 	{
978 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
979 		return false;
980 	}
981 
982 	//update names to pointers
983 	updateNames2Ptr();
984 
985 	return true;
986 }
987 
loadPalette(const QString & fileName)988 bool Scribus150Format::loadPalette(const QString & fileName)
989 {
990 	if (m_Doc == nullptr || m_AvailableFonts == nullptr)
991 	{
992 		Q_ASSERT(m_Doc == nullptr || m_AvailableFonts == nullptr);
993 		return false;
994 	}
995 
996 	Xp = 0.0;
997 	Yp = 0.0;
998 	GrX = 0.0;
999 	GrY = 0.0;
1000 	isNewFormat = false;
1001 
1002 	QMap<int, PageItem*> TableID;
1003 	QMap<int, PageItem*> TableIDM;
1004 	QMap<int, PageItem*> TableIDF;
1005 	QList<PageItem*> TableItems;
1006 	QList<PageItem*> TableItemsM;
1007 	QList<PageItem*> TableItemsF;
1008 	QMap<int, PageItem*> WeldID;
1009 	QList<PageItem*> WeldItems;
1010 	QStack< QList<PageItem*> > groupStackFI;
1011 	QStack< QList<PageItem*> > groupStackMI;
1012 	QStack< QList<PageItem*> > groupStackPI;
1013 	QStack< QList<PageItem*> > groupStackF;
1014 	QStack< QList<PageItem*> > groupStackM;
1015 	QStack< QList<PageItem*> > groupStackP;
1016 	QStack<int> groupStackFI2;
1017 	QStack<int> groupStackMI2;
1018 	QStack<int> groupStackPI2;
1019 
1020 	QScopedPointer<QIODevice> ioDevice(paletteReader(fileName));
1021 	if (ioDevice.isNull())
1022 	{
1023 		setFileReadError();
1024 		return false;
1025 	}
1026 	QString fileDir = QFileInfo(fileName).absolutePath();
1027 
1028 	if (m_mwProgressBar != nullptr)
1029 	{
1030 		m_mwProgressBar->setMaximum(ioDevice->size());
1031 		m_mwProgressBar->setValue(0);
1032 	}
1033 
1034 	itemRemap.clear();
1035 	itemNext.clear();
1036 	itemCount = 0;
1037 	itemRemapM.clear();
1038 	itemNextM.clear();
1039 	itemCountM = 0;
1040 	itemRemapF.clear();
1041 	itemNextF.clear();
1042 
1043 	TableItems.clear();
1044 	TableID.clear();
1045 	TableItemsM.clear();
1046 	TableIDM.clear();
1047 	TableItemsF.clear();
1048 	TableIDF.clear();
1049 	WeldItems.clear();
1050 
1051 	m_Doc->GroupCounter = 1;
1052 	m_Doc->LastAuto = nullptr;
1053 //	m_Doc->PageColors.clear();
1054 //	m_Doc->Layers.clear();
1055 
1056 	bool firstElement = true;
1057 	bool success = true;
1058 	int  progress = 0;
1059 
1060 	ReadObjectParams readObjectParams;
1061 	readObjectParams.baseDir = fileDir;
1062 	readObjectParams.itemKind = PageItem::StandardItem;
1063 	readObjectParams.loadingPage = false;
1064 
1065 	ScXmlStreamReader reader(ioDevice.data());
1066 	ScXmlStreamAttributes attrs;
1067 	while (!reader.atEnd() && !reader.hasError())
1068 	{
1069 		QXmlStreamReader::TokenType tType = reader.readNext();
1070 		if (tType != QXmlStreamReader::StartElement)
1071 			continue;
1072 		QStringRef tagName = reader.name();
1073 		attrs = reader.scAttributes();
1074 
1075 		if (m_mwProgressBar != nullptr)
1076 		{
1077 			int newProgress = qRound(ioDevice->pos() / (double) ioDevice->size() * 100);
1078 			if (newProgress != progress)
1079 			{
1080 				m_mwProgressBar->setValue(reader.characterOffset());
1081 				progress = newProgress;
1082 			}
1083 		}
1084 
1085 		if (firstElement)
1086 		{
1087 			if (tagName != "SCRIBUSCOLORS")
1088 			{
1089 				success = false;
1090 				break;
1091 			}
1092 			firstElement = false;
1093 		}
1094 		// 10/25/2004 pv - None is "reserved" color. cannot be defined in any file...
1095 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
1096 			readColor(m_Doc->PageColors, attrs);
1097 		if (tagName == "Gradient")
1098 		{
1099 			VGradient gra;
1100 			QString grName = attrs.valueAsString("Name");
1101 			success = readGradient(m_Doc, gra, reader);
1102 			if (!success)
1103 				break;
1104 			gra.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("Ext", VGradient::pad)));
1105 			if (!grName.isEmpty())
1106 			{
1107 				m_Doc->docGradients.insert(grName, gra);
1108 			}
1109 		}
1110 		if (tagName == "Arrows")
1111 		{
1112 			success = readArrows(m_Doc, attrs);
1113 			if (!success) break;
1114 		}
1115 		if (tagName == "MultiLine")
1116 		{
1117 			multiLine ml;
1118 			QString mlName = attrs.valueAsString("Name");
1119 			success = readMultiline(ml, reader);
1120 			if (!success) break;
1121 			if (!mlName.isEmpty())
1122 			{
1123 				m_Doc->docLineStyles.insert(mlName, ml);
1124 			}
1125 		}
1126 		if (tagName == "PAGEOBJECT" || tagName == "MASTEROBJECT" || tagName == "FRAMEOBJECT")
1127 		{
1128 			ItemInfo itemInfo;
1129 			success = readObject(m_Doc, reader, readObjectParams, itemInfo);
1130 			if (!success) break;
1131 
1132 			if (isNewFormat)
1133 			{
1134 				if (itemInfo.nextItem != -1)
1135 					itemNext[itemInfo.itemID] = itemInfo.nextItem;
1136 				if (itemInfo.item->isTableItem)
1137 					TableItems.append(itemInfo.item);
1138 				if (itemInfo.isWeldFlag)
1139 					WeldItems.append(itemInfo.item);
1140 			}
1141 			else
1142 			{
1143 				// first of linked chain?
1144 				if (tagName == "PAGEOBJECT")
1145 				{
1146 					if (itemInfo.nextItem != -1)
1147 						itemNext[itemInfo.ownNr] = itemInfo.nextItem;
1148 				}
1149 				else if (tagName == "MASTEROBJECT")
1150 				{
1151 					if (itemInfo.nextItem != -1)
1152 						itemNextM[itemInfo.ownNr] = itemInfo.nextItem;
1153 				}
1154 				if (itemInfo.item->isTableItem)
1155 				{
1156 					if (tagName == "PAGEOBJECT")
1157 					{
1158 						TableItems.append(itemInfo.item);
1159 						TableID.insert(itemInfo.ownLink, itemInfo.item);
1160 					}
1161 					else if (tagName == "FRAMEOBJECT")
1162 					{
1163 						TableItemsF.append(itemInfo.item);
1164 						TableIDF.insert(itemInfo.ownLink, itemInfo.item);
1165 					}
1166 					else
1167 					{
1168 						TableItemsM.append(itemInfo.item);
1169 						TableIDM.insert(itemInfo.ownLink, itemInfo.item);
1170 					}
1171 				}
1172 				if (itemInfo.isWeldFlag)
1173 				{
1174 					WeldItems.append(itemInfo.item);
1175 					WeldID.insert(itemInfo.ownWeld, itemInfo.item);
1176 				}
1177 			}
1178 
1179 			if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
1180 			{
1181 				groupStackPI.top().append(itemInfo.item);
1182 				while (itemInfo.ownNr == groupStackPI2.top())
1183 				{
1184 					groupStackP.push(groupStackPI.pop());
1185 					groupStackPI2.pop();
1186 					if (groupStackPI2.count() == 0)
1187 						break;
1188 				}
1189 			}
1190 			else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
1191 			{
1192 				groupStackFI.top().append(itemInfo.item);
1193 				while (itemInfo.ownNr == groupStackFI2.top())
1194 				{
1195 					groupStackF.push(groupStackFI.pop());
1196 					groupStackFI2.pop();
1197 					if (groupStackFI2.count() == 0)
1198 						break;
1199 				}
1200 			}
1201 			else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
1202 			{
1203 				groupStackMI.top().append(itemInfo.item);
1204 				while (itemInfo.ownNr == groupStackMI2.top())
1205 				{
1206 					groupStackM.push(groupStackMI.pop());
1207 					groupStackMI2.pop();
1208 					if (groupStackMI2.count() == 0)
1209 						break;
1210 				}
1211 			}
1212 
1213 			if (itemInfo.isGroupFlag)
1214 			{
1215 				QList<PageItem*> groupItems;
1216 				groupItems.append(itemInfo.item);
1217 				if (tagName == "PAGEOBJECT")
1218 				{
1219 					groupStackPI.push(groupItems);
1220 					groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1221 				}
1222 				else if (tagName == "FRAMEOBJECT")
1223 				{
1224 					groupStackFI.push(groupItems);
1225 					groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1226 				}
1227 				else
1228 				{
1229 					groupStackMI.push(groupItems);
1230 					groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1231 				}
1232 			}
1233 		}
1234 		if (tagName == "Pattern")
1235 		{
1236 			success = readPattern(m_Doc, reader, fileDir);
1237 			if (!success) break;
1238 		}
1239 		if (tagName == "NotesStyles")
1240 		{
1241 			success = readNotesStyles(m_Doc, reader);
1242 			if (!success) break;
1243 		}
1244 		if (tagName == "NotesFrames")
1245 		{
1246 			success = readNotesFrames(reader);
1247 			if (!success) break;
1248 		}
1249 		if (tagName == "Notes")
1250 		{
1251 			success = readNotes(m_Doc, reader);
1252 			if (!success) break;
1253 		}
1254 		if (tagName == "Marks")
1255 		{
1256 			success = readMarks(m_Doc, reader);
1257 			if (!success) break;
1258 		}
1259 	}
1260 
1261 	if (reader.hasError())
1262 	{
1263 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
1264 		return false;
1265 	}
1266 	if (isNewFormat)
1267 	{
1268 		if (TableItems.count() != 0)
1269 		{
1270 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
1271 			{
1272 				PageItem* ta = TableItems.at(ttc);
1273 				if (ta->TopLinkID != -1)
1274 					ta->m_topLink = LinkID[ta->TopLinkID];
1275 				else
1276 					ta->m_topLink = nullptr;
1277 				if (ta->LeftLinkID != -1)
1278 					ta->m_leftLink = LinkID[ta->LeftLinkID];
1279 				else
1280 					ta->m_leftLink = nullptr;
1281 				if (ta->RightLinkID != -1)
1282 					ta->m_rightLink = LinkID[ta->RightLinkID];
1283 				else
1284 					ta->m_rightLink = nullptr;
1285 				if (ta->BottomLinkID != -1)
1286 					ta->m_bottomLink = LinkID[ta->BottomLinkID];
1287 				else
1288 					ta->m_bottomLink = nullptr;
1289 			}
1290 		}
1291 		if (WeldItems.count() != 0)
1292 		{
1293 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
1294 			{
1295 				PageItem* ta = WeldItems.at(ttc);
1296 				for (int i = 0 ; i < ta->weldList.count(); ++i)
1297 				{
1298 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
1299 					ta->weldList[i].weldItem = LinkID.value(wInf.weldID, 0);
1300 					if (ta->weldList[i].weldItem == nullptr)
1301 						ta->weldList.removeAt(i--);
1302 				}
1303 			}
1304 		}
1305 		if (itemNext.count() != 0)
1306 		{
1307 			QMap<int,int>::Iterator lc;
1308 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
1309 			{
1310 				if (lc.value() >= 0)
1311 				{
1312 					PageItem * Its = LinkID[lc.key()];
1313 					PageItem * Itn = LinkID[lc.value()];
1314 					if (!Its->canBeLinkedTo(Itn))
1315 					{
1316 						qDebug() << "scribus150format: corruption in linked textframes detected";
1317 						continue;
1318 					}
1319 					Its->link(Itn);
1320 				}
1321 			}
1322 		}
1323 	}
1324 	else
1325 	{
1326 		if (TableItemsF.count() != 0)
1327 		{
1328 			for (int ttc = 0; ttc < TableItemsF.count(); ++ttc)
1329 			{
1330 				PageItem* ta = TableItemsF.at(ttc);
1331 				if (ta->TopLinkID != -1)
1332 					ta->m_topLink = TableIDF[ta->TopLinkID];
1333 				else
1334 					ta->m_topLink = nullptr;
1335 				if (ta->LeftLinkID != -1)
1336 					ta->m_leftLink = TableIDF[ta->LeftLinkID];
1337 				else
1338 					ta->m_leftLink = nullptr;
1339 				if (ta->RightLinkID != -1)
1340 					ta->m_rightLink = TableIDF[ta->RightLinkID];
1341 				else
1342 					ta->m_rightLink = nullptr;
1343 				if (ta->BottomLinkID != -1)
1344 					ta->m_bottomLink = TableIDF[ta->BottomLinkID];
1345 				else
1346 					ta->m_bottomLink = nullptr;
1347 			}
1348 		}
1349 		if (TableItemsM.count() != 0)
1350 		{
1351 			for (int ttc = 0; ttc < TableItemsM.count(); ++ttc)
1352 			{
1353 				PageItem* ta = TableItemsM.at(ttc);
1354 				if (ta->TopLinkID != -1)
1355 					ta->m_topLink = TableIDM[ta->TopLinkID];
1356 				else
1357 					ta->m_topLink = nullptr;
1358 				if (ta->LeftLinkID != -1)
1359 					ta->m_leftLink = TableIDM[ta->LeftLinkID];
1360 				else
1361 					ta->m_leftLink = nullptr;
1362 				if (ta->RightLinkID != -1)
1363 					ta->m_rightLink = TableIDM[ta->RightLinkID];
1364 				else
1365 					ta->m_rightLink = nullptr;
1366 				if (ta->BottomLinkID != -1)
1367 					ta->m_bottomLink = TableIDM[ta->BottomLinkID];
1368 				else
1369 					ta->m_bottomLink = nullptr;
1370 			}
1371 		}
1372 		if (TableItems.count() != 0)
1373 		{
1374 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
1375 			{
1376 				PageItem* ta = TableItems.at(ttc);
1377 				if (ta->TopLinkID != -1)
1378 					ta->m_topLink = TableID[ta->TopLinkID];
1379 				else
1380 					ta->m_topLink = nullptr;
1381 				if (ta->LeftLinkID != -1)
1382 					ta->m_leftLink = TableID[ta->LeftLinkID];
1383 				else
1384 					ta->m_leftLink = nullptr;
1385 				if (ta->RightLinkID != -1)
1386 					ta->m_rightLink = TableID[ta->RightLinkID];
1387 				else
1388 					ta->m_rightLink = nullptr;
1389 				if (ta->BottomLinkID != -1)
1390 					ta->m_bottomLink = TableID[ta->BottomLinkID];
1391 				else
1392 					ta->m_bottomLink = nullptr;
1393 			}
1394 		}
1395 		if (WeldItems.count() != 0)
1396 		{
1397 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
1398 			{
1399 				PageItem* ta = WeldItems.at(ttc);
1400 				for (int i = 0 ; i < ta->weldList.count(); ++i)
1401 				{
1402 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
1403 					ta->weldList[i].weldItem = WeldID.value(wInf.weldID, 0);
1404 					if (ta->weldList[i].weldItem == nullptr)
1405 						ta->weldList.removeAt(i--);
1406 				}
1407 			}
1408 		}
1409 		// reestablish textframe links
1410 		if (itemNext.count() != 0)
1411 		{
1412 			QMap<int,int>::Iterator lc;
1413 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
1414 			{
1415 				if (lc.value() >= 0)
1416 				{
1417 					PageItem *Its(nullptr), *Itn(nullptr);
1418 					if (lc.key() < m_Doc->DocItems.count())
1419 						Its = m_Doc->DocItems.at(lc.key());
1420 					if (lc.value() < m_Doc->DocItems.count())
1421 						Itn = m_Doc->DocItems.at(lc.value());
1422 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
1423 					{
1424 						qDebug() << "scribus150format: corruption in linked textframes detected";
1425 						continue;
1426 					}
1427 					Its->link(Itn);
1428 				}
1429 			}
1430 		}
1431 		if (itemNextM.count() != 0)
1432 		{
1433 			QMap<int,int>::Iterator lc;
1434 			for (lc = itemNextM.begin(); lc != itemNextM.end(); ++lc)
1435 			{
1436 				if (lc.value() >= 0)
1437 				{
1438 					PageItem *Its(nullptr), *Itn(nullptr);
1439 					if (lc.key() < m_Doc->MasterItems.count())
1440 						Its = m_Doc->MasterItems.at(lc.key());
1441 					if (lc.value() < m_Doc->MasterItems.count())
1442 						Itn = m_Doc->MasterItems.at(lc.value());
1443 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
1444 					{
1445 						qDebug() << "scribus150format: corruption in linked textframes detected";
1446 						continue;
1447 					}
1448 					Its->link(Itn);
1449 				}
1450 			}
1451 		}
1452 	}
1453 
1454 	while (groupStackP.count() > 0)
1455 	{
1456 		bool isTableIt = false;
1457 		QList<PageItem*> gpL = groupStackP.pop();
1458 		PageItem* gItem = gpL.takeFirst();
1459 		for (int id = 0; id < gpL.count(); id++)
1460 		{
1461 			PageItem* cItem = gpL.at(id);
1462 			isTableIt = cItem->isTableItem;
1463 			cItem->gXpos = cItem->xPos() - gItem->xPos();
1464 			cItem->gYpos = cItem->yPos() - gItem->yPos();
1465 			cItem->Parent = gItem;
1466 			if (gItem->rotation() != 0)
1467 			{
1468 				QTransform ma;
1469 				ma.rotate(-gItem->rotation());
1470 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
1471 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
1472 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
1473 				cItem->setRotation(cItem->rotation() - gItem->rotation());
1474 				cItem->oldRot = cItem->rotation();
1475 			}
1476 			m_Doc->DocItems.removeOne(cItem);
1477 		}
1478 		bool converted = false;
1479 		if (isTableIt)
1480 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
1481 		if (!converted)
1482 			gItem->groupItemList = gpL;
1483 	}
1484 
1485 	while (groupStackF.count() > 0)
1486 	{
1487 		bool isTableIt = false;
1488 		QList<PageItem*> gpL = groupStackF.pop();
1489 		PageItem* gItem = gpL.takeFirst();
1490 		for (int id = 0; id < gpL.count(); id++)
1491 		{
1492 			PageItem* cItem = gpL.at(id);
1493 			isTableIt = cItem->isTableItem;
1494 			cItem->gXpos = cItem->xPos() - gItem->xPos();
1495 			cItem->gYpos = cItem->yPos() - gItem->yPos();
1496 			cItem->Parent = gItem;
1497 			if (gItem->rotation() != 0)
1498 			{
1499 				QTransform ma;
1500 				ma.rotate(-gItem->rotation());
1501 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
1502 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
1503 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
1504 				cItem->setRotation(cItem->rotation() - gItem->rotation());
1505 				cItem->oldRot = cItem->rotation();
1506 			}
1507 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
1508 		}
1509 		bool converted = false;
1510 		if (isTableIt)
1511 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
1512 		if (!converted)
1513 			gItem->groupItemList = gpL;
1514 	}
1515 
1516 	while (groupStackM.count() > 0)
1517 	{
1518 		bool isTableIt = false;
1519 		QList<PageItem*> gpL = groupStackM.pop();
1520 		PageItem* gItem = gpL.takeFirst();
1521 		for (int id = 0; id < gpL.count(); id++)
1522 		{
1523 			PageItem* cItem = gpL.at(id);
1524 			isTableIt = cItem->isTableItem;
1525 			cItem->gXpos = cItem->xPos() - gItem->xPos();
1526 			cItem->gYpos = cItem->yPos() - gItem->yPos();
1527 			cItem->Parent = gItem;
1528 			if (gItem->rotation() != 0)
1529 			{
1530 				QTransform ma;
1531 				ma.rotate(-gItem->rotation());
1532 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
1533 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
1534 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
1535 				cItem->setRotation(cItem->rotation() - gItem->rotation());
1536 				cItem->oldRot = cItem->rotation();
1537 			}
1538 			m_Doc->MasterItems.removeOne(cItem);
1539 		}
1540 		bool converted = false;
1541 		if (isTableIt)
1542 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
1543 		if (!converted)
1544 			gItem->groupItemList = gpL;
1545 	}
1546 
1547 	if (m_Doc->Layers.count() == 0)
1548 		m_Doc->Layers.newLayer( QObject::tr("Background") );
1549 	if (m_mwProgressBar!=nullptr)
1550 	{
1551 		m_mwProgressBar->setValue(reader.characterOffset());
1552 		m_mwProgressBar->reset();
1553 	}
1554 	return true;
1555 }
1556 
loadFile(const QString & fileName,const FileFormat &,int,int)1557 bool Scribus150Format::loadFile(const QString & fileName, const FileFormat & /* fmt */, int /* flags */, int /* index */)
1558 {
1559 	if (m_Doc==nullptr || m_AvailableFonts==nullptr)
1560 	{
1561 		Q_ASSERT(m_Doc==nullptr || m_AvailableFonts==nullptr);
1562 		return false;
1563 	}
1564 
1565 	Xp = 0.0;
1566 	Yp = 0.0;
1567 	GrX = 0.0;
1568 	GrY = 0.0;
1569 	struct ScribusDoc::BookMa bok;
1570 	QMap<int, ScribusDoc::BookMa> bookmarks;
1571 
1572 	isNewFormat = false;
1573 
1574 	QMap<int, PageItem*> TableID;
1575 	QMap<int, PageItem*> TableIDM;
1576 	QMap<int, PageItem*> TableIDF;
1577 	QList<PageItem*> TableItems;
1578 	QList<PageItem*> TableItemsM;
1579 	QList<PageItem*> TableItemsF;
1580 	QMap<int, PageItem*> WeldID;
1581 	QList<PageItem*> WeldItems;
1582 	QStack< QList<PageItem*> > groupStackFI;
1583 	QStack< QList<PageItem*> > groupStackMI;
1584 	QStack< QList<PageItem*> > groupStackPI;
1585 	QStack< QList<PageItem*> > groupStackF;
1586 	QStack< QList<PageItem*> > groupStackM;
1587 	QStack< QList<PageItem*> > groupStackP;
1588 	QStack<int> groupStackFI2;
1589 	QStack<int> groupStackMI2;
1590 	QStack<int> groupStackPI2;
1591 
1592 	markeredItemsMap.clear();
1593 	markeredMarksMap.clear();
1594 	nsetRangeItemNamesMap.clear();
1595 	notesFramesData.clear();
1596 	notesMasterMarks.clear();
1597 	notesNSets.clear();
1598 
1599 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
1600 	if (ioDevice.isNull())
1601 	{
1602 		setFileReadError();
1603 		return false;
1604 	}
1605 	QString fileDir = QFileInfo(fileName).absolutePath();
1606 	int firstPage = 0;
1607 	int layerToSetActive = 0;
1608 
1609 	if (m_mwProgressBar != nullptr)
1610 	{
1611 		m_mwProgressBar->setMaximum(ioDevice->size());
1612 		m_mwProgressBar->setValue(0);
1613 	}
1614 	// Stop autosave timer,it will be restarted only if doc has autosave feature is enabled
1615 	if (m_Doc->autoSaveTimer->isActive())
1616 		m_Doc->autoSaveTimer->stop();
1617 
1618 	parStyleMap.clear();
1619 	charStyleMap.clear();
1620 	itemRemap.clear();
1621 	itemNext.clear();
1622 	itemCount = 0;
1623 	itemRemapM.clear();
1624 	itemNextM.clear();
1625 	itemCountM = 0;
1626 	itemRemapF.clear();
1627 	itemNextF.clear();
1628 
1629 	FrameItems.clear();
1630 	TableItems.clear();
1631 	TableID.clear();
1632 	TableItemsM.clear();
1633 	TableIDM.clear();
1634 	TableItemsF.clear();
1635 	TableIDF.clear();
1636 	WeldItems.clear();
1637 	WeldID.clear();
1638 	LinkID.clear();
1639 
1640 	m_Doc->GroupCounter = 1;
1641 	m_Doc->LastAuto = nullptr;
1642 	m_Doc->PageColors.clear();
1643 	m_Doc->Layers.clear();
1644 
1645 	ReadObjectParams readObjectParams;
1646 	readObjectParams.baseDir = fileDir;
1647 	readObjectParams.itemKind = PageItem::StandardItem;
1648 	readObjectParams.loadingPage = false;
1649 
1650 	bool firstElement = true;
1651 	bool success = true;
1652 	bool hasPageSets = false;
1653 	int  progress = 0;
1654 
1655 	ScXmlStreamReader reader(ioDevice.data());
1656 	ScXmlStreamAttributes attrs;
1657 	while (!reader.atEnd() && !reader.hasError())
1658 	{
1659 		QXmlStreamReader::TokenType tType = reader.readNext();
1660 		if (tType != QXmlStreamReader::StartElement)
1661 			continue;
1662 		QStringRef tagName = reader.name();
1663 		attrs = reader.scAttributes();
1664 
1665 		if (m_mwProgressBar != nullptr)
1666 		{
1667 			int newProgress = qRound(ioDevice->pos() / (double) ioDevice->size() * 100);
1668 			if (newProgress != progress)
1669 			{
1670 				m_mwProgressBar->setValue(reader.characterOffset());
1671 				progress = newProgress;
1672 			}
1673 		}
1674 
1675 		if (firstElement)
1676 		{
1677 			if (tagName != "SCRIBUSUTF8NEW")
1678 			{
1679 				success = false;
1680 				break;
1681 			}
1682 			firstElement = false;
1683 		}
1684 		if (tagName == "DOCUMENT")
1685 		{
1686 			readDocAttributes(m_Doc, attrs);
1687 			layerToSetActive = attrs.valueAsInt("ALAYER", 0);
1688 			if (m_Doc->pagePositioning() == 0)
1689 				firstPage = 0;
1690 			else
1691 			{
1692 				if (attrs.valueAsInt("FIRSTLEFT", 0) == 1)
1693 					firstPage = 0;
1694 				else
1695 					firstPage = 1;
1696 			}
1697 			if (attrs.hasAttribute("currentProfile"))
1698 			{
1699 				m_Doc->clearCheckerProfiles();
1700 				m_Doc->setCurCheckProfile(attrs.valueAsString("currentProfile"));
1701 			}
1702 		}
1703 		if (tagName == "CheckProfile")
1704 		{
1705 			success = readCheckProfile(m_Doc, attrs);
1706 			if (!success) break;
1707 		}
1708 		if (tagName == "PageSets")
1709 		{
1710 			success = readPageSets(m_Doc, reader);
1711 			if (!success) break;
1712 			hasPageSets = true;
1713 		}
1714 		// 10/25/2004 pv - None is "reserved" color. cannot be defined in any file...
1715 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
1716 			readColor(m_Doc->PageColors, attrs);
1717 		if (tagName == "Gradient")
1718 		{
1719 			VGradient gra;
1720 			QString grName = attrs.valueAsString("Name");
1721 			success = readGradient(m_Doc, gra, reader);
1722 			if (!success)
1723 				break;
1724 			gra.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("Ext", VGradient::pad)));
1725 			if (!grName.isEmpty())
1726 				m_Doc->docGradients.insert(grName, gra);
1727 		}
1728 		if (tagName == "STYLE")
1729 		{
1730 			ParagraphStyle pstyle;
1731 			readParagraphStyle(m_Doc, reader, pstyle);
1732 			StyleSet<ParagraphStyle>tmp;
1733 			tmp.create(pstyle);
1734 			m_Doc->redefineStyles(tmp, false);
1735 		}
1736 		if (tagName == "CHARSTYLE")
1737 		{
1738 			CharStyle cstyle;
1739 			ScXmlStreamAttributes attrs = reader.scAttributes();
1740 			readNamedCharacterStyleAttrs(m_Doc, attrs, cstyle);
1741 			StyleSet<CharStyle> temp;
1742 			temp.create(cstyle);
1743 			m_Doc->redefineCharStyles(temp, false);
1744 		}
1745 		if (tagName == "TableStyle")
1746 		{
1747 			TableStyle tstyle;
1748 			readTableStyle(m_Doc, reader, tstyle);
1749 			StyleSet<TableStyle> temp;
1750 			temp.create(tstyle);
1751 			m_Doc->redefineTableStyles(temp, false);
1752 		}
1753 		if (tagName == "CellStyle")
1754 		{
1755 			CellStyle tstyle;
1756 			readCellStyle(m_Doc, reader, tstyle);
1757 			StyleSet<CellStyle> temp;
1758 			temp.create(tstyle);
1759 			m_Doc->redefineCellStyles(temp, false);
1760 		}
1761 		if (tagName == "JAVA")
1762 		{
1763 			QString name = attrs.valueAsString("NAME");
1764 			if (!name.isEmpty())
1765 				m_Doc->JavaScripts[name] = attrs.valueAsString("SCRIPT");
1766 		}
1767 		if (tagName == "LAYERS")
1768 		{
1769 			ScLayer newLayer;
1770 			readLayers(newLayer, attrs);
1771 			m_Doc->Layers.append(newLayer);
1772 		}
1773 		if (tagName == "Arrows")
1774 		{
1775 			success = readArrows(m_Doc, attrs);
1776 			if (!success) break;
1777 		}
1778 		if (tagName == "MultiLine")
1779 		{
1780 			multiLine ml;
1781 			QString mlName = attrs.valueAsString("Name");
1782 			success = readMultiline(ml, reader);
1783 			if (!success) break;
1784 			if (!mlName.isEmpty())
1785 			{
1786 				m_Doc->docLineStyles.insert(mlName, ml);
1787 			}
1788 		}
1789 		if (tagName == "Bookmark")
1790 		{
1791 			int bmElem = 0;
1792 			struct ScribusDoc::BookMa bookmark;
1793 			success = readBookMark(bookmark, bmElem, attrs);
1794 			if (!success) break;
1795 			bookmarks.insert(bmElem, bookmark);
1796 		}
1797 		if (tagName == "PDF")
1798 		{
1799 			success = readPDFOptions(m_Doc, reader);
1800 			if (!success) break;
1801 		}
1802 		if (tagName == "Printer")
1803 		{
1804 			success = readPrinterOptions(m_Doc, reader);
1805 			if (!success) break;
1806 		}
1807 		if (tagName == "DocItemAttributes")
1808 		{
1809 			success = readDocItemAttributes(m_Doc, reader);
1810 			if (!success) break;
1811 		}
1812 		if (tagName == "TablesOfContents")
1813 		{
1814 			success = readTableOfContents(m_Doc, reader);
1815 			if (!success) break;
1816 		}
1817 		if (tagName == "Sections")
1818 		{
1819 			success = readSections(m_Doc, reader);
1820 			if (!success) break;
1821 		}
1822 		if (tagName == "HYPHEN")
1823 		{
1824 			success = readHyphen(m_Doc, reader);
1825 			if (!success) break;
1826 		}
1827 		if (tagName == "PAGE" || tagName == "MASTERPAGE")
1828 		{
1829 			success = readPage(m_Doc, reader);
1830 			if (!success)
1831 				break;
1832 		}
1833 		if (tagName == "PAGEOBJECT" || tagName == "MASTEROBJECT" || tagName == "FRAMEOBJECT")
1834 		{
1835 			ItemInfo itemInfo;
1836 			success = readObject(m_Doc, reader, readObjectParams, itemInfo);
1837 			if (!success)
1838 				break;
1839 
1840 			// first of linked chain?
1841 			if (isNewFormat)
1842 			{
1843 				if (itemInfo.nextItem != -1)
1844 					itemNext[itemInfo.itemID] = itemInfo.nextItem;
1845 				if (itemInfo.item->isTableItem)
1846 					TableItems.append(itemInfo.item);
1847 				if (itemInfo.isWeldFlag)
1848 					WeldItems.append(itemInfo.item);
1849 			}
1850 			else
1851 			{
1852 				if (tagName == "PAGEOBJECT")
1853 				{
1854 					if (itemInfo.nextItem != -1)
1855 						itemNext[itemInfo.ownNr] = itemInfo.nextItem;
1856 				}
1857 				else if (tagName == "MASTEROBJECT")
1858 				{
1859 					if (itemInfo.nextItem != -1)
1860 						itemNextM[itemInfo.ownNr] = itemInfo.nextItem;
1861 				}
1862 				if (itemInfo.item->isTableItem)
1863 				{
1864 					if (tagName == "PAGEOBJECT")
1865 					{
1866 						TableItems.append(itemInfo.item);
1867 						TableID.insert(itemInfo.ownLink, itemInfo.item);
1868 					}
1869 					else if (tagName == "FRAMEOBJECT")
1870 					{
1871 						TableItemsF.append(itemInfo.item);
1872 						TableIDF.insert(itemInfo.ownLink, itemInfo.item);
1873 					}
1874 					else
1875 					{
1876 						TableItemsM.append(itemInfo.item);
1877 						TableIDM.insert(itemInfo.ownLink, itemInfo.item);
1878 					}
1879 				}
1880 
1881 				if (itemInfo.isWeldFlag)
1882 				{
1883 					WeldItems.append(itemInfo.item);
1884 					WeldID.insert(itemInfo.ownWeld, itemInfo.item);
1885 				}
1886 			}
1887 
1888 			if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
1889 			{
1890 				groupStackPI.top().append(itemInfo.item);
1891 				while (itemInfo.ownNr == groupStackPI2.top())
1892 				{
1893 					groupStackP.push(groupStackPI.pop());
1894 					groupStackPI2.pop();
1895 					if (groupStackPI2.count() == 0)
1896 						break;
1897 				}
1898 			}
1899 			else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
1900 			{
1901 				groupStackFI.top().append(itemInfo.item);
1902 				while (itemInfo.ownNr == groupStackFI2.top())
1903 				{
1904 					groupStackF.push(groupStackFI.pop());
1905 					groupStackFI2.pop();
1906 					if (groupStackFI2.count() == 0)
1907 						break;
1908 				}
1909 			}
1910 			else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
1911 			{
1912 				groupStackMI.top().append(itemInfo.item);
1913 				while (itemInfo.ownNr == groupStackMI2.top())
1914 				{
1915 					groupStackM.push(groupStackMI.pop());
1916 					groupStackMI2.pop();
1917 					if (groupStackMI2.count() == 0)
1918 						break;
1919 				}
1920 			}
1921 
1922 			if (itemInfo.isGroupFlag)
1923 			{
1924 				QList<PageItem*> groupItems;
1925 				groupItems.append(itemInfo.item);
1926 				if (tagName == "PAGEOBJECT")
1927 				{
1928 					groupStackPI.push(groupItems);
1929 					groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1930 				}
1931 				else if (tagName == "FRAMEOBJECT")
1932 				{
1933 					groupStackFI.push(groupItems);
1934 					groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1935 				}
1936 				else
1937 				{
1938 					groupStackMI.push(groupItems);
1939 					groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
1940 				}
1941 			}
1942 		}
1943 		if (tagName == "Pattern")
1944 		{
1945 			success = readPattern(m_Doc, reader, fileDir);
1946 			if (!success)
1947 				break;
1948 		}
1949 		if (tagName == "NotesStyles")
1950 		{
1951 			success = readNotesStyles(m_Doc, reader);
1952 			if (!success) break;
1953 		}
1954 		if (tagName == "NotesFrames")
1955 		{
1956 			success = readNotesFrames(reader);
1957 			if (!success) break;
1958 		}
1959 		if (tagName == "Notes")
1960 		{
1961 			success = readNotes(m_Doc, reader);
1962 			if (!success) break;
1963 		}
1964 		if (tagName == "Marks")
1965 		{
1966 			success = readMarks(m_Doc, reader);
1967 			if (!success) break;
1968 		}
1969 	}
1970 
1971 	if (reader.hasError())
1972 	{
1973 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
1974 		return false;
1975 	}
1976 
1977 	QMap<int, ScribusDoc::BookMa>::Iterator it;
1978 	for (it = bookmarks.begin(); it != bookmarks.end(); ++it)
1979 	{
1980 		int elem = it.key();
1981 		PageItem* item = LinkID.value(elem, (PageItem*) nullptr);
1982 		if (!item)
1983 			continue;
1984 		ScribusDoc::BookMa bookmark = it.value();
1985 		bookmark.PageObject = item;
1986 		m_Doc->BookMarks.append( bookmark );
1987 	}
1988 	std::stable_sort(m_Doc->BookMarks.begin(), m_Doc->BookMarks.end());
1989 
1990 	if (isNewFormat)
1991 	{
1992 		if (TableItems.count() != 0)
1993 		{
1994 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
1995 			{
1996 				PageItem* ta = TableItems.at(ttc);
1997 				if (ta->TopLinkID != -1)
1998 					ta->m_topLink = LinkID[ta->TopLinkID];
1999 				else
2000 					ta->m_topLink = nullptr;
2001 				if (ta->LeftLinkID != -1)
2002 					ta->m_leftLink = LinkID[ta->LeftLinkID];
2003 				else
2004 					ta->m_leftLink = nullptr;
2005 				if (ta->RightLinkID != -1)
2006 					ta->m_rightLink = LinkID[ta->RightLinkID];
2007 				else
2008 					ta->m_rightLink = nullptr;
2009 				if (ta->BottomLinkID != -1)
2010 					ta->m_bottomLink = LinkID[ta->BottomLinkID];
2011 				else
2012 					ta->m_bottomLink = nullptr;
2013 			}
2014 		}
2015 		if (WeldItems.count() != 0)
2016 		{
2017 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
2018 			{
2019 				PageItem* ta = WeldItems.at(ttc);
2020 				for (int i = 0 ; i < ta->weldList.count(); ++i)
2021 				{
2022 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
2023 					ta->weldList[i].weldItem = LinkID.value(wInf.weldID, 0);
2024 					if (ta->weldList[i].weldItem == nullptr)
2025 						ta->weldList.removeAt(i--);
2026 				}
2027 			}
2028 		}
2029 		if (itemNext.count() != 0)
2030 		{
2031 			QMap<int,int>::Iterator lc;
2032 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
2033 			{
2034 				if (lc.value() >= 0)
2035 				{
2036 					PageItem * Its = LinkID[lc.key()];
2037 					PageItem * Itn = LinkID[lc.value()];
2038 					if (!Its->canBeLinkedTo(Itn))
2039 					{
2040 						qDebug() << "scribus150format: corruption in linked textframes detected";
2041 						continue;
2042 					}
2043 					Its->link(Itn);
2044 				}
2045 			}
2046 		}
2047 	}
2048 	else
2049 	{
2050 		if (TableItemsF.count() != 0)
2051 		{
2052 			for (int ttc = 0; ttc < TableItemsF.count(); ++ttc)
2053 			{
2054 				PageItem* ta = TableItemsF.at(ttc);
2055 				if (ta->TopLinkID != -1)
2056 					ta->m_topLink = TableIDF[ta->TopLinkID];
2057 				else
2058 					ta->m_topLink = nullptr;
2059 				if (ta->LeftLinkID != -1)
2060 					ta->m_leftLink = TableIDF[ta->LeftLinkID];
2061 				else
2062 					ta->m_leftLink = nullptr;
2063 				if (ta->RightLinkID != -1)
2064 					ta->m_rightLink = TableIDF[ta->RightLinkID];
2065 				else
2066 					ta->m_rightLink = nullptr;
2067 				if (ta->BottomLinkID != -1)
2068 					ta->m_bottomLink = TableIDF[ta->BottomLinkID];
2069 				else
2070 					ta->m_bottomLink = nullptr;
2071 			}
2072 		}
2073 		if (TableItemsM.count() != 0)
2074 		{
2075 			for (int ttc = 0; ttc < TableItemsM.count(); ++ttc)
2076 			{
2077 				PageItem* ta = TableItemsM.at(ttc);
2078 				if (ta->TopLinkID != -1)
2079 					ta->m_topLink = TableIDM[ta->TopLinkID];
2080 				else
2081 					ta->m_topLink = nullptr;
2082 				if (ta->LeftLinkID != -1)
2083 					ta->m_leftLink = TableIDM[ta->LeftLinkID];
2084 				else
2085 					ta->m_leftLink = nullptr;
2086 				if (ta->RightLinkID != -1)
2087 					ta->m_rightLink = TableIDM[ta->RightLinkID];
2088 				else
2089 					ta->m_rightLink = nullptr;
2090 				if (ta->BottomLinkID != -1)
2091 					ta->m_bottomLink = TableIDM[ta->BottomLinkID];
2092 				else
2093 					ta->m_bottomLink = nullptr;
2094 			}
2095 		}
2096 		if (TableItems.count() != 0)
2097 		{
2098 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
2099 			{
2100 				PageItem* ta = TableItems.at(ttc);
2101 				if (ta->TopLinkID != -1)
2102 					ta->m_topLink = TableID[ta->TopLinkID];
2103 				else
2104 					ta->m_topLink = nullptr;
2105 				if (ta->LeftLinkID != -1)
2106 					ta->m_leftLink = TableID[ta->LeftLinkID];
2107 				else
2108 					ta->m_leftLink = nullptr;
2109 				if (ta->RightLinkID != -1)
2110 					ta->m_rightLink = TableID[ta->RightLinkID];
2111 				else
2112 					ta->m_rightLink = nullptr;
2113 				if (ta->BottomLinkID != -1)
2114 					ta->m_bottomLink = TableID[ta->BottomLinkID];
2115 				else
2116 					ta->m_bottomLink = nullptr;
2117 			}
2118 		}
2119 		if (WeldItems.count() != 0)
2120 		{
2121 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
2122 			{
2123 				PageItem* ta = WeldItems.at(ttc);
2124 				for (int i = 0 ; i < ta->weldList.count(); ++i)
2125 				{
2126 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
2127 					ta->weldList[i].weldItem = WeldID.value(wInf.weldID, 0);
2128 					if (ta->weldList[i].weldItem == nullptr)
2129 						ta->weldList.removeAt(i--);
2130 				}
2131 			}
2132 		}
2133 		if (itemNext.count() != 0)
2134 		{
2135 			QMap<int,int>::Iterator lc;
2136 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
2137 			{
2138 				if (lc.value() >= 0)
2139 				{
2140 					PageItem *Its(nullptr), *Itn(nullptr);
2141 					if (lc.key() < m_Doc->DocItems.count())
2142 						Its = m_Doc->DocItems.at(lc.key());
2143 					if (lc.value() < m_Doc->DocItems.count())
2144 						Itn = m_Doc->DocItems.at(lc.value());
2145 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
2146 					{
2147 						qDebug() << "scribus150format: corruption in linked textframes detected";
2148 						continue;
2149 					}
2150 					Its->link(Itn);
2151 				}
2152 			}
2153 		}
2154 		if (itemNextM.count() != 0)
2155 		{
2156 			QMap<int,int>::Iterator lc;
2157 			for (lc = itemNextM.begin(); lc != itemNextM.end(); ++lc)
2158 			{
2159 				if (lc.value() >= 0)
2160 				{
2161 					PageItem *Its(nullptr), *Itn(nullptr);
2162 					if (lc.key() < m_Doc->MasterItems.count())
2163 						Its = m_Doc->MasterItems.at(lc.key());
2164 					if (lc.value() < m_Doc->MasterItems.count())
2165 						Itn = m_Doc->MasterItems.at(lc.value());
2166 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
2167 					{
2168 						qDebug() << "scribus150format: corruption in linked textframes detected";
2169 						continue;
2170 					}
2171 					Its->link(Itn);
2172 				}
2173 			}
2174 		}
2175 	}
2176 	//CB Add this in to set this in the file in memory. Its saved, why not load it.
2177 	//Will of course be replaced by per page settings although we still probably need a document default
2178 	if (!hasPageSets)
2179 	{
2180 		m_Doc->setPageSetFirstPage(m_Doc->pagePositioning(), firstPage);
2181 //->Prefs		m_Doc->pageSets[m_Doc->currentPageLayout].FirstPage = firstPage;
2182 //		m_Doc->pageSets[m_Doc->currentPageLayout].GapHorizontal = dc.attribute("GapHorizontal", "0").toDouble();
2183 //		m_Doc->pageSets[m_Doc->currentPageLayout].GapVertical = 0.0;
2184 //		m_Doc->pageSets[m_Doc->currentPageLayout].GapBelow = dc.attribute("GapVertical", "40").toDouble();
2185 	}
2186 	m_Doc->setActiveLayer(layerToSetActive);
2187 	m_Doc->setMasterPageMode(false);
2188 	m_Doc->reformPages();
2189 	m_Doc->refreshGuides();
2190 
2191 	// #12282 : some docs have language dependent style names specified in style properties
2192 	// #14129 : some others reference deleted character styles
2193 	m_Doc->fixCharacterStyles();
2194 	m_Doc->fixParagraphStyles();
2195 	m_Doc->fixNotesStyles();
2196 
2197 	// #14603 : it seems we need this also for some 1.5.x docs
2198 	m_Doc->fixItemPageOwner();
2199 
2200 	if (m_Doc->Layers.count() == 0)
2201 		m_Doc->Layers.newLayer( QObject::tr("Background") );
2202 	if (!EffVal.isEmpty())
2203 	{
2204 		for (int pdoE = 0; pdoE < EffVal.count(); ++pdoE)
2205 		{
2206 			if (pdoE < m_Doc->Pages->count())
2207 				m_Doc->Pages->at(pdoE)->PresentVals = EffVal[pdoE];
2208 		}
2209 	}
2210 
2211 	while (groupStackP.count() > 0)
2212 	{
2213 		bool isTableIt = false;
2214 		QList<PageItem*> gpL = groupStackP.pop();
2215 		PageItem* gItem = gpL.takeFirst();
2216 		for (int id = 0; id < gpL.count(); id++)
2217 		{
2218 			PageItem* cItem = gpL.at(id);
2219 			isTableIt = cItem->isTableItem;
2220 			cItem->gXpos = cItem->xPos() - gItem->xPos();
2221 			cItem->gYpos = cItem->yPos() - gItem->yPos();
2222 			cItem->Parent = gItem;
2223 			if (gItem->rotation() != 0)
2224 			{
2225 				QTransform ma;
2226 				ma.rotate(-gItem->rotation());
2227 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
2228 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
2229 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
2230 				cItem->setRotation(cItem->rotation() - gItem->rotation());
2231 				cItem->oldRot = cItem->rotation();
2232 			}
2233 			m_Doc->DocItems.removeOne(cItem);
2234 		}
2235 		bool converted = false;
2236 		if (isTableIt)
2237 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
2238 		if (!converted)
2239 			gItem->groupItemList = gpL;
2240 	}
2241 
2242 	while (groupStackF.count() > 0)
2243 	{
2244 		bool isTableIt = false;
2245 		QList<PageItem*> gpL = groupStackF.pop();
2246 		PageItem* gItem = gpL.takeFirst();
2247 		for (int id = 0; id < gpL.count(); id++)
2248 		{
2249 			PageItem* cItem = gpL.at(id);
2250 			isTableIt = cItem->isTableItem;
2251 			cItem->gXpos = cItem->xPos() - gItem->xPos();
2252 			cItem->gYpos = cItem->yPos() - gItem->yPos();
2253 			cItem->Parent = gItem;
2254 			if (gItem->rotation() != 0)
2255 			{
2256 				QTransform ma;
2257 				ma.rotate(-gItem->rotation());
2258 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
2259 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
2260 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
2261 				cItem->setRotation(cItem->rotation() - gItem->rotation());
2262 				cItem->oldRot = cItem->rotation();
2263 			}
2264 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
2265 		}
2266 		bool converted = false;
2267 		if (isTableIt)
2268 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
2269 		if (!converted)
2270 			gItem->groupItemList = gpL;
2271 	}
2272 
2273 	while (groupStackM.count() > 0)
2274 	{
2275 		bool isTableIt = false;
2276 		QList<PageItem*> gpL = groupStackM.pop();
2277 		PageItem* gItem = gpL.takeFirst();
2278 		for (int id = 0; id < gpL.count(); id++)
2279 		{
2280 			PageItem* cItem = gpL.at(id);
2281 			isTableIt = cItem->isTableItem;
2282 			cItem->gXpos = cItem->xPos() - gItem->xPos();
2283 			cItem->gYpos = cItem->yPos() - gItem->yPos();
2284 			cItem->Parent = gItem;
2285 			if (gItem->rotation() != 0)
2286 			{
2287 				QTransform ma;
2288 				ma.rotate(-gItem->rotation());
2289 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
2290 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
2291 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
2292 				cItem->setRotation(cItem->rotation() - gItem->rotation());
2293 				cItem->oldRot = cItem->rotation();
2294 			}
2295 			m_Doc->MasterItems.removeOne(cItem);
2296 		}
2297 		bool converted = false;
2298 		if (isTableIt)
2299 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
2300 		if (!converted)
2301 			gItem->groupItemList = gpL;
2302 	}
2303 
2304 	//update names to pointers
2305 	updateNames2Ptr();
2306 
2307 	// reestablish first/lastAuto
2308 	m_Doc->FirstAuto = m_Doc->LastAuto;
2309 	if (m_Doc->LastAuto)
2310 	{
2311 		while (m_Doc->LastAuto->nextInChain())
2312 			m_Doc->LastAuto = m_Doc->LastAuto->nextInChain();
2313 		while (m_Doc->FirstAuto->prevInChain())
2314 			m_Doc->FirstAuto = m_Doc->FirstAuto->prevInChain();
2315 	}
2316 
2317 	// start auto save timer if needed
2318 	if (m_Doc->autoSave() && ScCore->usingGUI())
2319 		m_Doc->restartAutoSaveTimer();
2320 //	m_Doc->autoSaveTimer->start(m_Doc->autoSaveTime());
2321 
2322 	if (m_mwProgressBar!=nullptr)
2323 		m_mwProgressBar->setValue(reader.characterOffset());
2324 	return true;
2325 }
2326 
2327 // Low level plugin API
scribus150format_getPluginAPIVersion()2328 int scribus150format_getPluginAPIVersion()
2329 {
2330 	return PLUGIN_API_VERSION;
2331 }
2332 
scribus150format_getPlugin()2333 ScPlugin* scribus150format_getPlugin()
2334 {
2335 	Scribus150Format* plug = new Scribus150Format();
2336 	Q_CHECK_PTR(plug);
2337 	return plug;
2338 }
2339 
scribus150format_freePlugin(ScPlugin * plugin)2340 void scribus150format_freePlugin(ScPlugin* plugin)
2341 {
2342 	Scribus150Format* plug = qobject_cast<Scribus150Format*>(plugin);
2343 	Q_ASSERT(plug);
2344 	delete plug;
2345 }
2346 
2347 
2348 namespace {
2349 	const int NOVALUE = -16000;
2350 
fixLegacyCharStyle(CharStyle & cstyle)2351 	void fixLegacyCharStyle(CharStyle& cstyle)
2352 	{
2353 		if (! cstyle.font().usable())
2354 			cstyle.resetFont();
2355 		if (cstyle.fontSize() <= NOVALUE / 10)
2356 			cstyle.resetFontSize();
2357 //		if (cstyle.effects() == 65535)
2358 //			cstyle.resetEffects();
2359 		if (cstyle.fillColor().isEmpty())
2360 			cstyle.resetFillColor();
2361 		if (cstyle.fillShade() <= NOVALUE)
2362 			cstyle.resetFillShade();
2363 		if (cstyle.strokeColor().isEmpty())
2364 			cstyle.resetStrokeColor();
2365 		if (cstyle.strokeShade() <= NOVALUE)
2366 			cstyle.resetStrokeShade();
2367 		if (cstyle.shadowXOffset() <= NOVALUE / 10)
2368 			cstyle.resetShadowXOffset();
2369 		if (cstyle.shadowYOffset() <= NOVALUE / 10)
2370 			cstyle.resetShadowYOffset();
2371 		if (cstyle.outlineWidth() <= NOVALUE / 10)
2372 			cstyle.resetOutlineWidth();
2373 		if (cstyle.underlineOffset() <= NOVALUE / 10)
2374 			cstyle.resetUnderlineOffset();
2375 		if (cstyle.underlineWidth() <= NOVALUE / 10)
2376 			cstyle.resetUnderlineWidth();
2377 		if (cstyle.strikethruOffset() <= NOVALUE / 10)
2378 			cstyle.resetStrikethruOffset();
2379 		if (cstyle.strikethruWidth() <= NOVALUE / 10)
2380 			cstyle.resetStrikethruWidth();
2381 		if (cstyle.scaleH() <= NOVALUE / 10)
2382 			cstyle.resetScaleH();
2383 		if (cstyle.scaleV() <= NOVALUE / 10)
2384 			cstyle.resetScaleV();
2385 		if (cstyle.baselineOffset() <= NOVALUE / 10)
2386 			cstyle.resetBaselineOffset();
2387 		if (cstyle.tracking() <= NOVALUE / 10)
2388 			cstyle.resetTracking();
2389 	}
2390 
fixLegacyParStyle(ParagraphStyle & pstyle)2391 	void fixLegacyParStyle(ParagraphStyle& pstyle)
2392 	{
2393 		if (pstyle.lineSpacing() <= NOVALUE)
2394 			pstyle.resetLineSpacing();
2395 		if (pstyle.leftMargin() <= NOVALUE)
2396 			pstyle.resetLeftMargin();
2397 		if (pstyle.rightMargin() <= NOVALUE)
2398 			pstyle.resetRightMargin();
2399 		if (pstyle.firstIndent() <= NOVALUE)
2400 			pstyle.resetFirstIndent();
2401 		if (pstyle.alignment() < 0)
2402 			pstyle.resetAlignment();
2403 		if (pstyle.gapBefore() <= NOVALUE)
2404 			pstyle.resetGapBefore();
2405 		if (pstyle.gapAfter() <= NOVALUE)
2406 			pstyle.resetGapAfter();
2407 		if (pstyle.dropCapLines() < 0)
2408 			pstyle.resetDropCapLines();
2409 		if (pstyle.parEffectOffset() <= NOVALUE)
2410 			pstyle.resetParEffectOffset();
2411 		fixLegacyCharStyle(pstyle.charStyle());
2412 	}
2413 
2414 }// namespace
2415 
readDocAttributes(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2416 void Scribus150Format::readDocAttributes(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2417 {
2418 	m_Doc->setPageSize(attrs.valueAsString("PAGESIZE"));
2419 	m_Doc->setPageOrientation(attrs.valueAsInt("ORIENTATION", 0));
2420 	m_Doc->FirstPnum  = attrs.valueAsInt("FIRSTNUM", 1);
2421 	m_Doc->setPagePositioning(attrs.valueAsInt("BOOK", 0));
2422 
2423 	m_Doc->setUsesAutomaticTextFrames( attrs.valueAsInt("AUTOTEXT") );
2424 	m_Doc->PageSp  = attrs.valueAsInt("AUTOSPALTEN");
2425 	m_Doc->PageSpa = attrs.valueAsDouble("ABSTSPALTEN");
2426 	m_Doc->setUnitIndex( attrs.valueAsInt("UNITS", 0) );
2427 
2428 	static const QString LANGUAGE("LANGUAGE");
2429 	if (attrs.hasAttribute(LANGUAGE))
2430 	{
2431 		QString l(attrs.valueAsString(LANGUAGE));
2432 		if (LanguageManager::instance()->langTableIndex(l) != -1)
2433 			m_Doc->setLanguage(l); //new style storage
2434 		else
2435 		{ //old style storage
2436 			QString lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
2437 			if (lnew.isEmpty())
2438 				lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
2439 			m_Doc->setLanguage(lnew);
2440 		}
2441 	}
2442 
2443 	if (attrs.hasAttribute("PAGEWIDTH"))
2444 		m_Doc->setPageWidth(attrs.valueAsDouble("PAGEWIDTH"));
2445 	else
2446 		m_Doc->setPageWidth(attrs.valueAsDouble("PAGEWITH"));
2447 	m_Doc->setPageHeight(attrs.valueAsDouble("PAGEHEIGHT"));
2448 	m_Doc->margins()->setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
2449 	m_Doc->margins()->setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
2450 	m_Doc->margins()->setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
2451 	m_Doc->margins()->setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
2452 	m_Doc->setMarginPreset(attrs.valueAsInt("PRESET", 0));
2453 	m_Doc->bleeds()->setTop(attrs.valueAsDouble("BleedTop", 0.0));
2454 	m_Doc->bleeds()->setLeft(attrs.valueAsDouble("BleedLeft", 0.0));
2455 	m_Doc->bleeds()->setRight(attrs.valueAsDouble("BleedRight", 0.0));
2456 	m_Doc->bleeds()->setBottom(attrs.valueAsDouble("BleedBottom", 0.0));
2457 	m_Doc->setHyphAutomatic(attrs.valueAsBool("AUTOMATIC", true));
2458 	m_Doc->setHyphAutoCheck(attrs.valueAsBool("AUTOCHECK", false));
2459 	m_Doc->GuideLock = attrs.valueAsBool("GUIDELOCK", false);
2460 
2461 	m_Doc->rulerXoffset = attrs.valueAsDouble("rulerXoffset", 0.0);
2462 	m_Doc->rulerYoffset = attrs.valueAsDouble("rulerYoffset", 0.0);
2463 	m_Doc->SnapGuides   = attrs.valueAsBool("SnapToGuides", false);
2464 	m_Doc->SnapElement  = attrs.valueAsBool("SnapToElement", false);
2465 	m_Doc->SnapGrid     = attrs.valueAsBool("SnapToGrid", false);
2466 
2467 	m_Doc->setAutoSave(attrs.valueAsBool("AutoSave", false));
2468 	m_Doc->setAutoSaveTime(attrs.valueAsInt("AutoSaveTime", 600000));
2469 	m_Doc->setAutoSaveKeep(attrs.valueAsBool("AutoSaveKeep", false));
2470 	m_Doc->setAutoSaveCount(attrs.valueAsInt("AutoSaveCount", 1));
2471 	m_Doc->setAutoSaveInDocDir(attrs.valueAsBool("AUtoSaveInDocDir", true));
2472 	m_Doc->setAutoSaveDir(attrs.valueAsString("AutoSaveDir", ""));
2473 	double leftScratch;
2474 	// FIXME A typo in early 1.3cvs (MAR 05) means we must support loading of
2475 	// FIXME 'ScatchLeft' for a while too. This can be removed in a few months.
2476 	if (attrs.hasAttribute("ScatchLeft"))
2477 		leftScratch = attrs.valueAsDouble("ScatchLeft", 100.0);
2478 	else
2479 		leftScratch = attrs.valueAsDouble("ScratchLeft", 100.0);
2480 	m_Doc->scratch()->set(attrs.valueAsDouble("ScratchTop", 20.0), leftScratch,
2481 						  attrs.valueAsDouble("ScratchBottom", 20.0),attrs.valueAsDouble("ScratchRight", 100.0));
2482 	m_Doc->setPageGapHorizontal(attrs.valueAsDouble("GapHorizontal", -1.0));
2483 	m_Doc->setPageGapVertical(attrs.valueAsDouble("GapVertical", -1.0));
2484 
2485 	if (attrs.hasAttribute("PAGEC"))
2486 		m_Doc->setPaperColor(QColor(attrs.valueAsString("PAGEC")));
2487 		//->Prefs m_Doc->papColor = QColor(attrs.valueAsString("PAGEC"));
2488 
2489 	m_Doc->setMarginColored(attrs.valueAsBool("RANDF", false));
2490 
2491 	readCMSSettings(doc, attrs);
2492 	readDocumentInfo(doc, attrs);
2493 	readGuideSettings(doc, attrs);
2494 	readToolSettings(doc, attrs);
2495 	readTypographicSettings(doc, attrs);
2496 }
2497 
readCMSSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2498 void Scribus150Format::readCMSSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2499 {
2500 	doc->cmsSettings().SoftProofOn     = attrs.valueAsBool("DPSo", false);
2501 	doc->cmsSettings().SoftProofFullOn = attrs.valueAsBool("DPSFo", false);
2502 	doc->cmsSettings().CMSinUse   = attrs.valueAsBool("DPuse", false);
2503 	doc->cmsSettings().GamutCheck = attrs.valueAsBool("DPgam", false);
2504 	doc->cmsSettings().BlackPoint = attrs.valueAsBool("DPbla", true);
2505 	doc->cmsSettings().DefaultMonitorProfile   = PrefsManager::instance().appPrefs.colorPrefs.DCMSset.DefaultMonitorProfile;
2506 	doc->cmsSettings().DefaultPrinterProfile   = attrs.valueAsString("DPPr","");
2507 	doc->cmsSettings().DefaultImageRGBProfile  = attrs.valueAsString("DPIn","");
2508 	doc->cmsSettings().DefaultImageCMYKProfile = attrs.valueAsString("DPInCMYK","");
2509 	doc->cmsSettings().DefaultSolidColorRGBProfile = attrs.valueAsString("DPIn2","");
2510 	if (attrs.hasAttribute("DPIn3"))
2511 		doc->cmsSettings().DefaultSolidColorCMYKProfile = attrs.valueAsString("DPIn3","");
2512 	else
2513 		doc->cmsSettings().DefaultSolidColorCMYKProfile = attrs.valueAsString("DPPr","");
2514 	doc->cmsSettings().DefaultIntentColors = (eRenderIntent) attrs.valueAsInt("DISc", 1);
2515 	doc->cmsSettings().DefaultIntentImages = (eRenderIntent) attrs.valueAsInt("DIIm", 0);
2516 }
2517 
readDocumentInfo(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2518 void Scribus150Format::readDocumentInfo(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2519 {
2520 	DocumentInformation di;
2521 	di.setAuthor(attrs.valueAsString("AUTHOR"));
2522 	di.setComments(attrs.valueAsString("COMMENTS"));
2523 	di.setKeywords(attrs.valueAsString("KEYWORDS",""));
2524 	di.setTitle(attrs.valueAsString("TITLE"));
2525 	di.setSubject(attrs.valueAsString("SUBJECT"));
2526 	di.setPublisher(attrs.valueAsString("PUBLISHER", ""));
2527 	di.setDate(attrs.valueAsString("DOCDATE", ""));
2528 	di.setType(attrs.valueAsString("DOCTYPE", ""));
2529 	di.setFormat(attrs.valueAsString("DOCFORMAT", ""));
2530 	di.setIdent(attrs.valueAsString("DOCIDENT", ""));
2531 	di.setSource(attrs.valueAsString("DOCSOURCE", ""));
2532 	di.setLangInfo(attrs.valueAsString("DOCLANGINFO", ""));
2533 	di.setRelation(attrs.valueAsString("DOCRELATION", ""));
2534 	di.setCover(attrs.valueAsString("DOCCOVER", ""));
2535 	di.setRights(attrs.valueAsString("DOCRIGHTS", ""));
2536 	di.setContrib(attrs.valueAsString("DOCCONTRIB", ""));
2537 	doc->setDocumentInfo(di);
2538 }
2539 
readGuideSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2540 void Scribus150Format::readGuideSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2541 {
2542 	PrefsManager& prefsManager = PrefsManager::instance();
2543 	doc->guidesPrefs().minorGridSpacing = attrs.valueAsDouble("MINGRID", prefsManager.appPrefs.guidesPrefs.minorGridSpacing);
2544 	doc->guidesPrefs().majorGridSpacing = attrs.valueAsDouble("MAJGRID", prefsManager.appPrefs.guidesPrefs.majorGridSpacing);
2545 	doc->guidesPrefs().gridShown    = attrs.valueAsBool("SHOWGRID", false);
2546 	doc->guidesPrefs().guidesShown  =attrs.valueAsBool("SHOWGUIDES", true);
2547 	doc->guidesPrefs().colBordersShown  = attrs.valueAsBool("showcolborders", false);
2548 	doc->guidesPrefs().framesShown  = attrs.valueAsBool("SHOWFRAME", true);
2549 	doc->guidesPrefs().layerMarkersShown = attrs.valueAsBool("SHOWLAYERM", false);
2550 	doc->guidesPrefs().marginsShown = attrs.valueAsBool("SHOWMARGIN", true);
2551 	doc->guidesPrefs().baselineGridShown    = attrs.valueAsBool("SHOWBASE", false);
2552 	doc->guidesPrefs().showPic      = attrs.valueAsBool("SHOWPICT", true);
2553 	doc->guidesPrefs().linkShown    = attrs.valueAsBool("SHOWLINK", false);
2554 	doc->guidesPrefs().showControls = attrs.valueAsBool("SHOWControl", false);
2555 	doc->guidesPrefs().rulerMode    = attrs.valueAsBool("rulerMode", true);
2556 	doc->guidesPrefs().rulersShown  = attrs.valueAsBool("showrulers", true);
2557 	doc->guidesPrefs().showBleed    = attrs.valueAsBool("showBleed", true);
2558 	m_Doc->drawAsPreview		    = false /*attrs.valueAsBool("previewMode", false)*/;
2559 	if (attrs.hasAttribute("MARGC"))
2560 		doc->guidesPrefs().marginColor  = QColor(attrs.valueAsString("MARGC"));
2561 	if (attrs.hasAttribute("MINORC"))
2562 		doc->guidesPrefs().minorGridColor = QColor(attrs.valueAsString("MINORC"));
2563 	if (attrs.hasAttribute("MAJORC"))
2564 		doc->guidesPrefs().majorGridColor = QColor(attrs.valueAsString("MAJORC"));
2565 	if (attrs.hasAttribute("GuideC"))
2566 		doc->guidesPrefs().guideColor = QColor(attrs.valueAsString("GuideC"));
2567 	if (attrs.hasAttribute("BaseC"))
2568 		doc->guidesPrefs().baselineGridColor  = QColor(attrs.valueAsString("BaseC"));
2569 	if (attrs.hasAttribute("BACKG"))
2570 	{
2571 		doc->guidesPrefs().renderStackOrder.clear();
2572 		if (attrs.valueAsBool("BACKG", true))
2573 			doc->guidesPrefs().renderStackOrder << 0 << 1 << 2 << 3 << 4;
2574 		else
2575 			doc->guidesPrefs().renderStackOrder << 4 << 0 << 1 << 2 << 3;
2576 	}
2577 	if (attrs.hasAttribute("renderStack"))
2578 	{
2579 		doc->guidesPrefs().renderStackOrder.clear();
2580 		QString renderStack = attrs.valueAsString("renderStack", "0 1 2 3 4");
2581 		ScTextStream fp(&renderStack, QIODevice::ReadOnly);
2582 		QString val;
2583 		while (!fp.atEnd())
2584 		{
2585 			fp >> val;
2586 			doc->guidesPrefs().renderStackOrder << val.toInt();
2587 		}
2588 	}
2589 	doc->guidesPrefs().gridType = attrs.valueAsInt("GridType", 0);
2590 	doc->guidesPrefs().guideRad = attrs.valueAsDouble("GuideRad", 10.0);
2591 	doc->guidesPrefs().grabRadius  = attrs.valueAsInt("GRAB", 4);
2592 }
2593 
readToolSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2594 void Scribus150Format::readToolSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2595 {
2596 	const ItemToolPrefs& defToolPrefs = PrefsManager::instance().appPrefs.itemToolPrefs;
2597 
2598 	QString textFont = attrs.valueAsString("DFONT");
2599 	m_AvailableFonts->findFont(textFont, doc);
2600 
2601 	doc->itemToolPrefs().textFont = textFont;
2602 	doc->itemToolPrefs().textSize = qRound(attrs.valueAsDouble("DSIZE", 12.0) * 10);
2603 	doc->itemToolPrefs().textColumns   = attrs.valueAsInt("DCOL", 1);
2604 	doc->itemToolPrefs().textColumnGap    = attrs.valueAsDouble("DGAP", 0.0);
2605 
2606 	const MarginStruct& defDistances = defToolPrefs.textDistances;
2607 	doc->itemToolPrefs().textDistances.setLeft(attrs.valueAsDouble("TextDistLeft", defDistances.left()));
2608 	doc->itemToolPrefs().textDistances.setRight(attrs.valueAsDouble("TextDistRight", defDistances.right()));
2609 	doc->itemToolPrefs().textDistances.setBottom(attrs.valueAsDouble("TextDistBottom", defDistances.bottom()));
2610 	doc->itemToolPrefs().textDistances.setTop(attrs.valueAsDouble("TextDistTop", defDistances.top()));
2611 
2612 	doc->itemToolPrefs().polyCorners      = attrs.valueAsInt("POLYC", 4);
2613 	doc->itemToolPrefs().polyFactor = attrs.valueAsDouble("POLYF", 0.5);
2614 	doc->itemToolPrefs().polyRotation     = attrs.valueAsDouble("POLYR", 0.0);
2615 	doc->itemToolPrefs().polyInnerRot     = attrs.valueAsDouble("POLYIR", 0.0);
2616 	doc->itemToolPrefs().polyCurvature    = attrs.valueAsDouble("POLYCUR", 0.0);
2617 	doc->itemToolPrefs().polyOuterCurvature    = attrs.valueAsDouble("POLYOCUR", 0.0);
2618 	doc->itemToolPrefs().polyUseFactor    = attrs.valueAsBool("POLYS", false);
2619 
2620 	doc->itemToolPrefs().arcStartAngle = attrs.valueAsDouble("arcStartAngle", 30.0);
2621 	doc->itemToolPrefs().arcSweepAngle = attrs.valueAsDouble("arcSweepAngle", 300.0);
2622 	doc->itemToolPrefs().spiralStartAngle = attrs.valueAsDouble("spiralStartAngle", 0.0);
2623 	doc->itemToolPrefs().spiralEndAngle = attrs.valueAsDouble("spiralEndAngle", 1080.0);
2624 	doc->itemToolPrefs().spiralFactor = attrs.valueAsDouble("spiralFactor", 1.2);
2625 
2626 	doc->itemToolPrefs().lineStartArrow = attrs.valueAsInt("StartArrow", 0);
2627 	doc->itemToolPrefs().lineEndArrow   = attrs.valueAsInt("EndArrow", 0);
2628 	doc->itemToolPrefs().imageScaleX      = attrs.valueAsDouble("PICTSCX", 1.0);
2629 	doc->itemToolPrefs().imageScaleY      = attrs.valueAsDouble("PICTSCY", 1.0);
2630 	doc->itemToolPrefs().imageScaleType   = attrs.valueAsBool("PSCALE", true);
2631 	doc->itemToolPrefs().imageAspectRatio = attrs.valueAsBool("PASPECT", false);
2632 	doc->itemToolPrefs().imageLowResType  = attrs.valueAsInt("HalfRes", 1);
2633 	doc->itemToolPrefs().imageUseEmbeddedPath = attrs.valueAsBool("EmbeddedPath", false);
2634 	if (attrs.hasAttribute("PEN"))
2635 		doc->itemToolPrefs().shapeLineColor = attrs.valueAsString("PEN");
2636 	if (attrs.hasAttribute("BRUSH"))
2637 		doc->itemToolPrefs().shapeFillColor = attrs.valueAsString("BRUSH");
2638 	if (attrs.hasAttribute("PENLINE"))
2639 		doc->itemToolPrefs().lineColor = attrs.valueAsString("PENLINE");
2640 	if (attrs.hasAttribute("PENTEXT"))
2641 		doc->itemToolPrefs().textColor = attrs.valueAsString("PENTEXT");
2642 	if (attrs.hasAttribute("StrokeText"))
2643 		doc->itemToolPrefs().textStrokeColor = attrs.valueAsString("StrokeText");
2644 	doc->itemToolPrefs().textFillColor  = attrs.valueAsString("TextBackGround", CommonStrings::None);
2645 	doc->itemToolPrefs().textLineColor   = attrs.valueAsString("TextLineColor", CommonStrings::None);
2646 	doc->itemToolPrefs().textFillColorShade =attrs.valueAsInt("TextBackGroundShade", 100);
2647 	doc->itemToolPrefs().textLineColorShade   = attrs.valueAsInt("TextLineShade", 100);
2648 	doc->itemToolPrefs().textShade    = attrs.valueAsInt("TextPenShade", 100);
2649 	doc->itemToolPrefs().textStrokeShade = attrs.valueAsInt("TextStrokeShade", 100);
2650 	doc->itemToolPrefs().shapeLineStyle    = static_cast<Qt::PenStyle>(attrs.valueAsInt("STIL"));
2651 	doc->itemToolPrefs().lineStyle = static_cast<Qt::PenStyle>(attrs.valueAsInt("STILLINE"));
2652 	doc->itemToolPrefs().shapeLineWidth      = attrs.valueAsDouble("WIDTH", 0.0);
2653 	doc->itemToolPrefs().lineWidth  = attrs.valueAsDouble("WIDTHLINE", 1.0);
2654 	doc->itemToolPrefs().shapeLineColorShade     = attrs.valueAsInt("PENSHADE", 100);
2655 	doc->itemToolPrefs().lineColorShade  = attrs.valueAsInt("LINESHADE", 100);
2656 	doc->itemToolPrefs().shapeFillColorShade      = attrs.valueAsInt("BRUSHSHADE", 100);
2657 	doc->itemToolPrefs().calligraphicPenFillColor = attrs.valueAsString("calligraphicPenFillColor", "Black");
2658 	doc->itemToolPrefs().calligraphicPenLineColor = attrs.valueAsString("calligraphicPenLineColor", "Black");
2659 	doc->itemToolPrefs().calligraphicPenFillColorShade = attrs.valueAsInt("calligraphicPenFillColorShade", 100);
2660 	doc->itemToolPrefs().calligraphicPenLineColorShade = attrs.valueAsInt("calligraphicPenLineColorShade", 100);
2661 	doc->itemToolPrefs().calligraphicPenLineWidth = attrs.valueAsDouble("calligraphicPenLineWidth", 1.0);
2662 	doc->itemToolPrefs().calligraphicPenAngle = attrs.valueAsDouble("calligraphicPenAngle", 0.0);
2663 	doc->itemToolPrefs().calligraphicPenWidth = attrs.valueAsDouble("calligraphicPenWidth", 10.0);
2664 	doc->itemToolPrefs().calligraphicPenStyle = static_cast<Qt::PenStyle>(attrs.valueAsInt("calligraphicPenStyle"));
2665 	doc->opToolPrefs().dispX       = attrs.valueAsDouble("dispX", 10.0);
2666 	doc->opToolPrefs().dispY       = attrs.valueAsDouble("dispY", 10.0);
2667 	doc->opToolPrefs().constrain   = attrs.valueAsDouble("constrain", 15.0);
2668 	doc->itemToolPrefs().textTabFillChar = attrs.valueAsString("TabFill","");
2669 	doc->itemToolPrefs().textTabWidth   = attrs.valueAsDouble("TabWidth", 36.0);
2670 	doc->itemToolPrefs().firstLineOffset = (FirstLineOffsetPolicy) attrs.valueAsInt("FirstLineOffset", (int) FLOPRealGlyphHeight); // Default to FLOPRealGlyphHeight for legacy docs
2671 	doc->itemToolPrefs().firstLineOffset = qMax(FLOPRealGlyphHeight, qMin(doc->itemToolPrefs().firstLineOffset, FLOPBaselineGrid));
2672 	if (attrs.hasAttribute("CPICT"))
2673 		doc->itemToolPrefs().imageFillColor = attrs.valueAsString("CPICT");
2674 	doc->itemToolPrefs().imageFillColorShade = attrs.valueAsInt("PICTSHADE", 100);
2675 	if (attrs.hasAttribute("CSPICT"))
2676 		doc->itemToolPrefs().imageStrokeColor = attrs.valueAsString("CSPICT");
2677 	doc->itemToolPrefs().imageStrokeColorShade = attrs.valueAsInt("PICTSSHADE", 100);
2678 }
2679 
readTypographicSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2680 void Scribus150Format::readTypographicSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2681 {
2682 	doc->typographicPrefs().valueSuperScript   = attrs.valueAsInt("VHOCH");
2683 	doc->typographicPrefs().scalingSuperScript = attrs.valueAsInt("VHOCHSC");
2684 	doc->typographicPrefs().valueSubScript     = attrs.valueAsInt("VTIEF");
2685 	doc->typographicPrefs().scalingSubScript   = attrs.valueAsInt("VTIEFSC");
2686 	doc->typographicPrefs().valueSmallCaps     = attrs.valueAsInt("VKAPIT");
2687 	doc->guidesPrefs().valueBaselineGrid      = attrs.valueAsDouble("BASEGRID", 12.0);
2688 	doc->guidesPrefs().offsetBaselineGrid     = attrs.valueAsDouble("BASEO", 0.0);
2689 	// #9621 : autolinespacing is now expressed as a percentage of the font height
2690 	doc->typographicPrefs().autoLineSpacing    = attrs.valueAsInt("AUTOL", 1, 500, 100);
2691 	doc->typographicPrefs().valueUnderlinePos  = attrs.valueAsInt("UnderlinePos", -1);
2692 	doc->typographicPrefs().valueUnderlineWidth  = attrs.valueAsInt("UnderlineWidth", -1);
2693 	doc->typographicPrefs().valueStrikeThruPos   = attrs.valueAsInt("StrikeThruPos", -1);
2694 	doc->typographicPrefs().valueStrikeThruWidth = attrs.valueAsInt("StrikeThruWidth", -1);
2695 }
2696 
readPageSets(ScribusDoc * doc,ScXmlStreamReader & reader)2697 bool Scribus150Format::readPageSets(ScribusDoc* doc, ScXmlStreamReader& reader)
2698 {
2699 	struct PageSet pageS;
2700 	ScXmlStreamAttributes attrs;
2701 
2702 	doc->clearPageSets();
2703 	while (!reader.atEnd() && !reader.hasError())
2704 	{
2705 		reader.readNext();
2706 		QStringRef tagName = reader.name();
2707 		if (reader.isStartElement())
2708 			attrs = reader.attributes();
2709 		if (reader.isEndElement() && tagName == "PageSets")
2710 			break;
2711 		if (reader.isStartElement() && tagName == "Set")
2712 		{
2713 			ScXmlStreamAttributes attrs = reader.scAttributes();
2714 			pageS.Name      = CommonStrings::untranslatePageSetString(attrs.valueAsString("Name"));
2715 			pageS.FirstPage = attrs.valueAsInt("FirstPage", 0);
2716 			pageS.Rows      = attrs.valueAsInt("Rows", 1);
2717 			pageS.Columns   = attrs.valueAsInt("Columns", 1);
2718 //			pageS.GapHorizontal = attrs.valueAsDouble("GapHorizontal", 0);
2719 //			pageS.GapVertical   = attrs.valueAsDouble("GapVertical", 0);
2720 //			pageS.GapBelow      = attrs.valueAsDouble("GapBelow", 0);
2721 			pageS.pageNames.clear();
2722 		}
2723 		if (reader.isEndElement() && tagName == "Set")
2724 		{
2725 //			doc->pageSets.append(pageS);
2726 			doc->appendToPageSets(pageS);
2727 			if ((doc->pageSets().count()-1 == doc->pagePositioning()) && ((doc->pageGapHorizontal() < 0) && (doc->pageGapVertical() < 0)))
2728 			{
2729 				doc->setPageGapHorizontal(attrs.valueAsDouble("GapHorizontal", 0.0));
2730 				doc->setPageGapVertical(attrs.valueAsDouble("GapBelow", 0.0));
2731 			}
2732 		}
2733 		if (reader.isStartElement() && tagName == "PageNames")
2734 			pageS.pageNames.append(CommonStrings::untranslatePageSetLocString(attrs.valueAsString("Name")));
2735 	}
2736 	return !reader.hasError();
2737 }
2738 
readCheckProfile(ScribusDoc * doc,ScXmlStreamAttributes & attrs)2739 bool Scribus150Format::readCheckProfile(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
2740 {
2741 	struct CheckerPrefs checkerSettings;
2742 
2743 	QString profileName = attrs.valueAsString("Name");
2744 	if (profileName.isEmpty())
2745 		return true;
2746 	checkerSettings.ignoreErrors      = attrs.valueAsBool("ignoreErrors", false);
2747 	checkerSettings.autoCheck         = attrs.valueAsBool("autoCheck", true);
2748 	checkerSettings.checkGlyphs       = attrs.valueAsBool("checkGlyphs", true);
2749 	checkerSettings.checkOrphans      = attrs.valueAsBool("checkOrphans", true);
2750 	checkerSettings.checkOverflow     = attrs.valueAsBool("checkOverflow", true);
2751 	checkerSettings.checkPictures     = attrs.valueAsBool("checkPictures", true);
2752 	checkerSettings.checkPartFilledImageFrames = attrs.valueAsBool("checkPartFilledImageFrames", false);
2753 	checkerSettings.checkResolution   = attrs.valueAsBool("checkResolution", true);
2754 	checkerSettings.checkTransparency = attrs.valueAsBool("checkTransparency", true);
2755 	checkerSettings.minResolution     = attrs.valueAsDouble("minResolution", 72.0);
2756 	checkerSettings.maxResolution     = attrs.valueAsDouble("maxResolution", 4800.0);
2757 	checkerSettings.checkAnnotations  = attrs.valueAsBool("checkAnnotations", false);
2758 	checkerSettings.checkRasterPDF    = attrs.valueAsBool("checkRasterPDF", true);
2759 	checkerSettings.checkForGIF       = attrs.valueAsBool("checkForGIF", true);
2760 	checkerSettings.ignoreOffLayers   = attrs.valueAsBool("ignoreOffLayers", false);
2761 	checkerSettings.checkNotCMYKOrSpot   = attrs.valueAsBool("checkNotCMYKOrSpot", false);
2762 	checkerSettings.checkDeviceColorsAndOutputIntent = attrs.valueAsBool("checkDeviceColorsAndOutputIntent", false);
2763 	checkerSettings.checkFontNotEmbedded = attrs.valueAsBool("checkFontNotEmbedded", false);
2764 	checkerSettings.checkFontIsOpenType  = attrs.valueAsBool("checkFontIsOpenType", false);
2765 	checkerSettings.checkAppliedMasterDifferentSide  = attrs.valueAsBool("checkAppliedMasterDifferentSide", true);
2766 	checkerSettings.checkEmptyTextFrames     = attrs.valueAsBool("checkEmptyTextFrames", true);
2767 	doc->set1CheckerProfile(profileName, checkerSettings);
2768 	return true;
2769 }
2770 
readColor(ColorList & colors,ScXmlStreamAttributes & attrs)2771 void Scribus150Format::readColor(ColorList& colors, ScXmlStreamAttributes& attrs)
2772 {
2773 	ScColor color;
2774 	if (attrs.hasAttribute("SPACE"))
2775 	{
2776 		QString space = attrs.valueAsString("SPACE");
2777 		if (space == "CMYK")
2778 		{
2779 			double c = attrs.valueAsDouble("C", 0) / 100.0;
2780 			double m = attrs.valueAsDouble("M", 0) / 100.0;
2781 			double y = attrs.valueAsDouble("Y", 0) / 100.0;
2782 			double k = attrs.valueAsDouble("K", 0) / 100.0;
2783 			color.setCmykColorF(c, m, y, k);
2784 		}
2785 		else if (space == "RGB")
2786 		{
2787 			double r = attrs.valueAsDouble("R", 0) / 255.0;
2788 			double g = attrs.valueAsDouble("G", 0) / 255.0;
2789 			double b = attrs.valueAsDouble("B", 0) / 255.0;
2790 			color.setRgbColorF(r, g, b);
2791 		}
2792 		else if (space == "Lab")
2793 		{
2794 			double L = attrs.valueAsDouble("L", 0);
2795 			double a = attrs.valueAsDouble("A", 0);
2796 			double b = attrs.valueAsDouble("B", 0);
2797 			color.setLabColor(L, a, b);
2798 		}
2799 	}
2800 	else if (attrs.hasAttribute("CMYK"))
2801 		color.setNamedColor(attrs.valueAsString("CMYK"));
2802 	else if (attrs.hasAttribute("RGB"))
2803 		color.fromQColor(QColor(attrs.valueAsString("RGB")));
2804 	else
2805 	{
2806 		double L = attrs.valueAsDouble("L", 0);
2807 		double a = attrs.valueAsDouble("A", 0);
2808 		double b = attrs.valueAsDouble("B", 0);
2809 		color.setLabColor(L, a, b);
2810 	}
2811 	color.setSpotColor( attrs.valueAsBool("Spot", false) );
2812 	color.setRegistrationColor( attrs.valueAsBool("Register", false) );
2813 	QString name(attrs.valueAsString("NAME", color.name()));
2814 	if (name == "All")
2815 	{
2816 		color.setSpotColor(true);
2817 		color.setRegistrationColor(true);
2818 		color.setCmykColorF(1.0, 1.0, 1.0, 1.0);
2819 	}
2820 	// #10323 : break loading of doc which contain colors with different names
2821 	// and same definition
2822 	// colors.tryAddColor(name, color);
2823 	if (name.length() > 0 && !colors.contains(name))
2824 		colors.insert(name, color);
2825 }
2826 
readGradient(ScribusDoc * doc,VGradient & gra,ScXmlStreamReader & reader)2827 bool Scribus150Format::readGradient(ScribusDoc *doc, VGradient &gra, ScXmlStreamReader& reader)
2828 {
2829 	gra = VGradient(VGradient::linear);
2830 	gra.clearStops();
2831 	ScXmlStreamAttributes rattrs = reader.scAttributes();
2832 	QStringRef tagName = reader.name();
2833 	while (!reader.atEnd() && !reader.hasError())
2834 	{
2835 		ScXmlStreamReader::TokenType tType = reader.readNext();
2836 		if (tType == ScXmlStreamReader::EndElement && reader.name() == tagName)
2837 			break;
2838 		if (tType == ScXmlStreamReader::StartElement && reader.name() == "CSTOP")
2839 		{
2840 			ScXmlStreamAttributes attrs = reader.scAttributes();
2841 			QString name = attrs.valueAsString("NAME");
2842 			double ramp  = attrs.valueAsDouble("RAMP", 0.0);
2843 			int shade    = attrs.valueAsInt("SHADE", 100);
2844 			double opa   = attrs.valueAsDouble("TRANS", 1.0);
2845 			gra.addStop(SetColor(doc, name, shade), ramp, 0.5, opa, name, shade);
2846 		}
2847 	}
2848 	return !reader.hasError();
2849 }
2850 
readCharacterStyleAttrs(ScribusDoc * doc,ScXmlStreamAttributes & attrs,CharStyle & newStyle)2851 void Scribus150Format::readCharacterStyleAttrs(ScribusDoc *doc, ScXmlStreamAttributes& attrs, CharStyle & newStyle)
2852 {
2853 	static const QString CPARENT("CPARENT");
2854 	if (attrs.hasAttribute(CPARENT))
2855 	{
2856 		QString parentStyle = attrs.valueAsString(CPARENT);
2857 		if (!parentStyle.isEmpty())
2858 			parentStyle = charStyleMap.value(parentStyle, parentStyle);
2859 		newStyle.setParent(parentStyle);
2860 	}
2861 
2862 	static const QString FONT("FONT");
2863 	if (attrs.hasAttribute(FONT))
2864 	{
2865 		const ScFace& face = m_AvailableFonts->findFont(attrs.valueAsString(FONT), doc);
2866 		if (!face.isNone())
2867 			newStyle.setFont(face);
2868 	}
2869 
2870 	static const QString FONTSIZE("FONTSIZE");
2871 	if (attrs.hasAttribute(FONTSIZE))
2872 		newStyle.setFontSize(qRound(attrs.valueAsDouble(FONTSIZE) * 10));
2873 
2874 	static const QString FONTFEATURES("FONTFEATURES");
2875 	if (attrs.hasAttribute(FONTFEATURES))
2876 		newStyle.setFontFeatures(attrs.valueAsString(FONTFEATURES));
2877 
2878 	static const QString FCOLOR("FCOLOR");
2879 	if (attrs.hasAttribute(FCOLOR))
2880 		newStyle.setFillColor(attrs.valueAsString(FCOLOR));
2881 
2882 	static const QString HyphenChar("HyphenChar");
2883 	if (attrs.hasAttribute(HyphenChar))
2884 		newStyle.setHyphenChar(attrs.valueAsInt(HyphenChar));
2885 
2886 	static const QString HyphenWordMin("HyphenWordMin");
2887 	if (attrs.hasAttribute(HyphenWordMin))
2888 		newStyle.setHyphenWordMin(attrs.valueAsInt(HyphenWordMin));
2889 
2890 	static const QString KERN("KERN");
2891 	if (attrs.hasAttribute(KERN))
2892 		newStyle.setTracking(qRound(attrs.valueAsDouble(KERN) * 10));
2893 
2894 	static const QString FSHADE("FSHADE");
2895 	if (attrs.hasAttribute(FSHADE))
2896 		newStyle.setFillShade(attrs.valueAsInt(FSHADE));
2897 
2898 	static const QString EFFECTS("EFFECTS");
2899 	if (attrs.hasAttribute(EFFECTS))
2900 		newStyle.setFeatures(static_cast<StyleFlag>(attrs.valueAsInt(EFFECTS)).featureList());
2901 
2902 	static const QString EFFECT("EFFECT");
2903 	if (attrs.hasAttribute(EFFECT))
2904 		newStyle.setFeatures(static_cast<StyleFlag>(attrs.valueAsInt(EFFECT)).featureList());
2905 
2906 	static const QString FEATURES("FEATURES");
2907 	if (attrs.hasAttribute(FEATURES))
2908 		newStyle.setFeatures(attrs.valueAsString(FEATURES).split( " ", Qt::SkipEmptyParts));
2909 
2910 	static const QString SCOLOR("SCOLOR");
2911 	if (attrs.hasAttribute(SCOLOR))
2912 		newStyle.setStrokeColor(attrs.valueAsString(SCOLOR, CommonStrings::None));
2913 
2914 	static const QString BCOLOR("BGCOLOR");
2915 	if (attrs.hasAttribute(BCOLOR))
2916 		newStyle.setBackColor(attrs.valueAsString(BCOLOR, CommonStrings::None));
2917 	static const QString BSHADE("BGSHADE");
2918 	if (attrs.hasAttribute(BSHADE))
2919 		newStyle.setBackShade(attrs.valueAsInt(BSHADE, 100));
2920 
2921 	static const QString SSHADE("SSHADE");
2922 	if (attrs.hasAttribute(SSHADE))
2923 		newStyle.setStrokeShade(attrs.valueAsInt(SSHADE));
2924 
2925 	static const QString SCALEH("SCALEH");
2926 	if (attrs.hasAttribute(SCALEH))
2927 		newStyle.setScaleH(qRound(attrs.valueAsDouble(SCALEH) * 10));
2928 
2929 	static const QString SCALEV("SCALEV");
2930 	if (attrs.hasAttribute(SCALEV))
2931 		newStyle.setScaleV(qRound(attrs.valueAsDouble(SCALEV) * 10));
2932 
2933 	static const QString BASEO("BASEO");
2934 	if (attrs.hasAttribute(BASEO))
2935 		newStyle.setBaselineOffset(qRound(attrs.valueAsDouble(BASEO) * 10));
2936 
2937 	static const QString TXTSHX("TXTSHX");
2938 	if (attrs.hasAttribute(TXTSHX))
2939 		newStyle.setShadowXOffset(qRound(attrs.valueAsDouble(TXTSHX) * 10));
2940 
2941 	static const QString TXTSHY("TXTSHY");
2942 	if (attrs.hasAttribute(TXTSHY))
2943 		newStyle.setShadowYOffset(qRound(attrs.valueAsDouble(TXTSHY) * 10));
2944 
2945 	static const QString TXTOUT("TXTOUT");
2946 	if (attrs.hasAttribute(TXTOUT))
2947 		newStyle.setOutlineWidth(qRound(attrs.valueAsDouble(TXTOUT) * 10));
2948 
2949 	static const QString TXTULP("TXTULP");
2950 	if (attrs.hasAttribute(TXTULP))
2951 		newStyle.setUnderlineOffset(qRound(attrs.valueAsDouble(TXTULP) * 10));
2952 
2953 	static const QString TXTULW("TXTULW");
2954 	if (attrs.hasAttribute(TXTULW))
2955 		newStyle.setUnderlineWidth(qRound(attrs.valueAsDouble(TXTULW) * 10));
2956 
2957 	static const QString TXTSTP("TXTSTP");
2958 	if (attrs.hasAttribute(TXTSTP))
2959 		newStyle.setStrikethruOffset(qRound(attrs.valueAsDouble(TXTSTP) * 10));
2960 
2961 	static const QString TXTSTW("TXTSTW");
2962 	if (attrs.hasAttribute(TXTSTW))
2963 		newStyle.setStrikethruWidth(qRound(attrs.valueAsDouble(TXTSTW) * 10));
2964 
2965 	static const QString LANGUAGE("LANGUAGE");
2966 	if (attrs.hasAttribute(LANGUAGE))
2967 	{
2968 		QString l(attrs.valueAsString(LANGUAGE));
2969 		if (LanguageManager::instance()->langTableIndex(l) != -1)
2970 			newStyle.setLanguage(l); //new style storage
2971 		else
2972 		{ //old style storage
2973 			QString lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
2974 			if (lnew.isEmpty())
2975 				lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
2976 			newStyle.setLanguage(lnew);
2977 		}
2978 	}
2979 
2980 	static const QString SHORTCUT("SHORTCUT");
2981 	if (attrs.hasAttribute(SHORTCUT))
2982 		newStyle.setShortcut(attrs.valueAsString(SHORTCUT));
2983 
2984 	static const QString WORDTRACK("wordTrack");
2985 	if (attrs.hasAttribute(WORDTRACK))
2986 		newStyle.setWordTracking(attrs.valueAsDouble(WORDTRACK));
2987 }
2988 
readNamedCharacterStyleAttrs(ScribusDoc * doc,ScXmlStreamAttributes & attrs,CharStyle & newStyle)2989 void Scribus150Format::readNamedCharacterStyleAttrs(ScribusDoc *doc, ScXmlStreamAttributes& attrs, CharStyle & newStyle)
2990 {
2991 	static const QString CNAME("CNAME");
2992 	if (attrs.hasAttribute(CNAME))
2993 		newStyle.setName(attrs.valueAsString(CNAME));
2994 
2995 	// The default style attribute must be correctly set before trying to assign a parent
2996 	static const QString DEFAULTSTYLE("DefaultStyle");
2997 	if (newStyle.hasName() && attrs.hasAttribute(DEFAULTSTYLE))
2998 		newStyle.setDefaultStyle(attrs.valueAsInt(DEFAULTSTYLE));
2999 	else if (newStyle.name() == CommonStrings::DefaultCharacterStyle || newStyle.name() == CommonStrings::trDefaultCharacterStyle)
3000 		newStyle.setDefaultStyle(true);
3001 	else
3002 		newStyle.setDefaultStyle(false);
3003 
3004 	readCharacterStyleAttrs(doc, attrs, newStyle);
3005 
3006 	// Check that a style is not its own parent
3007 	QString parentStyle = newStyle.parent();
3008 	if (parentStyle == newStyle.name())
3009 		newStyle.setParent(QString());
3010 }
3011 
readParagraphStyle(ScribusDoc * doc,ScXmlStreamReader & reader,ParagraphStyle & newStyle)3012 void Scribus150Format::readParagraphStyle(ScribusDoc *doc, ScXmlStreamReader& reader, ParagraphStyle& newStyle)
3013 {
3014 	ScXmlStreamAttributes attrs = reader.scAttributes();
3015 
3016 	newStyle.erase();
3017 	newStyle.setName(attrs.valueAsString("NAME", ""));
3018 	// The default style attribute must be correctly set before trying to assign a parent
3019 	static const QString DEFAULTSTYLE("DefaultStyle");
3020 	if (attrs.hasAttribute(DEFAULTSTYLE))
3021 		newStyle.setDefaultStyle(attrs.valueAsInt(DEFAULTSTYLE));
3022 	else if (newStyle.name() == CommonStrings::DefaultParagraphStyle || newStyle.name() == CommonStrings::trDefaultParagraphStyle)
3023 		newStyle.setDefaultStyle(true);
3024 	else
3025 		newStyle.setDefaultStyle(false);
3026 
3027 	QString parentStyle = attrs.valueAsString("PARENT", QString());
3028 	if (!parentStyle.isEmpty() && (parentStyle != newStyle.name()))
3029 	{
3030 		parentStyle = parStyleMap.value(parentStyle, parentStyle);
3031 		if (m_Doc->styleExists(parentStyle))
3032 			newStyle.setParent(parentStyle);
3033 		else
3034 			newStyle.setParent(CommonStrings::DefaultParagraphStyle);
3035 	}
3036 
3037 	static const QString LINESPMode("LINESPMode");
3038 	if (attrs.hasAttribute(LINESPMode))
3039 		newStyle.setLineSpacingMode(static_cast<ParagraphStyle::LineSpacingMode>(attrs.valueAsInt(LINESPMode)));
3040 
3041 	static const QString LINESP("LINESP");
3042 	if (attrs.hasAttribute(LINESP))
3043 		newStyle.setLineSpacing(attrs.valueAsDouble(LINESP));
3044 
3045 	static const QString INDENT("INDENT");
3046 	if (attrs.hasAttribute(INDENT))
3047 		newStyle.setLeftMargin(attrs.valueAsDouble(INDENT));
3048 
3049 	static const QString RMARGIN("RMARGIN");
3050 	if (attrs.hasAttribute(RMARGIN))
3051 		newStyle.setRightMargin(attrs.valueAsDouble(RMARGIN));
3052 
3053 	static const QString FIRST("FIRST");
3054 	if (attrs.hasAttribute(FIRST))
3055 		newStyle.setFirstIndent(attrs.valueAsDouble(FIRST));
3056 
3057 	static const QString ALIGN("ALIGN");
3058 	if (attrs.hasAttribute(ALIGN))
3059 		newStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(attrs.valueAsInt(ALIGN)));
3060 
3061 	static const QString DIRECTION("DIRECTION");
3062 	if (attrs.hasAttribute(DIRECTION))
3063 		newStyle.setDirection(static_cast<ParagraphStyle::DirectionType>(attrs.valueAsInt(DIRECTION)));
3064 
3065 	static const QString VOR("VOR");
3066 	if (attrs.hasAttribute(VOR))
3067 		newStyle.setGapBefore(attrs.valueAsDouble(VOR));
3068 
3069 	static const QString NACH("NACH");
3070 	if (attrs.hasAttribute(NACH))
3071 		newStyle.setGapAfter(attrs.valueAsDouble(NACH));
3072 
3073 	static const QString ParagraphEffectCharStyle("ParagraphEffectCharStyle");
3074 	if (attrs.hasAttribute(ParagraphEffectCharStyle))
3075 		newStyle.setPeCharStyleName(attrs.valueAsString(ParagraphEffectCharStyle));
3076 
3077 	static const QString ParagraphEffectOffset("ParagraphEffectOffset");
3078 	if (attrs.hasAttribute(ParagraphEffectOffset))
3079 		newStyle.setParEffectOffset(attrs.valueAsDouble(ParagraphEffectOffset));
3080 
3081 	static const QString ParagraphEffectIndent("ParagraphEffectIndent");
3082 	if (attrs.hasAttribute(ParagraphEffectIndent))
3083 		newStyle.setParEffectIndent(attrs.valueAsDouble(ParagraphEffectIndent));
3084 
3085 	static const QString DROP("DROP");
3086 	if (attrs.hasAttribute(DROP))
3087 		newStyle.setHasDropCap(static_cast<bool>(attrs.valueAsInt(DROP)));
3088 
3089 	static const QString DROPCHSTYLE("DROPCHSTYLE");
3090 	if (attrs.hasAttribute(DROPCHSTYLE))
3091 		newStyle.setPeCharStyleName(attrs.valueAsString(DROPCHSTYLE));
3092 
3093 	static const QString DROPLIN("DROPLIN");
3094 	if (attrs.hasAttribute(DROPLIN))
3095 		newStyle.setDropCapLines(attrs.valueAsInt(DROPLIN));
3096 
3097 	static const QString DROPDIST("DROPDIST");
3098 	if (attrs.hasAttribute(DROPDIST))
3099 		newStyle.setParEffectOffset(attrs.valueAsDouble(DROPDIST));
3100 
3101 	static const QString Bullet("Bullet");
3102 	if (attrs.hasAttribute(Bullet))
3103 		newStyle.setHasBullet(static_cast<bool>(attrs.valueAsInt(Bullet)));
3104 
3105 	static const QString BulletStr("BulletStr");
3106 	if (attrs.hasAttribute(BulletStr))
3107 		newStyle.setBulletStr(attrs.valueAsString(BulletStr));
3108 
3109 	static const QString Numeration("Numeration");
3110 	if (attrs.hasAttribute(Numeration))
3111 		newStyle.setHasNum(static_cast<bool>(attrs.valueAsInt(Numeration)));
3112 
3113 	static const QString NumerationName("NumerationName");
3114 	if (attrs.hasAttribute(NumerationName))
3115 		newStyle.setNumName(attrs.valueAsString(NumerationName));
3116 
3117 	static const QString NumerationFormat("NumerationFormat");
3118 	if (attrs.hasAttribute(NumerationFormat))
3119 		newStyle.setNumFormat(attrs.valueAsInt(NumerationFormat));
3120 
3121 	static const QString NumerationLevel("NumerationLevel");
3122 	if (attrs.hasAttribute(NumerationLevel))
3123 		newStyle.setNumLevel(attrs.valueAsInt(NumerationLevel));
3124 
3125 	static const QString NumerationStart("NumerationStart");
3126 	if (attrs.hasAttribute(NumerationStart))
3127 		newStyle.setNumStart(attrs.valueAsInt(NumerationStart));
3128 
3129 	static const QString NumearationPrefix("NumerationPrefix");
3130 	if (attrs.hasAttribute(NumearationPrefix))
3131 		newStyle.setNumPrefix(attrs.valueAsString(NumearationPrefix));
3132 
3133 	static const QString NumerationSuffix("NumerationSuffix");
3134 	if (attrs.hasAttribute(NumerationSuffix))
3135 		newStyle.setNumSuffix(attrs.valueAsString(NumerationSuffix));
3136 
3137 	static const QString NumerationRestart("NumerationRestart");
3138 	if (attrs.hasAttribute(NumerationRestart))
3139 		newStyle.setNumRestart(attrs.valueAsInt(NumerationRestart));
3140 
3141 	static const QString NumerationOther("NumerationOther");
3142 	if (attrs.hasAttribute(NumerationOther))
3143 		newStyle.setNumOther(static_cast<bool>(attrs.valueAsInt(NumerationOther)));
3144 
3145 	static const QString NumerationHigher("NumerationHigher");
3146 	if (attrs.hasAttribute(NumerationHigher))
3147 		newStyle.setNumHigher(static_cast<bool>(attrs.valueAsInt(NumerationHigher)));
3148 
3149 	static const QString PSHORTCUT("PSHORTCUT");
3150 	if (attrs.hasAttribute(PSHORTCUT))
3151 		newStyle.setShortcut(attrs.valueAsString(PSHORTCUT));
3152 
3153 	static const QString OpticalMargins("OpticalMargins");
3154 	if (attrs.hasAttribute(OpticalMargins))
3155 		newStyle.setOpticalMargins(attrs.valueAsInt(OpticalMargins));
3156 
3157 	static const QString HyphenConsecutiveLines("HyphenConsecutiveLines");
3158 	if (attrs.hasAttribute(HyphenConsecutiveLines))
3159 		newStyle.setHyphenConsecutiveLines(attrs.valueAsInt(HyphenConsecutiveLines));
3160 
3161 	static const QString HyphenationMode("HyphenationMode");
3162 	if (attrs.hasAttribute(HyphenationMode))
3163 		newStyle.setHyphenationMode(attrs.valueAsInt(HyphenationMode));
3164 
3165 	static const QString MinWordTrack("MinWordTrack");
3166 	if (attrs.hasAttribute(MinWordTrack))
3167 		newStyle.setMinWordTracking(attrs.valueAsDouble(MinWordTrack));
3168 
3169 	static const QString NormWordTrack("NormWordTrack");
3170 	if (attrs.hasAttribute(NormWordTrack))
3171 		newStyle.charStyle().setWordTracking(attrs.valueAsDouble(NormWordTrack));
3172 
3173 	static const QString MinGlyphShrink("MinGlyphShrink");
3174 	if (attrs.hasAttribute(MinGlyphShrink))
3175 		newStyle.setMinGlyphExtension(attrs.valueAsDouble(MinGlyphShrink));
3176 
3177 	static const QString MaxGlyphExtend("MaxGlyphExtend");
3178 	if (attrs.hasAttribute(MaxGlyphExtend))
3179 		newStyle.setMaxGlyphExtension(attrs.valueAsDouble(MaxGlyphExtend));
3180 
3181 	static const QString KeepLinesStart("KeepLinesStart");
3182 	if (attrs.hasAttribute(KeepLinesStart))
3183 		newStyle.setKeepLinesStart(attrs.valueAsInt(KeepLinesStart));
3184 
3185 	static const QString KeepLinesEnd("KeepLinesEnd");
3186 	if (attrs.hasAttribute(KeepLinesEnd))
3187 		newStyle.setKeepLinesEnd(attrs.valueAsInt(KeepLinesEnd));
3188 
3189 	static const QString KeepWithNext("KeepWithNext");
3190 	if (attrs.hasAttribute(KeepWithNext))
3191 		newStyle.setKeepWithNext(attrs.valueAsInt(KeepWithNext));
3192 
3193 	static const QString KeepTogether("KeepTogether");
3194 	if (attrs.hasAttribute(KeepTogether))
3195 		newStyle.setKeepTogether(attrs.valueAsInt(KeepTogether));
3196 	static const QString BCOLOR("BCOLOR");
3197 	if (attrs.hasAttribute(BCOLOR))
3198 		newStyle.setBackgroundColor(attrs.valueAsString(BCOLOR, CommonStrings::None));
3199 	static const QString BSHADE("BSHADE");
3200 	if (attrs.hasAttribute(BSHADE))
3201 		newStyle.setBackgroundShade(attrs.valueAsInt(BSHADE, 100));
3202 
3203 	readCharacterStyleAttrs(doc, attrs, newStyle.charStyle());
3204 
3205 	//	newStyle.tabValues().clear();
3206 	QList<ParagraphStyle::TabRecord> tbs;
3207 	newStyle.resetTabValues();
3208 	QStringRef thisTagName = reader.name();
3209 	while (!reader.atEnd() && !reader.hasError())
3210 	{
3211 		reader.readNext();
3212 		if (reader.isEndElement() && reader.name() == thisTagName)
3213 			break;
3214 		if (reader.isStartElement() && reader.name() == "Tabs")
3215 		{
3216 			ParagraphStyle::TabRecord tb;
3217 			ScXmlStreamAttributes attrs2 = reader.scAttributes();
3218 			tb.tabPosition = attrs2.valueAsDouble("Pos");
3219 			tb.tabType     = attrs2.valueAsInt("Type");
3220 			QString tbCh   = attrs2.valueAsString("Fill","");
3221 			tb.tabFillChar = tbCh.isEmpty() ? QChar() : tbCh[0];
3222 			tbs.append(tb);
3223 		}
3224 	}
3225 	if (tbs.count() > 0)
3226 		newStyle.setTabValues(tbs);
3227 
3228 	fixLegacyParStyle(newStyle);
3229 }
3230 
readTableStyle(ScribusDoc * doc,ScXmlStreamReader & reader,TableStyle & newStyle)3231 void Scribus150Format::readTableStyle(ScribusDoc *doc, ScXmlStreamReader& reader, TableStyle& newStyle)
3232 {
3233 	ScXmlStreamAttributes attrs = reader.scAttributes();
3234 	newStyle.erase();
3235 	newStyle.setName(attrs.valueAsString("NAME", ""));
3236 	// The default style attribute must be correctly set before trying to assign a parent
3237 	if (attrs.hasAttribute("DefaultStyle"))
3238 		newStyle.setDefaultStyle(attrs.valueAsInt("DefaultStyle"));
3239 	else if (newStyle.name() == CommonStrings::DefaultTableStyle || newStyle.name() == CommonStrings::trDefaultTableStyle)
3240 		newStyle.setDefaultStyle(true);
3241 	else
3242 		newStyle.setDefaultStyle(false);
3243 	QString parentStyle = attrs.valueAsString("PARENT", "");
3244 	if (!parentStyle.isEmpty() && (parentStyle != newStyle.name()))
3245 		newStyle.setParent(parentStyle);
3246 	if (attrs.hasAttribute("FillColor"))
3247 		newStyle.setFillColor(attrs.valueAsString("FillColor"));
3248 	if (attrs.hasAttribute("FillShade"))
3249 		newStyle.setFillShade(attrs.valueAsDouble("FillShade"));
3250 	QStringRef tagName = reader.name();
3251 	while (!reader.atEnd() && !reader.hasError())
3252 	{
3253 		reader.readNext();
3254 		if (reader.isEndElement() && reader.name() == tagName)
3255 			break;
3256 		if (reader.name() == "TableBorderLeft")
3257 		{
3258 			TableBorder border;
3259 			QStringRef tagName = reader.name();
3260 			while (!reader.atEnd() && !reader.hasError())
3261 			{
3262 				reader.readNext();
3263 				if (reader.isEndElement() && reader.name() == tagName)
3264 					break;
3265 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3266 				{
3267 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3268 					double width = tAttB.valueAsDouble("Width", 0.0);
3269 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3270 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3271 					int style = tAttB.valueAsInt("PenStyle", 1);
3272 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3273 				}
3274 			}
3275 			newStyle.setLeftBorder(border);
3276 		}
3277 		else if (reader.name() == "TableBorderRight")
3278 		{
3279 			TableBorder border;
3280 			QStringRef tagName = reader.name();
3281 			while (!reader.atEnd() && !reader.hasError())
3282 			{
3283 				reader.readNext();
3284 				if (reader.isEndElement() && reader.name() == tagName)
3285 					break;
3286 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3287 				{
3288 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3289 					double width = tAttB.valueAsDouble("Width", 0.0);
3290 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3291 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3292 					int style = tAttB.valueAsInt("PenStyle", 1);
3293 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3294 				}
3295 			}
3296 			newStyle.setRightBorder(border);
3297 		}
3298 		else if (reader.name() == "TableBorderTop")
3299 		{
3300 			TableBorder border;
3301 			QStringRef tagName = reader.name();
3302 			while (!reader.atEnd() && !reader.hasError())
3303 			{
3304 				reader.readNext();
3305 				if (reader.isEndElement() && reader.name() == tagName)
3306 					break;
3307 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3308 				{
3309 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3310 					double width = tAttB.valueAsDouble("Width", 0.0);
3311 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3312 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3313 					int style = tAttB.valueAsInt("PenStyle", 1);
3314 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3315 				}
3316 			}
3317 			newStyle.setTopBorder(border);
3318 		}
3319 		else if (reader.name() == "TableBorderBottom")
3320 		{
3321 			TableBorder border;
3322 			QStringRef tagName = reader.name();
3323 			while (!reader.atEnd() && !reader.hasError())
3324 			{
3325 				reader.readNext();
3326 				if (reader.isEndElement() && reader.name() == tagName)
3327 					break;
3328 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3329 				{
3330 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3331 					double width = tAttB.valueAsDouble("Width", 0.0);
3332 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3333 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3334 					int style = tAttB.valueAsInt("PenStyle", 1);
3335 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3336 				}
3337 			}
3338 			newStyle.setBottomBorder(border);
3339 		}
3340 	}
3341 }
3342 
readCellStyle(ScribusDoc * doc,ScXmlStreamReader & reader,CellStyle & newStyle)3343 void Scribus150Format::readCellStyle(ScribusDoc *doc, ScXmlStreamReader& reader, CellStyle& newStyle)
3344 {
3345 	ScXmlStreamAttributes attrs = reader.scAttributes();
3346 	newStyle.erase();
3347 	newStyle.setName(attrs.valueAsString("NAME", ""));
3348 	// The default style attribute must be correctly set before trying to assign a parent
3349 	if (attrs.hasAttribute("DefaultStyle"))
3350 		newStyle.setDefaultStyle(attrs.valueAsInt("DefaultStyle"));
3351 	else if (newStyle.name() == CommonStrings::DefaultCellStyle || newStyle.name() == CommonStrings::trDefaultCellStyle)
3352 		newStyle.setDefaultStyle(true);
3353 	else
3354 		newStyle.setDefaultStyle(false);
3355 	QString parentStyle = attrs.valueAsString("PARENT", "");
3356 	if (!parentStyle.isEmpty() && (parentStyle != newStyle.name()))
3357 		newStyle.setParent(parentStyle);
3358 	if (attrs.hasAttribute("FillColor"))
3359 		newStyle.setFillColor(attrs.valueAsString("FillColor"));
3360 	if (attrs.hasAttribute("FillShade"))
3361 		newStyle.setFillShade(attrs.valueAsDouble("FillShade"));
3362 	if (attrs.hasAttribute("LeftPadding"))
3363 		newStyle.setLeftPadding(attrs.valueAsDouble("LeftPadding", 0.0));
3364 	if (attrs.hasAttribute("RightPadding"))
3365 		newStyle.setRightPadding(attrs.valueAsDouble("RightPadding", 0.0));
3366 	if (attrs.hasAttribute("TopPadding"))
3367 		newStyle.setTopPadding(attrs.valueAsDouble("TopPadding", 0.0));
3368 	if (attrs.hasAttribute("BottomPadding"))
3369 		newStyle.setBottomPadding(attrs.valueAsDouble("BottomPadding", 0.0));
3370 	QStringRef tagName = reader.name();
3371 	while (!reader.atEnd() && !reader.hasError())
3372 	{
3373 		reader.readNext();
3374 		if (reader.isEndElement() && reader.name() == tagName)
3375 			break;
3376 		if (reader.name() == "TableBorderLeft")
3377 		{
3378 			TableBorder border;
3379 			QStringRef tagName = reader.name();
3380 			while (!reader.atEnd() && !reader.hasError())
3381 			{
3382 				reader.readNext();
3383 				if (reader.isEndElement() && reader.name() == tagName)
3384 					break;
3385 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3386 				{
3387 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3388 					double width = tAttB.valueAsDouble("Width", 0.0);
3389 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3390 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3391 					int style = tAttB.valueAsInt("PenStyle", 1);
3392 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3393 				}
3394 			}
3395 			newStyle.setLeftBorder(border);
3396 		}
3397 		else if (reader.name() == "TableBorderRight")
3398 		{
3399 			TableBorder border;
3400 			QStringRef tagName = reader.name();
3401 			while (!reader.atEnd() && !reader.hasError())
3402 			{
3403 				reader.readNext();
3404 				if (reader.isEndElement() && reader.name() == tagName)
3405 					break;
3406 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3407 				{
3408 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3409 					double width = tAttB.valueAsDouble("Width", 0.0);
3410 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3411 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3412 					int style = tAttB.valueAsInt("PenStyle", 1);
3413 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3414 				}
3415 			}
3416 			newStyle.setRightBorder(border);
3417 		}
3418 		else if (reader.name() == "TableBorderTop")
3419 		{
3420 			TableBorder border;
3421 			QStringRef tagName = reader.name();
3422 			while (!reader.atEnd() && !reader.hasError())
3423 			{
3424 				reader.readNext();
3425 				if (reader.isEndElement() && reader.name() == tagName)
3426 					break;
3427 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3428 				{
3429 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3430 					double width = tAttB.valueAsDouble("Width", 0.0);
3431 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3432 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3433 					int style = tAttB.valueAsInt("PenStyle", 1);
3434 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3435 				}
3436 			}
3437 			newStyle.setTopBorder(border);
3438 		}
3439 		else if (reader.name() == "TableBorderBottom")
3440 		{
3441 			TableBorder border;
3442 			QStringRef tagName = reader.name();
3443 			while (!reader.atEnd() && !reader.hasError())
3444 			{
3445 				reader.readNext();
3446 				if (reader.isEndElement() && reader.name() == tagName)
3447 					break;
3448 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
3449 				{
3450 					ScXmlStreamAttributes tAttB = reader.scAttributes();
3451 					double width = tAttB.valueAsDouble("Width", 0.0);
3452 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
3453 					double shade = tAttB.valueAsDouble("Shade", 100.0);
3454 					int style = tAttB.valueAsInt("PenStyle", 1);
3455 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
3456 				}
3457 			}
3458 			newStyle.setBottomBorder(border);
3459 		}
3460 	}
3461 }
3462 
readLayers(ScLayer & layer,ScXmlStreamAttributes & attrs)3463 void Scribus150Format::readLayers(ScLayer& layer, ScXmlStreamAttributes& attrs)
3464 {
3465 	int lId   = attrs.valueAsInt("NUMMER");
3466 	int level = attrs.valueAsInt("LEVEL");
3467 	layer = ScLayer( attrs.valueAsString("NAME"), level, lId);
3468 	layer.isViewable   = attrs.valueAsInt("SICHTBAR");
3469 	layer.isPrintable  = attrs.valueAsInt("DRUCKEN");
3470 	layer.isEditable   = attrs.valueAsInt("EDIT", 1);
3471 	layer.flowControl  = attrs.valueAsInt("FLOW", 1);
3472 	layer.isSelectable = attrs.valueAsInt("SELECT", 0);
3473 	layer.transparency = attrs.valueAsDouble("TRANS", 1.0);
3474 	layer.blendMode    = attrs.valueAsInt("BLEND", 0);
3475 	layer.outlineMode  = attrs.valueAsInt("OUTL", 0);
3476 	if (attrs.hasAttribute("LAYERC"))
3477 		layer.markerColor =  QColor(attrs.valueAsString("LAYERC","#000000"));
3478 }
3479 
readArrows(ScribusDoc * doc,ScXmlStreamAttributes & attrs)3480 bool Scribus150Format::readArrows(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
3481 {
3482 	double xa, ya;
3483 	struct ArrowDesc arrow;
3484 	arrow.name = attrs.valueAsString("Name");
3485 	arrow.userArrow = true;
3486 	QString tmp = attrs.valueAsString("Points");
3487 	ScTextStream fp(&tmp, QIODevice::ReadOnly);
3488 	unsigned int numPoints = attrs.valueAsUInt("NumPoints");
3489 	for (uint cx = 0; cx < numPoints; ++cx)
3490 	{
3491 		fp >> xa;
3492 		fp >> ya;
3493 		arrow.points.addPoint(xa, ya);
3494 	}
3495 	if (!doc->hasArrowStyle(arrow.name))
3496 		doc->appendToArrowStyles(arrow);
3497 	return true;
3498 }
3499 
readMultiline(multiLine & ml,ScXmlStreamReader & reader)3500 bool Scribus150Format::readMultiline(multiLine& ml, ScXmlStreamReader& reader)
3501 {
3502 	ml = multiLine();
3503 	ScXmlStreamAttributes rattrs = reader.scAttributes();
3504 	QStringRef tagName = reader.name();
3505 	while (!reader.atEnd() && !reader.hasError())
3506 	{
3507 		ScXmlStreamReader::TokenType tType = reader.readNext();
3508 		if (tType == ScXmlStreamReader::EndElement && reader.name() == tagName)
3509 			break;
3510 		if (tType == ScXmlStreamReader::StartElement && reader.name() == "SubLine")
3511 		{
3512 			struct SingleLine sl;
3513 			ScXmlStreamAttributes attrs = reader.scAttributes();
3514 			sl.Color    = attrs.valueAsString("Color");
3515 			sl.Dash     = attrs.valueAsInt("Dash");
3516 			sl.LineEnd  = attrs.valueAsInt("LineEnd");
3517 			sl.LineJoin = attrs.valueAsInt("LineJoin");
3518 			sl.Shade    = attrs.valueAsInt("Shade");
3519 			sl.Width    = attrs.valueAsDouble("Width");
3520 			ml.shortcut = attrs.valueAsString("Shortcut");
3521 			ml.push_back(sl);
3522 		}
3523 	}
3524 	return !reader.hasError();
3525 }
3526 
readBookMark(ScribusDoc::BookMa & bookmark,int & elem,ScXmlStreamAttributes & attrs)3527 bool Scribus150Format::readBookMark(ScribusDoc::BookMa& bookmark, int& elem, ScXmlStreamAttributes& attrs)
3528 {
3529 	elem = attrs.valueAsInt("Element");
3530 	bookmark.PageObject = nullptr;
3531 	bookmark.Title  = attrs.valueAsString("Title");
3532 	bookmark.Text   = attrs.valueAsString("Text");
3533 	bookmark.Aktion = attrs.valueAsString("Aktion");
3534 	bookmark.ItemNr = attrs.valueAsInt("ItemNr");
3535 	bookmark.First  = attrs.valueAsInt("First");
3536 	bookmark.Last   = attrs.valueAsInt("Last");
3537 	bookmark.Prev   = attrs.valueAsInt("Prev");
3538 	bookmark.Next   = attrs.valueAsInt("Next");
3539 	bookmark.Parent = attrs.valueAsInt("Parent");
3540 	return true;
3541 }
3542 
readPDFOptions(ScribusDoc * doc,ScXmlStreamReader & reader)3543 bool Scribus150Format::readPDFOptions(ScribusDoc* doc, ScXmlStreamReader& reader)
3544 {
3545 	ScXmlStreamAttributes attrs = reader.scAttributes();
3546 
3547 	doc->pdfOptions().firstUse   = attrs.valueAsBool("firstUse", true);
3548 	doc->pdfOptions().Articles   = attrs.valueAsBool("Articles");
3549 	doc->pdfOptions().Thumbnails = attrs.valueAsBool("Thumbnails");
3550 	doc->pdfOptions().Compress   = attrs.valueAsBool("Compress");
3551 	doc->pdfOptions().CompressMethod = (PDFOptions::PDFCompression) attrs.valueAsInt("CMethod", 0);
3552 	doc->pdfOptions().Quality    = attrs.valueAsInt("Quality", 0);
3553 	doc->pdfOptions().RecalcPic  = attrs.valueAsBool("RecalcPic");
3554 	doc->pdfOptions().embedPDF   = attrs.valueAsBool("EmbedPDF", false);
3555 	doc->pdfOptions().Bookmarks  = attrs.valueAsBool("Bookmarks");
3556 	doc->pdfOptions().MirrorH    = attrs.valueAsBool("MirrorH", false);
3557 	doc->pdfOptions().MirrorV    = attrs.valueAsBool("MirrorV", false);
3558 	doc->pdfOptions().RotateDeg  = attrs.valueAsInt("RotateDeg", 0);
3559 	doc->pdfOptions().pageRangeSelection = attrs.valueAsInt("rangeSel", 0);
3560 	doc->pdfOptions().pageRangeString = attrs.valueAsString("rangeTxt", "");
3561 	doc->pdfOptions().doClip     = attrs.valueAsBool("Clip", false);
3562 	doc->pdfOptions().PresentMode = attrs.valueAsBool("PresentMode");
3563 	doc->pdfOptions().PicRes     = attrs.valueAsInt("PicRes");
3564 	// Fixme: check input pdf version
3565 	doc->pdfOptions().Version    = (PDFVersion::Version) attrs.valueAsInt("Version");
3566 	doc->pdfOptions().Resolution = attrs.valueAsInt("Resolution");
3567 	doc->pdfOptions().Binding    = attrs.valueAsInt("Binding");
3568 	doc->pdfOptions().fileName   = "";
3569 
3570 	doc->pdfOptions().FontEmbedding = (PDFOptions::PDFFontEmbedding) attrs.valueAsInt("FontEmbedding", 0);
3571 	doc->pdfOptions().isGrayscale   = attrs.valueAsBool("Grayscale", false);
3572 	doc->pdfOptions().UseRGB        = attrs.valueAsBool("RGBMode", false);
3573 	doc->pdfOptions().UseProfiles   = attrs.valueAsBool("UseProfiles", false);
3574 	doc->pdfOptions().UseProfiles2  = attrs.valueAsBool("UseProfiles2", false);
3575 	doc->pdfOptions().Intent        = attrs.valueAsInt("Intent", 1);
3576 	doc->pdfOptions().Intent2       = attrs.valueAsInt("Intent2", 1);
3577 	doc->pdfOptions().SolidProf     = attrs.valueAsString("SolidP", "");
3578 	doc->pdfOptions().ImageProf     = attrs.valueAsString("ImageP", "");
3579 	doc->pdfOptions().PrintProf     = attrs.valueAsString("PrintP", "");
3580 	doc->pdfOptions().Info          = attrs.valueAsString("InfoString", "");
3581 	doc->pdfOptions().bleeds.setTop(attrs.valueAsDouble("BTop", 0.0));
3582 	doc->pdfOptions().bleeds.setLeft(attrs.valueAsDouble("BLeft", 0.0));
3583 	doc->pdfOptions().bleeds.setRight(attrs.valueAsDouble("BRight", 0.0));
3584 	doc->pdfOptions().bleeds.setBottom(attrs.valueAsDouble("BBottom", 0.0));
3585 	doc->pdfOptions().useDocBleeds  = attrs.valueAsBool("useDocBleeds", true);
3586 	doc->pdfOptions().cropMarks     = attrs.valueAsBool("cropMarks", false);
3587 	doc->pdfOptions().bleedMarks    = attrs.valueAsBool("bleedMarks", false);
3588 	doc->pdfOptions().registrationMarks = attrs.valueAsBool("registrationMarks", false);
3589 	doc->pdfOptions().colorMarks    = attrs.valueAsBool("colorMarks", false);
3590 	doc->pdfOptions().docInfoMarks  = attrs.valueAsBool("docInfoMarks", false);
3591 	doc->pdfOptions().markLength    = attrs.valueAsDouble("markLength", 20.0);
3592 	doc->pdfOptions().markOffset    = attrs.valueAsDouble("markOffset", 0.0);
3593 	doc->pdfOptions().EmbeddedI     = attrs.valueAsBool("ImagePr", false);
3594 	doc->pdfOptions().PassOwner     = attrs.valueAsString("PassOwner", "");
3595 	doc->pdfOptions().PassUser      = attrs.valueAsString("PassUser", "");
3596 	doc->pdfOptions().Permissions   = attrs.valueAsInt("Permissions", -4);
3597 	doc->pdfOptions().Encrypt       = attrs.valueAsBool("Encrypt", false);
3598 	doc->pdfOptions().useLayers     = attrs.valueAsBool("UseLayers", false);
3599 	doc->pdfOptions().UseLPI        = attrs.valueAsBool("UseLpi", false);
3600 	doc->pdfOptions().UseSpotColors = attrs.valueAsBool("UseSpotColors", true);
3601 	doc->pdfOptions().doMultiFile   = attrs.valueAsBool("doMultiFile", false);
3602 	doc->pdfOptions().displayBookmarks =  attrs.valueAsBool("displayBookmarks", false);
3603 	doc->pdfOptions().displayFullscreen = attrs.valueAsBool("displayFullscreen", false);
3604 	doc->pdfOptions().displayLayers = attrs.valueAsBool("displayLayers", false);
3605 	doc->pdfOptions().displayThumbs = attrs.valueAsBool("displayThumbs", false);
3606 	doc->pdfOptions().hideMenuBar   = attrs.valueAsBool("hideMenuBar", false);
3607 	doc->pdfOptions().hideToolBar   = attrs.valueAsBool("hideToolBar", false);
3608 	doc->pdfOptions().fitWindow     = attrs.valueAsBool("fitWindow", false);
3609 	doc->pdfOptions().openAfterExport     = attrs.valueAsBool("openAfterExport", false);
3610 	doc->pdfOptions().PageLayout    = attrs.valueAsInt("PageLayout", 0);
3611 	doc->pdfOptions().openAction    = attrs.valueAsString("openAction", "");
3612 
3613 	QStringRef tagName = reader.name();
3614 	while (!reader.atEnd() && !reader.hasError())
3615 	{
3616 		reader.readNext();
3617 		if (reader.isEndElement() && (reader.name() == tagName))
3618 			break;
3619 		if (!reader.isStartElement())
3620 			continue;
3621 		QStringRef tName = reader.name();
3622 		attrs = reader.scAttributes();
3623 		if (tName == "LPI")
3624 		{
3625 			struct LPIData lpo;
3626 			lpo.Angle     = attrs.valueAsInt("Angle");
3627 			lpo.Frequency = attrs.valueAsInt("Frequency");
3628 			lpo.SpotFunc  = attrs.valueAsInt("SpotFunction");
3629 			doc->pdfOptions().LPISettings[attrs.valueAsString("Color")] = lpo;
3630 		}
3631 		if (tName == "Fonts")
3632 		{
3633 			QString fname = attrs.valueAsString("Name");
3634 			if (!doc->pdfOptions().EmbedList.contains(fname))
3635 				doc->pdfOptions().EmbedList.append(fname);
3636 		}
3637 		if (tName == "Subset")
3638 		{
3639 			QString sname = attrs.valueAsString("Name");
3640 			if (!doc->pdfOptions().SubsetList.contains(sname))
3641 				doc->pdfOptions().SubsetList.append(sname);
3642 		}
3643 		if (tName == "Effekte")
3644 		{
3645 			struct PDFPresentationData ef;
3646 			ef.pageEffectDuration =  attrs.valueAsInt("pageEffectDuration");
3647 			ef.pageViewDuration =  attrs.valueAsInt("pageViewDuration");
3648 			ef.effectType = attrs.valueAsInt("effectType");
3649 			ef.Dm = attrs.valueAsInt("Dm");
3650 			ef.M  = attrs.valueAsInt("M");
3651 			ef.Di = attrs.valueAsInt("Di");
3652 			EffVal.append(ef);
3653 		}
3654 	}
3655 	return !reader.hasError();
3656 }
3657 
readPrinterOptions(ScribusDoc * doc,ScXmlStreamReader & reader)3658 bool Scribus150Format::readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader)
3659 {
3660 	ScXmlStreamAttributes attrs = reader.scAttributes();
3661 	doc->Print_Options.firstUse = attrs.valueAsBool("firstUse");
3662 	if (doc->Print_Options.firstUse)
3663 	{
3664 		// Formerly we were writing uninitialized structure values in documents
3665 		// so set these uninitialized values to something more meaningful
3666 		PrinterUtil::getDefaultPrintOptions(doc->Print_Options, doc->bleedsVal());
3667 		reader.readToElementEnd();
3668 		return !reader.hasError();
3669 	}
3670 
3671 	doc->Print_Options.toFile   = attrs.valueAsBool("toFile");
3672 	doc->Print_Options.useAltPrintCommand = attrs.valueAsBool("useAltPrintCommand");
3673 	doc->Print_Options.outputSeparations  = attrs.valueAsBool("outputSeparations");
3674 	doc->Print_Options.useSpotColors      = attrs.valueAsBool("useSpotColors");
3675 	doc->Print_Options.useColor = attrs.valueAsBool("useColor");
3676 	doc->Print_Options.mirrorH  = attrs.valueAsBool("mirrorH");
3677 	doc->Print_Options.mirrorV  = attrs.valueAsBool("mirrorV");
3678 	doc->Print_Options.doGCR    = attrs.valueAsBool("doGCR");
3679 	doc->Print_Options.doClip   = attrs.valueAsBool("doClip");
3680 	doc->Print_Options.setDevParam  = attrs.valueAsBool("setDevParam");
3681 	doc->Print_Options.useDocBleeds = attrs.valueAsBool("useDocBleeds");
3682 	doc->Print_Options.cropMarks    = attrs.valueAsBool("cropMarks");
3683 	doc->Print_Options.bleedMarks   = attrs.valueAsBool("bleedMarks");
3684 	doc->Print_Options.registrationMarks = attrs.valueAsBool("registrationMarks");
3685 	doc->Print_Options.colorMarks   = attrs.valueAsBool("colorMarks");
3686 	doc->Print_Options.includePDFMarks = attrs.valueAsBool("includePDFMarks", true);
3687 	if (attrs.hasAttribute("PrintEngine"))
3688 		doc->Print_Options.prnLanguage = (PrintLanguage) attrs.valueAsInt("PrintEngine", 3);
3689 	else
3690 		doc->Print_Options.prnLanguage = (PrintLanguage) attrs.valueAsInt("PSLevel", 3);
3691 	doc->Print_Options.markLength    = attrs.valueAsDouble("markLength");
3692 	doc->Print_Options.markOffset    = attrs.valueAsDouble("markOffset");
3693 	doc->Print_Options.bleeds.setTop(attrs.valueAsDouble("BleedTop"));
3694 	doc->Print_Options.bleeds.setLeft(attrs.valueAsDouble("BleedLeft"));
3695 	doc->Print_Options.bleeds.setRight(attrs.valueAsDouble("BleedRight"));
3696 	doc->Print_Options.bleeds.setBottom(attrs.valueAsDouble("BleedBottom"));
3697 	doc->Print_Options.printer  = attrs.valueAsString("printer");
3698 	doc->Print_Options.filename = attrs.valueAsString("filename");
3699 	doc->Print_Options.separationName = attrs.valueAsString("separationName");
3700 	doc->Print_Options.printerCommand = attrs.valueAsString("printerCommand");
3701 	doc->Print_Options.copies = 1;
3702 
3703 	QStringRef tagName = reader.name();
3704 	while (!reader.atEnd() && !reader.hasError())
3705 	{
3706 		ScXmlStreamReader::TokenType tType = reader.readNext();
3707 		QStringRef tName = reader.name();
3708 		if (tType == ScXmlStreamReader::StartElement && tName == "Separation")
3709 			doc->Print_Options.allSeparations.append(reader.attributes().value("Name").toString());
3710 		if (tType == ScXmlStreamReader::EndElement && tName == tagName)
3711 			break;
3712 	}
3713 	return !reader.hasError();
3714 }
3715 
readDocItemAttributes(ScribusDoc * doc,ScXmlStreamReader & reader)3716 bool Scribus150Format::readDocItemAttributes(ScribusDoc *doc, ScXmlStreamReader& reader)
3717 {
3718 	QStringRef tagName = reader.name();
3719 	doc->clearItemAttributes();
3720 	while (!reader.atEnd() && !reader.hasError())
3721 	{
3722 		reader.readNext();
3723 		if (reader.isEndElement() && reader.name() == tagName)
3724 			break;
3725 		if (reader.isStartElement() && reader.name() == "ItemAttribute")
3726 		{
3727 			ScXmlStreamAttributes attrs = reader.scAttributes();
3728 			ObjectAttribute objattr;
3729 			objattr.name  = attrs.valueAsString("Name");
3730 			objattr.type  = attrs.valueAsString("Type");
3731 			objattr.value = attrs.valueAsString("Value");
3732 			objattr.parameter      = attrs.valueAsString("Parameter");
3733 			objattr.relationship   = attrs.valueAsString("Relationship");
3734 			objattr.relationshipto = attrs.valueAsString("RelationshipTo");
3735 			objattr.autoaddto = attrs.valueAsString("AutoAddTo");
3736 			doc->appendToItemAttributes(objattr);
3737 		}
3738 	}
3739 	return !reader.hasError();
3740 }
3741 
readTableOfContents(ScribusDoc * doc,ScXmlStreamReader & reader)3742 bool Scribus150Format::readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader)
3743 {
3744 	QStringRef tagName = reader.name();
3745 	m_Doc->clearTocSetups();
3746 	while (!reader.atEnd() && !reader.hasError())
3747 	{
3748 		reader.readNext();
3749 		if (reader.isEndElement() && reader.name() == tagName)
3750 			break;
3751 		if (reader.isStartElement() && reader.name() == "TableOfContents")
3752 		{
3753 			ScXmlStreamAttributes attrs = reader.scAttributes();
3754 			ToCSetup tocsetup;
3755 			tocsetup.name = attrs.valueAsString("Name");
3756 			tocsetup.itemAttrName = attrs.valueAsString("ItemAttributeName");
3757 			tocsetup.frameName    = attrs.valueAsString("FrameName");
3758 			tocsetup.textStyle    = attrs.valueAsString("Style");
3759 			tocsetup.listNonPrintingFrames = QVariant(attrs.valueAsString("ListNonPrinting")).toBool();
3760 			QString numberPlacement(attrs.valueAsString("NumberPlacement"));
3761 			if (numberPlacement == "Beginning")
3762 				tocsetup.pageLocation = Beginning;
3763 			if (numberPlacement == "End")
3764 				tocsetup.pageLocation = End;
3765 			if (numberPlacement == "NotShown")
3766 				tocsetup.pageLocation = NotShown;
3767 			doc->appendToTocSetups(tocsetup);
3768 		}
3769 	}
3770 	return !reader.hasError();
3771 }
3772 
readNotesStyles(ScribusDoc * doc,ScXmlStreamReader & reader)3773 bool Scribus150Format::readNotesStyles(ScribusDoc* doc, ScXmlStreamReader& reader)
3774 {
3775 	QStringRef tagName = reader.name();
3776 	while (!reader.atEnd() && !reader.hasError())
3777 	{
3778 		reader.readNext();
3779 		if (reader.isEndElement() && reader.name() == tagName)
3780 			break;
3781 		//read notes styles
3782 		if (reader.isStartElement() && reader.name() == "notesStyle")
3783 		{
3784 			ScXmlStreamAttributes attrs = reader.scAttributes();
3785 			NotesStyle NS;
3786 			NS.setName(attrs.valueAsString("Name"));
3787 			NS.setStart(attrs.valueAsInt("Start"));
3788 			NS.setEndNotes(attrs.valueAsBool("Endnotes"));
3789 			QString type = attrs.valueAsString("Type");
3790 			if (type == "Type_1_2_3")
3791 				NS.setType(Type_1_2_3);
3792 			else if (type == "Type_1_2_3_ar")
3793 				NS.setType(Type_1_2_3_ar);
3794 			else if (type == "Type_i_ii_iii")
3795 				NS.setType(Type_i_ii_iii);
3796 			else if (type == "Type_I_II_III")
3797 				NS.setType(Type_I_II_III);
3798 			else if (type == "Type_a_b_c")
3799 				NS.setType(Type_a_b_c);
3800 			else if (type == "Type_A_B_C")
3801 				NS.setType(Type_A_B_C);
3802 			else if (type == "Type_Alphabet_ar")
3803 				NS.setType(Type_Alphabet_ar);
3804 			else if (type == "Type_Abjad_ar")
3805 				NS.setType(Type_Abjad_ar);
3806 			else if (type == "Type_Hebrew")
3807 				NS.setType(Type_Hebrew);
3808 			else if (type == "Type_asterix")
3809 				NS.setType(Type_asterix);
3810 			else if (type == "Type_CJK")
3811 				NS.setType(Type_CJK);
3812 			else //if (type == "Type_None")
3813 				NS.setType(Type_None);
3814 			// Fix deprecated numeration ranges
3815 			NumerationRange numRange = (NumerationRange) attrs.valueAsInt("Range");
3816 			if (numRange != NSRdocument && numRange != NSRstory)
3817 				numRange = NSRstory;
3818 			NS.setRange(numRange);
3819 			NS.setPrefix(attrs.valueAsString("Prefix"));
3820 			NS.setSuffix(attrs.valueAsString("Suffix"));
3821 			NS.setAutoNotesHeight(attrs.valueAsBool("AutoHeight"));
3822 			NS.setAutoNotesWidth(attrs.valueAsBool("AutoWidth"));
3823 			NS.setAutoRemoveEmptyNotesFrames(attrs.valueAsBool("AutoRemove"));
3824 			NS.setAutoWeldNotesFrames(attrs.valueAsBool("AutoWeld"));
3825 			NS.setSuperscriptInNote(attrs.valueAsBool("SuperNote"));
3826 			NS.setSuperscriptInMaster(attrs.valueAsBool("SuperMaster"));
3827 			NS.setMarksCharStyle("");
3828 			NS.setNotesParStyle("");
3829 			QString name;
3830 			name = attrs.valueAsString("MarksStyle");
3831 			if (!name.isEmpty())
3832 				NS.setMarksCharStyle(name);
3833 			name = attrs.valueAsString("NotesStyle");
3834 			if (!name.isEmpty())
3835 				NS.setNotesParStyle(name);
3836 
3837 			m_Doc->newNotesStyle(NS);
3838 		}
3839 	}
3840 	return !reader.hasError();
3841 }
3842 
readNotesFrames(ScXmlStreamReader & reader)3843 bool Scribus150Format::readNotesFrames(ScXmlStreamReader& reader)
3844 {
3845 	notesFramesData.clear();
3846 	QStringRef tagName = reader.name();
3847 	while (!reader.atEnd() && !reader.hasError())
3848 	{
3849 		reader.readNext();
3850 		if (reader.isEndElement() && reader.name() == tagName)
3851 			break;
3852 		if (reader.isStartElement())
3853 		{
3854 			ScXmlStreamAttributes attrs = reader.scAttributes();
3855 			NoteFrameData eF;
3856 			eF.NSname = attrs.valueAsString("NSname");
3857 			eF.myID = attrs.valueAsInt("myID");
3858 			if (reader.name() == "ENDNOTEFRAME")
3859 			{
3860 				eF.index = attrs.valueAsInt("index");
3861 				eF.NSrange = (NumerationRange) attrs.valueAsInt("range");
3862 				 // Fix deprecated numeration ranges
3863 				if (eF.NSrange != NSRdocument && eF.NSrange != NSRstory)
3864 					eF.NSrange = NSRstory;
3865 				eF.itemID = attrs.valueAsInt("ItemID");
3866 			}
3867 			if (reader.name() == "FOOTNOTEFRAME")
3868 				eF.itemID = attrs.valueAsInt("MasterID");
3869 			notesFramesData.append(eF);
3870 		}
3871 	}
3872 	return !reader.hasError();
3873 }
3874 
readNotes(ScribusDoc * doc,ScXmlStreamReader & reader)3875 bool Scribus150Format::readNotes(ScribusDoc* doc, ScXmlStreamReader& reader)
3876 {
3877 	//read notes
3878 	QStringRef tagName = reader.name();
3879 	while (!reader.atEnd() && !reader.hasError())
3880 	{
3881 		reader.readNext();
3882 		if (reader.isEndElement() && reader.name() == tagName)
3883 			break;
3884 		if (reader.isStartElement() && reader.name() == "Note")
3885 		{
3886 			ScXmlStreamAttributes attrs = reader.scAttributes();
3887 			TextNote* note = m_Doc->newNote(nullptr);
3888 			note->setSaxedText(attrs.valueAsString("Text"));
3889 			//temporaly insert names of master mark and notes style into maps with note pointer
3890 			//will be resolved to pointers by updateNames2Ptr() after all will read
3891 			notesMasterMarks.insert(attrs.valueAsString("Master"), note);
3892 			notesNSets.insert(note, attrs.valueAsString("NStyle"));
3893 		}
3894 	}
3895 	return !reader.hasError();
3896 }
3897 
readMarks(ScribusDoc * doc,ScXmlStreamReader & reader)3898 bool Scribus150Format::readMarks(ScribusDoc* doc, ScXmlStreamReader& reader)
3899 {
3900 	QStringRef tagName = reader.name();
3901 	while (!reader.atEnd() && !reader.hasError())
3902 	{
3903 		reader.readNext();
3904 		if (reader.isEndElement() && reader.name() == tagName)
3905 			break;
3906 		if (reader.isStartElement() && reader.name() == "Mark")
3907 		{
3908 			ScXmlStreamAttributes attrs = reader.scAttributes();
3909 
3910 			QString label;
3911 			if (attrs.hasAttribute("label"))
3912 				label = attrs.valueAsString("label");
3913 
3914 			MarkType type = MARKNoType;
3915 			if (attrs.hasAttribute("type"))
3916 				type = (MarkType) attrs.valueAsInt("type");
3917 
3918 			if (!label.isEmpty() && type != MARKNoType)
3919 			{
3920 				Mark* mark = doc->newMark();
3921 				mark->label=attrs.valueAsString("label");
3922 				mark->setType(type);
3923 				if (type == MARKVariableTextType && attrs.hasAttribute("str"))
3924 					mark->setString(attrs.valueAsString("str"));
3925 				if (type == MARK2ItemType && attrs.hasAttribute("ItemID"))
3926 				{
3927 					//QString itemName = attrs.valueAsString("itemName");
3928 					markeredItemsMap.insert(mark, attrs.valueAsInt("ItemID"));
3929 				}
3930 				if (type == MARK2MarkType && attrs.hasAttribute("MARKlabel"))
3931 				{
3932 					QString mark2Label = attrs.valueAsString("MARKlabel");
3933 					MarkType mark2Type = (MarkType) attrs.valueAsInt("MARKtype");
3934 					Mark* mark2 = doc->getMark(mark2Label, mark2Type);
3935 					if (mark2 != nullptr) //mark is not defined yet, insert into temp list for update to pointers later
3936 						mark->setMark(mark2);
3937 					else
3938 					{
3939 						QMap<QString, MarkType> mark2map;
3940 						mark2map.insert(mark2Label, mark2Type);
3941 						markeredMarksMap.insert(mark, mark2map);
3942 					}
3943 				}
3944 			}
3945 		}
3946 	}
3947 	return !reader.hasError();
3948 }
3949 
readSections(ScribusDoc * doc,ScXmlStreamReader & reader)3950 bool Scribus150Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
3951 {
3952 	QStringRef tagName = reader.name();
3953 	while (!reader.atEnd() && !reader.hasError())
3954 	{
3955 		reader.readNext();
3956 		if (reader.isEndElement() && reader.name() == tagName)
3957 			break;
3958 		if (reader.isStartElement() && reader.name() == "Section")
3959 		{
3960 			ScXmlStreamAttributes attrs = reader.scAttributes();
3961 			struct DocumentSection newSection;
3962 			newSection.number = attrs.valueAsInt("Number");
3963 			newSection.name   = attrs.valueAsString("Name");
3964 			newSection.fromindex = attrs.valueAsInt("From");
3965 			newSection.toindex   = attrs.valueAsInt("To");
3966 			QString type = attrs.valueAsString("Type");
3967 			if (type == "Type_1_2_3")
3968 				newSection.type=Type_1_2_3;
3969 			if (type == "Type_1_2_3_ar")
3970 				newSection.type=Type_1_2_3_ar;
3971 			if (type == "Type_i_ii_iii")
3972 				newSection.type=Type_i_ii_iii;
3973 			if (type == "Type_I_II_III")
3974 				newSection.type=Type_I_II_III;
3975 			if (type == "Type_a_b_c")
3976 				newSection.type=Type_a_b_c;
3977 			if (type == "Type_A_B_C")
3978 				newSection.type=Type_A_B_C;
3979 			if (type == "Type_Alphabet_ar")
3980 				newSection.type=Type_Alphabet_ar;
3981 			if (type == "Type_Abjad_ar")
3982 				newSection.type=Type_Abjad_ar;
3983 			if (type == "Type_Hebrew")
3984 				newSection.type=Type_Hebrew;
3985 			if (type == "Type_CJK")
3986 				newSection.type=Type_CJK;
3987 			if (type == "Type_None")
3988 				newSection.type=Type_None;
3989 			newSection.sectionstartindex = attrs.valueAsInt("Start");
3990 			newSection.reversed = attrs.valueAsBool("Reversed");
3991 			newSection.active = attrs.valueAsBool("Active");
3992 			if (attrs.hasAttribute("FillChar"))
3993 				newSection.pageNumberFillChar = QChar(attrs.valueAsInt("FillChar"));
3994 			else
3995 				newSection.pageNumberFillChar = QChar();
3996 			if (attrs.hasAttribute("FieldWidth"))
3997 				newSection.pageNumberWidth = attrs.valueAsInt("FieldWidth");
3998 			else
3999 				newSection.pageNumberWidth = 0;
4000 			doc->sections().insert(newSection.number, newSection);
4001 		}
4002 	}
4003 	return !reader.hasError();
4004 }
4005 
readHyphen(ScribusDoc * doc,ScXmlStreamReader & reader)4006 bool Scribus150Format::readHyphen(ScribusDoc *doc, ScXmlStreamReader& reader)
4007 {
4008 	if (!doc->docHyphenator)
4009 		doc->createHyphenator();
4010 
4011 	QStringRef tagName = reader.name();
4012 	while (!reader.atEnd() && !reader.hasError())
4013 	{
4014 		reader.readNext();
4015 		if (reader.isEndElement() && reader.name() == tagName)
4016 			break;
4017 		if (reader.isStartElement() && reader.name() == "EXCEPTION")
4018 		{
4019 			ScXmlStreamAttributes attrs = reader.scAttributes();
4020 			QString word = attrs.valueAsString("WORD");
4021 			QString hyph = attrs.valueAsString("HYPHENATED");
4022 			doc->docHyphenator->specialWords.insert(word, hyph);
4023 		}
4024 		else if (reader.isStartElement() && reader.name() == "IGNORE")
4025 		{
4026 			ScXmlStreamAttributes attrs = reader.scAttributes();
4027 			QString word = attrs.valueAsString("WORD");
4028 			doc->docHyphenator->ignoredWords.insert(word);
4029 		}
4030 	}
4031 	return !reader.hasError();
4032 }
4033 
readPage(ScribusDoc * doc,ScXmlStreamReader & reader)4034 bool Scribus150Format::readPage(ScribusDoc* doc, ScXmlStreamReader& reader)
4035 {
4036 	QStringRef tagName = reader.name();
4037 
4038 	ScXmlStreamAttributes attrs = reader.scAttributes();
4039 	int     pageNum  = attrs.valueAsInt("NUM");
4040 	QString pageName = attrs.valueAsString("NAM", "");
4041 	if (tagName == "MASTERPAGE" && pageName.isEmpty())
4042 	{
4043 		qDebug() << "scribus150format: corrupted masterpage with empty name detected";
4044 		return true;
4045 	}
4046 
4047 	bool savedMasterPageMode = m_Doc->masterPageMode();
4048 	m_Doc->setMasterPageMode(!pageName.isEmpty());
4049 	ScPage* newPage = pageName.isEmpty() ? doc->addPage(pageNum) : doc->addMasterPage(pageNum, pageName);
4050 
4051 	newPage->LeftPg   = attrs.valueAsInt("LEFT", 0);
4052 	QString mpName    = attrs.valueAsString("MNAM", "Normal");
4053 	newPage->setMasterPageName(m_Doc->masterPageMode() ? QString() : mpName);
4054 	if (attrs.hasAttribute("Size"))
4055 		newPage->setSize(attrs.valueAsString("Size"));
4056 	if (attrs.hasAttribute("Orientation"))
4057 		newPage->setOrientation(attrs.valueAsInt("Orientation"));
4058 	newPage->setXOffset(attrs.valueAsDouble("PAGEXPOS"));
4059 	newPage->setYOffset(attrs.valueAsDouble("PAGEYPOS"));
4060 	if (attrs.hasAttribute("PAGEWIDTH"))
4061 		newPage->setWidth(attrs.valueAsDouble("PAGEWIDTH"));
4062 	else
4063 		newPage->setWidth(attrs.valueAsDouble("PAGEWITH"));
4064 	newPage->setHeight(attrs.valueAsDouble("PAGEHEIGHT"));
4065 
4066 	//14704: Double check the page size should not be Custom in case the size doesn't match a standard size
4067 	if (attrs.hasAttribute("Size"))
4068 	{
4069 		QString pageSize(attrs.valueAsString("Size"));
4070 		PageSize ps(pageSize);
4071 		if (!compareDouble(ps.width(), newPage->width()) || !compareDouble(ps.height(), newPage->height()))
4072 			newPage->setSize(CommonStrings::customPageSize);
4073 		else
4074 			newPage->setSize(pageSize);
4075 	}
4076 
4077 	newPage->setInitialHeight(newPage->height());
4078 	newPage->setInitialWidth(newPage->width());
4079 	newPage->initialMargins.setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
4080 	newPage->initialMargins.setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
4081 	newPage->initialMargins.setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
4082 	newPage->initialMargins.setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
4083 	newPage->marginPreset = attrs.valueAsInt("PRESET", 0);
4084 	newPage->Margins.setTop(newPage->initialMargins.top());
4085 	newPage->Margins.setBottom(newPage->initialMargins.bottom());
4086 
4087 	m_Doc->setMasterPageMode(savedMasterPageMode);
4088 
4089 	// guides reading
4090 	newPage->guides.setHorizontalAutoGap(attrs.valueAsDouble("AGhorizontalAutoGap", 0.0));
4091 	newPage->guides.setVerticalAutoGap(attrs.valueAsDouble("AGverticalAutoGap", 0.0));
4092 	newPage->guides.setHorizontalAutoCount(attrs.valueAsInt("AGhorizontalAutoCount", 0) );
4093 	newPage->guides.setVerticalAutoCount(attrs.valueAsInt("AGverticalAutoCount", 0) );
4094 	newPage->guides.setHorizontalAutoRefer(attrs.valueAsInt("AGhorizontalAutoRefer", 0) );
4095 	newPage->guides.setVerticalAutoRefer(attrs.valueAsInt("AGverticalAutoRefer", 0) );
4096 	GuideManagerIO::readVerticalGuides(attrs.valueAsString("VerticalGuides"),
4097 			newPage,
4098 			GuideManagerCore::Standard,
4099 			attrs.hasAttribute("NumVGuides"));
4100 	GuideManagerIO::readHorizontalGuides(attrs.valueAsString("HorizontalGuides"),
4101 			newPage,
4102 			GuideManagerCore::Standard,
4103 			attrs.hasAttribute("NumHGuides"));
4104 	GuideManagerIO::readSelection(attrs.valueAsString("AGSelection"), newPage);
4105 
4106 	newPage->guides.addHorizontals(newPage->guides.getAutoHorizontals(newPage), GuideManagerCore::Auto);
4107 	newPage->guides.addVerticals(newPage->guides.getAutoVerticals(newPage), GuideManagerCore::Auto);
4108 	struct PDFPresentationData ef;
4109 	ef.pageEffectDuration =  attrs.valueAsInt("pageEffectDuration", 1);
4110 	ef.pageViewDuration =  attrs.valueAsInt("pageViewDuration", 1);
4111 	ef.effectType = attrs.valueAsInt("effectType", 0);
4112 	ef.Dm = attrs.valueAsInt("Dm", 0);
4113 	ef.M  = attrs.valueAsInt("M", 0);
4114 	ef.Di = attrs.valueAsInt("Di", 0);
4115 	newPage->PresentVals = ef;
4116 	return true;
4117 }
4118 
readObject(ScribusDoc * doc,ScXmlStreamReader & reader,const ReadObjectParams & readObjectParams,ItemInfo & info)4119 bool Scribus150Format::readObject(ScribusDoc* doc, ScXmlStreamReader& reader, const ReadObjectParams& readObjectParams, ItemInfo& info)
4120 {
4121 	QStringRef tagName = reader.name();
4122 	ScXmlStreamAttributes attrs = reader.scAttributes();
4123 
4124 	bool savedMasterPageMode = doc->masterPageMode();
4125 	if (!readObjectParams.loadingPage)
4126 	{
4127 		if (tagName == "PAGEOBJECT" || tagName == "FRAMEOBJECT" || tagName == "PatternItem" || tagName == "ITEM")
4128 			doc->setMasterPageMode(false);
4129 		else
4130 			doc->setMasterPageMode(true);
4131 	}
4132 
4133 	PageItem::ItemKind itemKind = PageItem::StandardItem;
4134 	if (tagName =="FRAMEOBJECT")
4135 		itemKind = PageItem::InlineItem;
4136 	else if (tagName =="PatternItem")
4137 		itemKind = PageItem::PatternItem;
4138 
4139 	// We are loading patterns, force itemKind to PatternItem
4140 	if (readObjectParams.itemKind == PageItem::PatternItem)
4141 		itemKind = PageItem::PatternItem;
4142 
4143 	int pageNr = -1;
4144 	QString masterPageName = attrs.valueAsString("OnMasterPage");
4145 	if ((!masterPageName.isEmpty()) && (tagName == "MASTEROBJECT"))
4146 	{
4147 		if (!readObjectParams.renamedMasterPage.isEmpty())
4148 			masterPageName = readObjectParams.renamedMasterPage;
4149 		doc->setCurrentPage(doc->MasterPages.at(doc->MasterNames[masterPageName]));
4150 		pageNr = -2;
4151 	}
4152 	layerFound = false;
4153 	clipPath.clear();
4154 
4155 	PageItem* newItem = pasteItem(doc, attrs, readObjectParams.baseDir, itemKind, pageNr);
4156 	newItem->setRedrawBounding();
4157 	if (tagName == "MASTEROBJECT")
4158 		newItem->setOwnerPage(doc->OnPage(newItem));
4159 	else
4160 		newItem->setOwnerPage(attrs.valueAsInt("OwnPage"));
4161 	if ((tagName == "PAGEOBJECT") || (tagName == "ITEM"))
4162 		newItem->setMasterPageName(QString());
4163 	if (tagName == "ITEM")
4164 	{
4165 		newItem->setLayer(LayerToPaste);
4166 		newItem->setMasterPage(doc->OnPage(newItem), doc->currentPage()->pageName());
4167 	}
4168 	QString tmpf = attrs.valueAsString("IFONT", doc->itemToolPrefs().textFont);
4169 	m_AvailableFonts->findFont(tmpf, doc);
4170 
4171 //	newItem->Language = ScMW->GetLang(pg.attribute("LANGUAGE", doc->Language));
4172 	newItem->isAutoText = attrs.valueAsBool("AUTOTEXT", false);
4173 	newItem->isEmbedded = attrs.valueAsBool("isInline", false);
4174 	newItem->gXpos   = attrs.valueAsDouble("gXpos", 0.0);
4175 	newItem->gYpos   = attrs.valueAsDouble("gYpos", 0.0);
4176 	newItem->gWidth  = attrs.valueAsDouble("gWidth", newItem->width());
4177 	newItem->gHeight = attrs.valueAsDouble("gHeight", newItem->height());
4178 	if (newItem->isAutoText)
4179 		doc->LastAuto = newItem;
4180 
4181 	if (tagName == "FRAMEOBJECT")
4182 	{
4183 		if (newItem->inlineCharID == -1)
4184 			FrameItems.append(m_Doc->Items->takeAt(m_Doc->Items->indexOf(newItem)));
4185 		else
4186 			doc->FrameItems.insert(newItem->inlineCharID, doc->Items->takeAt(doc->Items->indexOf(newItem)));
4187 		newItem->setLayer(doc->firstLayerID());
4188 	}
4189 
4190 	info.item   = newItem;
4191 	isNewFormat = attrs.hasAttribute("ItemID");
4192 	if (isNewFormat)
4193 	{
4194 		info.itemID = attrs.valueAsInt("ItemID", 0);
4195 		LinkID.insert(info.itemID, newItem);
4196 	}
4197 	info.nextItem = attrs.valueAsInt("NEXTITEM", -1);
4198 	if (isNewFormat)
4199 	{
4200 		if (info.nextItem != -1)
4201 			itemNext[info.itemID] = info.nextItem;
4202 	}
4203 	info.ownLink  = newItem->isTableItem ? attrs.valueAsInt("OwnLINK", 0) : 0;
4204 	info.groupLastItem = 0;
4205 	info.isGroupFlag = attrs.valueAsBool("isGroupControl", false);
4206 	if (info.isGroupFlag)
4207 		info.groupLastItem = attrs.valueAsInt("groupsLastItem", 0);
4208 	info.isWeldFlag = attrs.valueAsBool("isWeldItem", false);
4209 	info.ownWeld = attrs.valueAsInt("WeldSource", 0);
4210 	info.ownNr = doc->Items->indexOf(newItem);
4211 
4212 	struct ImageLoadRequest loadingInfo;
4213 #ifdef HAVE_OSG
4214 	struct PageItem_OSGFrame::viewDefinition currentView;
4215 #endif
4216 	QList<ParagraphStyle::TabRecord> tabValues;
4217 
4218 	int mGArrayRows = 0;
4219 	int mGArrayCols = 0;
4220 	LastStyles * lastStyle = new LastStyles();
4221 	while (!reader.atEnd() && !reader.hasError())
4222 	{
4223 		ScXmlStreamReader::TokenType tType = reader.readNext();
4224 		if (reader.isEndElement() && tagName == reader.name())
4225 			break;
4226 		if (tType != ScXmlStreamReader::StartElement)
4227 			continue;
4228 		QStringRef tName = reader.name();
4229 		ScXmlStreamAttributes tAtt = reader.scAttributes();
4230 		if (tName == "CSTOP")
4231 		{
4232 			QString name = tAtt.valueAsString("NAME");
4233 			double ramp  = tAtt.valueAsDouble("RAMP", 0.0);
4234 			int shade    = tAtt.valueAsInt("SHADE", 100);
4235 			double opa   = tAtt.valueAsDouble("TRANS", 1.0);
4236 			newItem->fill_gradient.addStop(SetColor(doc, name, shade), ramp, 0.5, opa, name, shade);
4237 		}
4238 		if (tName == "S_CSTOP")
4239 		{
4240 			QString name = tAtt.valueAsString("NAME");
4241 			double ramp  = tAtt.valueAsDouble("RAMP", 0.0);
4242 			int shade    = tAtt.valueAsInt("SHADE", 100);
4243 			double opa   = tAtt.valueAsDouble("TRANS", 1.0);
4244 			newItem->stroke_gradient.addStop(SetColor(doc, name, shade), ramp, 0.5, opa, name, shade);
4245 		}
4246 		if (tName == "M_CSTOP")
4247 		{
4248 			QString name = tAtt.valueAsString("NAME");
4249 			double ramp  = tAtt.valueAsDouble("RAMP", 0.0);
4250 			int shade    = tAtt.valueAsInt("SHADE", 100);
4251 			double opa   = tAtt.valueAsDouble("TRANS", 1.0);
4252 			newItem->mask_gradient.addStop(SetColor(doc, name, shade), ramp, 0.5, opa, name, shade);
4253 		}
4254 		if (tName == "MPoint")
4255 		{
4256 			MeshPoint mp;
4257 			mp.colorName     = tAtt.valueAsString("NAME");
4258 			mp.shade         = tAtt.valueAsInt("SHADE", 100);
4259 			mp.transparency  = tAtt.valueAsDouble("TRANS", 1.0);
4260 			mp.gridPoint     = FPoint(tAtt.valueAsDouble("GX", 0.0), tAtt.valueAsDouble("GY", 0.0));
4261 			mp.controlTop    = FPoint(tAtt.valueAsDouble("CTX", 0.0), tAtt.valueAsDouble("CTY", 0.0));
4262 			mp.controlBottom = FPoint(tAtt.valueAsDouble("CBX", 0.0), tAtt.valueAsDouble("CBY", 0.0));
4263 			mp.controlLeft   = FPoint(tAtt.valueAsDouble("CLX", 0.0), tAtt.valueAsDouble("CLY", 0.0));
4264 			mp.controlRight  = FPoint(tAtt.valueAsDouble("CRX", 0.0), tAtt.valueAsDouble("CRY", 0.0));
4265 			mp.controlColor  = FPoint(tAtt.valueAsDouble("CCX", mp.gridPoint.x()), tAtt.valueAsDouble("CCY", mp.gridPoint.y()));
4266 			mp.color         = SetColor(doc, mp.colorName, mp.shade);
4267 			mp.color.setAlphaF(mp.transparency);
4268 			newItem->meshGradientArray[mGArrayRows][mGArrayCols] = mp;
4269 			mGArrayCols++;
4270 			if (mGArrayCols == newItem->meshGradientArray[mGArrayRows].count())
4271 			{
4272 				mGArrayCols = 0;
4273 				mGArrayRows++;
4274 			}
4275 		}
4276 		if (tName == "PMPoint")
4277 		{
4278 			MeshPoint mp;
4279 			mp.colorName     = tAtt.valueAsString("NAME");
4280 			mp.shade         = tAtt.valueAsInt("SHADE", 100);
4281 			mp.transparency  = tAtt.valueAsDouble("TRANS", 1.0);
4282 			mp.gridPoint     = FPoint(tAtt.valueAsDouble("GX", 0.0), tAtt.valueAsDouble("GY", 0.0));
4283 			mp.controlTop    = FPoint(tAtt.valueAsDouble("CTX", mp.gridPoint.x()), tAtt.valueAsDouble("CTY", mp.gridPoint.y()));
4284 			mp.controlBottom = FPoint(tAtt.valueAsDouble("CBX", mp.gridPoint.x()), tAtt.valueAsDouble("CBY", mp.gridPoint.y()));
4285 			mp.controlLeft   = FPoint(tAtt.valueAsDouble("CLX", mp.gridPoint.x()), tAtt.valueAsDouble("CLY", mp.gridPoint.y()));
4286 			mp.controlRight  = FPoint(tAtt.valueAsDouble("CRX", mp.gridPoint.x()), tAtt.valueAsDouble("CRY", mp.gridPoint.y()));
4287 			mp.controlColor  = FPoint(tAtt.valueAsDouble("CCX", mp.gridPoint.x()), tAtt.valueAsDouble("CCY", mp.gridPoint.y()));
4288 			mp.color         = SetColor(doc, mp.colorName, mp.shade);
4289 			mp.color.setAlphaF(mp.transparency);
4290 			if (mGArrayCols == 0)
4291 				newItem->meshGradientPatches[mGArrayRows].TL = mp;
4292 			else if (mGArrayCols == 1)
4293 				newItem->meshGradientPatches[mGArrayRows].TR = mp;
4294 			else if (mGArrayCols == 2)
4295 				newItem->meshGradientPatches[mGArrayRows].BR = mp;
4296 			else if (mGArrayCols == 3)
4297 				newItem->meshGradientPatches[mGArrayRows].BL = mp;
4298 			mGArrayCols++;
4299 			if (mGArrayCols == 4)
4300 			{
4301 				mGArrayCols = 0;
4302 				mGArrayRows++;
4303 			}
4304 		}
4305 
4306 		if (tName == "ITEXT")
4307 			readItemText(newItem->itemText, tAtt, lastStyle);
4308 		else if (tName == "TableData")
4309 		{
4310 			readItemTableData(newItem->asTable(), reader, doc);
4311 		}
4312 		else if (tName == "para")
4313 		{
4314 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PARSEP);
4315 			ParagraphStyle newStyle;
4316 			readParagraphStyle(doc, reader, newStyle);
4317 			newItem->itemText.setStyle(newItem->itemText.length()-1, newStyle);
4318 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, lastStyle->Style);
4319 		}
4320 		else if (tName == "trail")
4321 		{
4322 			ParagraphStyle newStyle;
4323 			readParagraphStyle(doc, reader, newStyle);
4324 			newItem->itemText.setStyle(newItem->itemText.length(), newStyle);
4325 		}
4326 		else if (tName == "tab")
4327 		{
4328 			CharStyle newStyle;
4329 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::TAB);
4330 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4331 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4332 			lastStyle->StyleStart = newItem->itemText.length()-1;
4333 			lastStyle->Style = newStyle;
4334 		}
4335 		else if (tName == "breakline")
4336 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::LINEBREAK);
4337 		else if (tName == "breakcol")
4338 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::COLBREAK);
4339 		else if (tName == "breakframe")
4340 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::FRAMEBREAK);
4341 		else if (tName == "nbhyphen")
4342 		{
4343 			CharStyle newStyle;
4344 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::NBHYPHEN);
4345 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4346 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4347 			lastStyle->StyleStart = newItem->itemText.length()-1;
4348 			lastStyle->Style = newStyle;
4349 		}
4350 		else if (tName == "nbspace")
4351 		{
4352 			CharStyle newStyle;
4353 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::NBSPACE);
4354 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4355 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4356 			lastStyle->StyleStart = newItem->itemText.length()-1;
4357 			lastStyle->Style = newStyle;
4358 		}
4359 		else if (tName == "zwnbspace")
4360 		{
4361 			CharStyle newStyle;
4362 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::ZWNBSPACE);
4363 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4364 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4365 			lastStyle->StyleStart = newItem->itemText.length()-1;
4366 			lastStyle->Style = newStyle;
4367 		}
4368 		else if (tName == "zwspace")
4369 		{
4370 			CharStyle newStyle;
4371 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::ZWSPACE);
4372 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4373 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4374 			lastStyle->StyleStart = newItem->itemText.length()-1;
4375 			lastStyle->Style = newStyle;
4376 		}
4377 		else if (tName == "var")
4378 		{
4379 			CharStyle newStyle;
4380 			if (tAtt.value("name") == "pgno")
4381 				newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PAGENUMBER);
4382 			else
4383 				newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PAGECOUNT);
4384 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4385 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
4386 			lastStyle->StyleStart = newItem->itemText.length()-1;
4387 			lastStyle->Style = newStyle;
4388 		}
4389 		if (tName == "PageItemAttributes")
4390 		{
4391 			readPageItemAttributes(newItem, reader);
4392 		}
4393 		if (tName == "PSDLayer")
4394 		{
4395 			layerFound = true;
4396 			loadingInfo.blend   = tAtt.valueAsString("Blend");
4397 			loadingInfo.opacity = tAtt.valueAsInt("Opacity");
4398 			loadingInfo.visible = tAtt.valueAsBool("Visible");
4399 			loadingInfo.useMask = tAtt.valueAsBool("useMask", true);
4400 			newItem->pixm.imgInfo.RequestProps.insert(tAtt.valueAsInt("Layer"), loadingInfo);
4401 		}
4402 #ifdef HAVE_OSG
4403 		if (tName == "OSGViews")
4404 		{
4405 			currentView.angleFOV = tAtt.valueAsDouble("angleFOV");
4406 			QString tmp = "";
4407 			tmp = tAtt.valueAsString("trackM");
4408 			ScTextStream fp(&tmp, QIODevice::ReadOnly);
4409 			double m1, m2, m3, m4;
4410 			double m5, m6, m7, m8;
4411 			double m9, m10, m11, m12;
4412 			double m13, m14, m15, m16;
4413 			fp >> m1 >> m2 >> m3 >> m4;
4414 			fp >> m5 >> m6 >> m7 >> m8;
4415 			fp >> m9 >> m10 >> m11 >> m12;
4416 			fp >> m13 >> m14 >> m15 >> m16;
4417 			currentView.trackerMatrix.set(m1, m2, m3, m4, m5, m6, m7, m8, m9, m10, m11, m12, m13, m14, m15, m16);
4418 			tmp = "";
4419 			tmp = tAtt.valueAsString("trackC");
4420 			ScTextStream fp2(&tmp, QIODevice::ReadOnly);
4421 			double v1, v2, v3;
4422 			fp2 >> v1 >> v2 >> v3;
4423 			currentView.trackerCenter.set(v1, v2, v3);
4424 			tmp = "";
4425 			tmp = tAtt.valueAsString("cameraP");
4426 			ScTextStream fp3(&tmp, QIODevice::ReadOnly);
4427 			fp3 >> v1 >> v2 >> v3;
4428 			currentView.cameraPosition.set(v1, v2, v3);
4429 			tmp = "";
4430 			tmp = tAtt.valueAsString("cameraU");
4431 			ScTextStream fp4(&tmp, QIODevice::ReadOnly);
4432 			fp4 >> v1 >> v2 >> v3;
4433 			currentView.cameraUp.set(v1, v2, v3);
4434 			currentView.trackerDist = tAtt.valueAsDouble("trackerDist");
4435 			currentView.trackerSize = tAtt.valueAsDouble("trackerSize");
4436 			currentView.illumination = static_cast<PageItem_OSGFrame::LightType>(tAtt.valueAsInt("illumination"));
4437 			currentView.rendermode = static_cast<PageItem_OSGFrame::RenderType>(tAtt.valueAsInt("rendermode"));
4438 			currentView.addedTransparency = tAtt.valueAsDouble("trans");
4439 			currentView.colorAC = QColor(tAtt.valueAsString("colorAC"));
4440 			currentView.colorFC = QColor(tAtt.valueAsString("colorFC"));
4441 			if (newItem->isOSGFrame())
4442 				newItem->asOSGFrame()->viewMap.insert(tAtt.valueAsString("viewName"), currentView);
4443 		}
4444 #endif
4445 		if (tName == "ImageEffect")
4446 		{
4447 			struct ImageEffect ef;
4448 			ef.effectParameters = tAtt.valueAsString("Param");
4449 			ef.effectCode = tAtt.valueAsInt("Code");
4450 			newItem->effectsInUse.append(ef);
4451 		}
4452 		if (tName == "StoryText")
4453 			readStoryText(doc, reader, newItem->itemText, newItem);
4454 		if (tName == "Tabs")
4455 		{
4456 			ParagraphStyle::TabRecord tb;
4457 			tb.tabPosition = tAtt.valueAsDouble("Pos");
4458 			tb.tabType     = tAtt.valueAsInt("Type");
4459 			QString tbCh   = tAtt.valueAsString("Fill", "");
4460 			tb.tabFillChar = tbCh.isEmpty() ? QChar() : tbCh[0];
4461 			tabValues.append(tb);
4462 		}
4463 		if (tName == "LATEX")
4464 		{
4465 			if (newItem->isLatexFrame())
4466 			{
4467 				readLatexInfo(newItem->asLatexFrame(), reader);
4468 			}
4469 			else
4470 			{
4471 				while (!reader.atEnd() && !reader.hasError())
4472 				{
4473 					reader.readNext();
4474 					if (reader.isEndElement() && reader.name() == tName)
4475 						break;
4476 				}
4477 			}
4478 		}
4479 		if ((tName == "PAGEOBJECT") || (tName == "ITEM"))
4480 		{
4481 			if (newItem->isGroup())
4482 			{
4483 			//	bool success = true;
4484 				QList<PageItem*>* docItems = doc->Items;
4485 				QList<PageItem*> groupItems;
4486 				doc->Items = &groupItems;
4487 				ItemInfo itemInfo;
4488 				// #12313: set the 'loadPage' parameter to true in order to
4489 				// avoid the change of page mode and the doc item lists switch
4490 				// when loading groups in masterpages
4491 				ReadObjectParams readObjectParams2;
4492 				readObjectParams2.baseDir = readObjectParams.baseDir;
4493 				readObjectParams2.itemKind = (itemKind == PageItem::PatternItem) ? PageItem::PatternItem : PageItem::StandardItem;
4494 				readObjectParams2.loadingPage = true;
4495 				readObject(doc, reader, readObjectParams2, itemInfo);
4496 				for (int as = 0; as < groupItems.count(); ++as)
4497 				{
4498 					PageItem* currItem = groupItems.at(as);
4499 					newItem->groupItemList.append(currItem);
4500 					currItem->Parent = newItem;
4501 					currItem->m_layerID = newItem->m_layerID;
4502 					currItem->OwnPage = newItem->OwnPage;
4503 					currItem->OnMasterPage = newItem->OnMasterPage;
4504 				}
4505 				doc->Items = docItems;
4506 			}
4507 		}
4508 		if (tName == "MARK")
4509 		{
4510 			if (newItem->isTextFrame())
4511 			{
4512 				QString l = tAtt.valueAsString("label");
4513 				MarkType t = (MarkType) tAtt.valueAsInt("type");
4514 				Mark* mark = nullptr;
4515 				if (m_Doc->isLoading())
4516 				{
4517 					mark = m_Doc->getMark(l, t);
4518 				}
4519 				else
4520 				{	//doc is not loading so it is copy/paste task
4521 					if (t == MARKVariableTextType)
4522 						mark = m_Doc->getMark(l, t);
4523 					else
4524 					{
4525 						//create copy of mark
4526 						Mark* oldMark = m_Doc->getMark(l, t);
4527 						if (oldMark == nullptr)
4528 						{
4529 							qWarning() << "wrong copy of oldMark";
4530 							mark = m_Doc->newMark();
4531 							mark->setType(t);
4532 						}
4533 						else
4534 						{
4535 							mark = m_Doc->newMark(oldMark);
4536 							getUniqueName(l,doc->marksLabelsList(t), "_");
4537 						}
4538 						mark->label = l;
4539 						if (t == MARKNoteMasterType)
4540 						{  //create copy of note
4541 							TextNote* old = mark->getNotePtr();
4542 							TextNote* note = m_Doc->newNote(old->notesStyle());
4543 							mark->setNotePtr(note);
4544 							note->setMasterMark(mark);
4545 							note->setSaxedText(old->saxedText());
4546 							m_Doc->setNotesChanged(true);
4547 						}
4548 					}
4549 				}
4550 				if (mark == nullptr)
4551 					qDebug() << "Undefined mark label ["<< l << "] type " << t;
4552 				else
4553 				{
4554 					//set pointer to item holds mark in his text
4555 					CharStyle newStyle;
4556 					if (t == MARKAnchorType)
4557 						mark->setItemPtr(newItem);
4558 					mark->OwnPage = newItem->OwnPage;
4559 					newItem->itemText.insertMark(mark, newItem->itemText.length());
4560 					readCharacterStyleAttrs(doc, tAtt, newStyle);
4561 					newItem->itemText.setCharStyle(newItem->itemText.length() - 1, 1, newStyle);
4562 					lastStyle->StyleStart = newItem->itemText.length() - 1;
4563 					lastStyle->Style = newStyle;
4564 				}
4565 			}
4566 		}
4567 		if (tName == "WeldEntry")
4568 		{
4569 			PageItem::WeldingInfo wInf;
4570 			wInf.weldItem = nullptr;
4571 			wInf.weldPoint = FPoint(tAtt.valueAsDouble("WX", 0.0), tAtt.valueAsDouble("WY", 0.0));
4572 			wInf.weldID = tAtt.valueAsInt("Target", 0);
4573 			newItem->weldList.append(wInf);
4574 		}
4575 	}
4576 	delete lastStyle;
4577 
4578 	if (tabValues.count() > 0)
4579 	{
4580 		ParagraphStyle newDefault(newItem->itemText.defaultStyle());
4581 		newDefault.setTabValues(tabValues);
4582 		newItem->itemText.setDefaultStyle(newDefault);
4583 	}
4584 
4585 	if (newItem->fill_gradient.stops() == 0)
4586 	{
4587 		const ScColor& col1 = doc->PageColors[doc->itemToolPrefs().shapeFillColor];
4588 		const ScColor& col2 = doc->PageColors[doc->itemToolPrefs().shapeLineColor];
4589 		newItem->fill_gradient.addStop(ScColorEngine::getRGBColor(col1, doc), 0.0, 0.5, 1.0, doc->itemToolPrefs().shapeFillColor, 100);
4590 		newItem->fill_gradient.addStop(ScColorEngine::getRGBColor(col2, doc), 1.0, 0.5, 1.0, doc->itemToolPrefs().shapeLineColor, 100);
4591 	}
4592 
4593 	if (newItem->stroke_gradient.stops() == 0)
4594 	{
4595 		const ScColor& col1 = doc->PageColors[doc->itemToolPrefs().shapeFillColor];
4596 		const ScColor& col2 = doc->PageColors[doc->itemToolPrefs().shapeLineColor];
4597 		newItem->stroke_gradient.addStop(ScColorEngine::getRGBColor(col1, doc), 0.0, 0.5, 1.0, doc->itemToolPrefs().shapeFillColor, 100);
4598 		newItem->stroke_gradient.addStop(ScColorEngine::getRGBColor(col2, doc), 1.0, 0.5, 1.0, doc->itemToolPrefs().shapeLineColor, 100);
4599 	}
4600 
4601 	if (newItem->mask_gradient.stops() == 0)
4602 	{
4603 		const ScColor& col1 = doc->PageColors[doc->itemToolPrefs().shapeFillColor];
4604 		const ScColor& col2 = doc->PageColors[doc->itemToolPrefs().shapeLineColor];
4605 		newItem->mask_gradient.addStop(ScColorEngine::getRGBColor(col1, doc), 0.0, 0.5, 1.0, doc->itemToolPrefs().shapeFillColor, 100);
4606 		newItem->mask_gradient.addStop(ScColorEngine::getRGBColor(col2, doc), 1.0, 0.5, 1.0, doc->itemToolPrefs().shapeLineColor, 100);
4607 	}
4608 	if (newItem->GrType == Gradient_Conical)
4609 	{
4610 		if (!newItem->gradient().isEmpty())
4611 			newItem->fill_gradient = doc->docGradients[newItem->gradient()];
4612 		newItem->createConicalMesh();
4613 	}
4614 
4615 	if (newItem->isPathText())
4616 		newItem->updatePolyClip();
4617 #ifdef HAVE_OSG
4618 	if (newItem->isImageFrame() || newItem->isLatexFrame() || newItem->isOSGFrame())
4619 #else
4620 	if (newItem->isImageFrame() || newItem->isLatexFrame())
4621 #endif
4622 	{
4623 		if (!newItem->Pfile.isEmpty())
4624 		{
4625 			double imageXOffset = newItem->imageXOffset();
4626 			double imageYOffset = newItem->imageYOffset();
4627 			doc->loadPict(newItem->Pfile, newItem, false);
4628 			newItem->setImageXYOffset(imageXOffset, imageYOffset);
4629 			if (newItem->pixm.imgInfo.PDSpathData.contains(clipPath))
4630 			{
4631 				newItem->imageClip = newItem->pixm.imgInfo.PDSpathData[clipPath].copy();
4632 				newItem->pixm.imgInfo.usedPath = clipPath;
4633 				QTransform cl;
4634 				cl.translate(newItem->imageXOffset()*newItem->imageXScale(), newItem->imageYOffset()*newItem->imageYScale());
4635 				cl.scale(newItem->imageXScale(), newItem->imageYScale());
4636 				newItem->imageClip.map(cl);
4637 			}
4638 			if (layerFound)
4639 			{
4640 				newItem->pixm.imgInfo.isRequest = true;
4641 				doc->loadPict(newItem->Pfile, newItem, true);
4642 				newItem->setImageXYOffset(imageXOffset, imageYOffset);
4643 			}
4644 		}
4645 	}
4646 	if (!readObjectParams.loadingPage)
4647 		doc->setMasterPageMode(savedMasterPageMode);
4648 	return !reader.hasError();
4649 }
4650 
readPattern(ScribusDoc * doc,ScXmlStreamReader & reader,const QString & baseDir)4651 bool Scribus150Format::readPattern(ScribusDoc* doc, ScXmlStreamReader& reader, const QString& baseDir)
4652 {
4653 	ScPattern pat;
4654 	ScXmlStreamAttributes attrs = reader.scAttributes();
4655 	QString patternName = attrs.valueAsString("Name");
4656 	bool success = true;
4657 	isNewFormat = false;
4658 
4659 	if (patternName.isEmpty())
4660 	{
4661 		reader.readToElementEnd();
4662 		return true;
4663 	}
4664 
4665 	QStack< QList<PageItem*> > groupStack;
4666 	QStack< QList<PageItem*> > groupStackP;
4667 	QStack<int> groupStack2;
4668 	QMap<int, PageItem*> TableID2;
4669 	QList<PageItem*> TableItems2;
4670 	QMap<int, PageItem*> WeldID;
4671 	QList<PageItem*> WeldItems;
4672 
4673 	pat.setDoc(doc);
4674 	pat.width   = attrs.valueAsDouble("width", 0.0);
4675 	pat.height  = attrs.valueAsDouble("height", 0.0);
4676 	pat.scaleX  = attrs.valueAsDouble("scaleX", 0.0);
4677 	pat.scaleY  = attrs.valueAsDouble("scaleY", 0.0);
4678 	pat.xoffset = attrs.valueAsDouble("xoffset", 0.0);
4679 	pat.yoffset = attrs.valueAsDouble("yoffset", 0.0);
4680 
4681 	ReadObjectParams readObjectParams;
4682 	readObjectParams.baseDir = baseDir;
4683 	readObjectParams.itemKind = PageItem::PatternItem;
4684 	readObjectParams.loadingPage = false;
4685 
4686 	bool savedAlignGrid = m_Doc->SnapGrid;
4687 	bool savedAlignGuides = m_Doc->SnapGuides;
4688 	bool savedAlignElement = m_Doc->SnapElement;
4689 	bool savedMasterPageMode = m_Doc->masterPageMode();
4690 	m_Doc->SnapGrid  = false;
4691 	m_Doc->SnapGuides = false;
4692 	m_Doc->SnapElement = false;
4693 
4694 	m_Doc->setMasterPageMode(false);
4695 	int itemCount1 = m_Doc->Items->count();
4696 
4697 	QStringRef tagName = reader.name();
4698 	while (!reader.atEnd() && !reader.hasError())
4699 	{
4700 		reader.readNext();
4701 		if (reader.isEndElement() && reader.name() == tagName)
4702 			break;
4703 		if (!reader.isStartElement() || reader.name() != "PatternItem")
4704 			continue;
4705 
4706 		ScXmlStreamAttributes tAtt = reader.attributes();
4707 
4708 		ItemInfo itemInfo;
4709 
4710 		success = readObject(doc, reader, readObjectParams, itemInfo);
4711 		if (!success) break;
4712 
4713 		itemInfo.item->OwnPage = -1 /*ownPage*/;
4714 		itemInfo.item->OnMasterPage.clear();
4715 		if (isNewFormat)
4716 		{
4717 			if (itemInfo.item->isTableItem)
4718 				TableItems2.append(itemInfo.item);
4719 			if (itemInfo.isWeldFlag)
4720 				WeldItems.append(itemInfo.item);
4721 		}
4722 		else
4723 		{
4724 			if (itemInfo.item->isTableItem)
4725 			{
4726 				TableItems2.append(itemInfo.item);
4727 				TableID2.insert(itemInfo.ownLink, itemInfo.item);
4728 			}
4729 			if (itemInfo.isWeldFlag)
4730 			{
4731 				WeldItems.append(itemInfo.item);
4732 				WeldID.insert(itemInfo.ownWeld, itemInfo.item);
4733 			}
4734 		}
4735 		if (groupStack.count() > 0)
4736 		{
4737 			groupStack.top().append(itemInfo.item);
4738 			while (itemInfo.ownNr == groupStack2.top())
4739 			{
4740 				groupStackP.push(groupStack.pop());
4741 				groupStack2.pop();
4742 				if (groupStack2.count() == 0)
4743 					break;
4744 			}
4745 		}
4746 		if (itemInfo.isGroupFlag)
4747 		{
4748 			QList<PageItem*> GroupItems;
4749 			GroupItems.append(itemInfo.item);
4750 			groupStack.push(GroupItems);
4751 			groupStack2.push(itemInfo.groupLastItem + itemInfo.ownNr);
4752 		}
4753 	}
4754 
4755 	doc->SnapGrid   = savedAlignGrid;
4756 	doc->SnapGuides = savedAlignGuides;
4757 	doc->SnapElement = savedAlignElement;
4758 	if (!success)
4759 	{
4760 		doc->setMasterPageMode(savedMasterPageMode);
4761 		return false;
4762 	}
4763 	if (isNewFormat)
4764 	{
4765 		if (TableItems2.count() != 0)
4766 		{
4767 			for (int ttc = 0; ttc < TableItems2.count(); ++ttc)
4768 			{
4769 				PageItem* ta = TableItems2.at(ttc);
4770 				if (ta->TopLinkID != -1)
4771 					ta->m_topLink = LinkID[ta->TopLinkID];
4772 				else
4773 					ta->m_topLink = nullptr;
4774 				if (ta->LeftLinkID != -1)
4775 					ta->m_leftLink = LinkID[ta->LeftLinkID];
4776 				else
4777 					ta->m_leftLink = nullptr;
4778 				if (ta->RightLinkID != -1)
4779 					ta->m_rightLink = LinkID[ta->RightLinkID];
4780 				else
4781 					ta->m_rightLink = nullptr;
4782 				if (ta->BottomLinkID != -1)
4783 					ta->m_bottomLink = LinkID[ta->BottomLinkID];
4784 				else
4785 					ta->m_bottomLink = nullptr;
4786 			}
4787 		}
4788 		if (WeldItems.count() != 0)
4789 		{
4790 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
4791 			{
4792 				PageItem* ta = WeldItems.at(ttc);
4793 				for (int i = 0 ; i < ta->weldList.count(); ++i)
4794 				{
4795 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
4796 					ta->weldList[i].weldItem = LinkID.value(wInf.weldID, 0);
4797 					if (ta->weldList[i].weldItem == nullptr)
4798 						ta->weldList.removeAt(i--);
4799 				}
4800 			}
4801 		}
4802 	}
4803 	else
4804 	{
4805 		if (TableItems2.count() != 0)
4806 		{
4807 			for (int ttc = 0; ttc < TableItems2.count(); ++ttc)
4808 			{
4809 				PageItem* ta = TableItems2.at(ttc);
4810 				if (ta->TopLinkID != -1)
4811 					ta->m_topLink = TableID2[ta->TopLinkID];
4812 				else
4813 					ta->m_topLink = nullptr;
4814 				if (ta->LeftLinkID != -1)
4815 					ta->m_leftLink = TableID2[ta->LeftLinkID];
4816 				else
4817 					ta->m_leftLink = nullptr;
4818 				if (ta->RightLinkID != -1)
4819 					ta->m_rightLink = TableID2[ta->RightLinkID];
4820 				else
4821 					ta->m_rightLink = nullptr;
4822 				if (ta->BottomLinkID != -1)
4823 					ta->m_bottomLink = TableID2[ta->BottomLinkID];
4824 				else
4825 					ta->m_bottomLink = nullptr;
4826 			}
4827 		}
4828 		if (WeldItems.count() != 0)
4829 		{
4830 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
4831 			{
4832 				PageItem* ta = WeldItems.at(ttc);
4833 				for (int i = 0 ; i < ta->weldList.count(); ++i)
4834 				{
4835 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
4836 					ta->weldList[i].weldItem = WeldID.value(wInf.weldID, 0);
4837 					if (ta->weldList[i].weldItem == nullptr)
4838 						ta->weldList.removeAt(i--);
4839 				}
4840 			}
4841 		}
4842 	}
4843 
4844 	while (groupStackP.count() > 0)
4845 	{
4846 		bool isTableIt = false;
4847 		QList<PageItem*> gpL = groupStackP.pop();
4848 		PageItem* gItem = gpL.takeFirst();
4849 		for (int id = 0; id < gpL.count(); id++)
4850 		{
4851 			PageItem* cItem = gpL.at(id);
4852 			isTableIt = cItem->isTableItem;
4853 			cItem->gXpos = cItem->xPos() - gItem->xPos();
4854 			cItem->gYpos = cItem->yPos() - gItem->yPos();
4855 			cItem->Parent = gItem;
4856 			if (gItem->rotation() != 0)
4857 			{
4858 				QTransform ma;
4859 				ma.rotate(-gItem->rotation());
4860 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
4861 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
4862 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
4863 				cItem->setRotation(cItem->rotation() - gItem->rotation());
4864 				cItem->oldRot = cItem->rotation();
4865 			}
4866 			m_Doc->DocItems.removeOne(cItem);
4867 		}
4868 		bool converted = false;
4869 		if (isTableIt)
4870 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
4871 		if (!converted)
4872 			gItem->groupItemList = gpL;
4873 	}
4874 
4875 	int itemCount2 = m_Doc->Items->count();
4876 	if (itemCount2 > itemCount1)
4877 	{
4878 		PageItem* currItem = doc->Items->at(itemCount1), *newItem;
4879 		double minx =  std::numeric_limits<double>::max();
4880 		double miny =  std::numeric_limits<double>::max();
4881 		double maxx = -std::numeric_limits<double>::max();
4882 		double maxy = -std::numeric_limits<double>::max();
4883 		for (int i = itemCount1; i < itemCount2; ++i)
4884 		{
4885 			currItem = doc->Items->at(i);
4886 			double x1, x2, y1, y2;
4887 			currItem->getVisualBoundingRect(&x1, &y1, &x2, &y2);
4888 			minx = qMin(minx, x1);
4889 			miny = qMin(miny, y1);
4890 			maxx = qMax(maxx, x2);
4891 			maxy = qMax(maxy, y2);
4892 		}
4893 		for (int i = itemCount1; i < itemCount2; ++i)
4894 		{
4895 			newItem = doc->Items->takeAt(itemCount1);
4896 			newItem->gXpos = newItem->xPos() - minx;
4897 			newItem->gYpos = newItem->yPos() - miny;
4898 			newItem->gWidth = maxx - minx;
4899 			newItem->gHeight = maxy - miny;
4900 			newItem->setXYPos(newItem->gXpos, newItem->gYpos, true);
4901 			newItem->moveBy(pat.xoffset, pat.yoffset, true);
4902 			newItem->gXpos += pat.xoffset;
4903 			newItem->gYpos += pat.yoffset;
4904 			pat.items.append(newItem);
4905 		}
4906 		pat.createPreview();
4907 	}
4908 	doc->docPatterns.insert(patternName, pat);
4909 
4910 	doc->setMasterPageMode(savedMasterPageMode);
4911 	return success;
4912 }
4913 
readStoryText(ScribusDoc * doc,ScXmlStreamReader & reader,StoryText & story,PageItem * item)4914 bool Scribus150Format::readStoryText(ScribusDoc *doc, ScXmlStreamReader& reader, StoryText& story, PageItem* item)
4915 {
4916 	QStringRef tagName = reader.name();
4917 	ScXmlStreamAttributes attrs = reader.scAttributes();
4918 
4919 	LastStyles * lastStyle = new LastStyles();
4920 	while (!reader.atEnd() && !reader.hasError())
4921 	{
4922 		ScXmlStreamReader::TokenType tType = reader.readNext();
4923 		if (reader.isEndElement() && tagName == reader.name())
4924 			break;
4925 		if (tType != ScXmlStreamReader::StartElement)
4926 			continue;
4927 		QStringRef tName = reader.name();
4928 		ScXmlStreamAttributes tAtt = reader.scAttributes();
4929 
4930 		if (tName == "DefaultStyle")
4931 		{
4932 			ParagraphStyle newStyle;
4933 			readParagraphStyle(doc, reader, newStyle);
4934 			story.setDefaultStyle(newStyle);
4935 		}
4936 
4937 		if (tName == "ITEXT")
4938 			readItemText(story, tAtt, lastStyle);
4939 		else if (tName == "para")
4940 		{
4941 			story.insertChars(story.length(), SpecialChars::PARSEP);
4942 			ParagraphStyle newStyle;
4943 			readParagraphStyle(doc, reader, newStyle);
4944 			story.setStyle(story.length() - 1, newStyle);
4945 			story.setCharStyle(story.length() - 1, 1, lastStyle->Style);
4946 		}
4947 		else if (tName == "trail")
4948 		{
4949 			ParagraphStyle newStyle;
4950 			readParagraphStyle(doc, reader, newStyle);
4951 			story.setStyle(story.length(), newStyle);
4952 		}
4953 		else if (tName == "tab")
4954 		{
4955 			CharStyle newStyle;
4956 			story.insertChars(story.length(), SpecialChars::TAB);
4957 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4958 			story.setCharStyle(story.length() - 1, 1, newStyle);
4959 			lastStyle->StyleStart = story.length() - 1;
4960 			lastStyle->Style = newStyle;
4961 		}
4962 		else if (tName == "breakline")
4963 			story.insertChars(story.length(), SpecialChars::LINEBREAK);
4964 		else if (tName == "breakcol")
4965 			story.insertChars(story.length(), SpecialChars::COLBREAK);
4966 		else if (tName == "breakframe")
4967 			story.insertChars(story.length(), SpecialChars::FRAMEBREAK);
4968 		else if (tName == "nbhyphen")
4969 		{
4970 			CharStyle newStyle;
4971 			story.insertChars(story.length(), SpecialChars::NBHYPHEN);
4972 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4973 			story.setCharStyle(story.length() - 1, 1, newStyle);
4974 			lastStyle->StyleStart = story.length() - 1;
4975 			lastStyle->Style = newStyle;
4976 		}
4977 		else if (tName == "nbspace")
4978 		{
4979 			CharStyle newStyle;
4980 			story.insertChars(story.length(), SpecialChars::NBSPACE);
4981 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4982 			story.setCharStyle(story.length() - 1, 1, newStyle);
4983 			lastStyle->StyleStart = story.length() - 1;
4984 			lastStyle->Style = newStyle;
4985 		}
4986 		else if (tName == "zwnbspace")
4987 		{
4988 			CharStyle newStyle;
4989 			story.insertChars(story.length(), SpecialChars::ZWNBSPACE);
4990 			readCharacterStyleAttrs(doc, tAtt, newStyle);
4991 			story.setCharStyle(story.length() - 1, 1, newStyle);
4992 			lastStyle->StyleStart = story.length() - 1;
4993 			lastStyle->Style = newStyle;
4994 		}
4995 		else if (tName == "zwspace")
4996 		{
4997 			CharStyle newStyle;
4998 			story.insertChars(story.length(), SpecialChars::ZWSPACE);
4999 			readCharacterStyleAttrs(doc, tAtt, newStyle);
5000 			story.setCharStyle(story.length() - 1, 1, newStyle);
5001 			lastStyle->StyleStart = story.length() - 1;
5002 			lastStyle->Style = newStyle;
5003 		}
5004 		else if (tName == "var")
5005 		{
5006 			CharStyle newStyle;
5007 			if (tAtt.value("name") == "pgno")
5008 				story.insertChars(story.length(), SpecialChars::PAGENUMBER);
5009 			else
5010 				story.insertChars(story.length(), SpecialChars::PAGECOUNT);
5011 			readCharacterStyleAttrs(doc, tAtt, newStyle);
5012 			story.setCharStyle(story.length() - 1, 1, newStyle);
5013 			lastStyle->StyleStart = story.length() - 1;
5014 			lastStyle->Style = newStyle;
5015 		}
5016 
5017 		if (tName == "MARK")
5018 		{
5019 			QString l = tAtt.valueAsString("label");
5020 			MarkType t = (MarkType) tAtt.valueAsInt("type");
5021 			Mark* mark = nullptr;
5022 			if (m_Doc->isLoading())
5023 			{
5024 				mark = m_Doc->getMark(l, t);
5025 			}
5026 			else
5027 			{	//doc is not loading so it is copy/paste task
5028 				if (t == MARKVariableTextType)
5029 					mark = m_Doc->getMark(l, t);
5030 				else
5031 				{
5032 					//create copy of mark
5033 					Mark* oldMark = m_Doc->getMark(l, t);
5034 					if (oldMark == nullptr)
5035 					{
5036 						qWarning() << "wrong copy of oldMark";
5037 						mark = m_Doc->newMark();
5038 						mark->setType(t);
5039 					}
5040 					else
5041 					{
5042 						mark = m_Doc->newMark(oldMark);
5043 						getUniqueName(l, doc->marksLabelsList(t), "_");
5044 					}
5045 					mark->label = l;
5046 					if (t == MARKNoteMasterType)
5047 					{  //create copy of note
5048 						TextNote* old = mark->getNotePtr();
5049 						TextNote* note = m_Doc->newNote(old->notesStyle());
5050 						mark->setNotePtr(note);
5051 						note->setMasterMark(mark);
5052 						note->setSaxedText(old->saxedText());
5053 						m_Doc->setNotesChanged(true);
5054 					}
5055 				}
5056 			}
5057 			if (mark == nullptr)
5058 				qDebug() << "Undefined mark label ["<< l << "] type " << t;
5059 			else
5060 			{
5061 				//set pointer to item holds mark in his text
5062 				CharStyle newStyle;
5063 				if (t == MARKAnchorType)
5064 					mark->setItemPtr(item);
5065 				mark->OwnPage = item->OwnPage;
5066 				story.insertMark(mark, story.length());
5067 				readCharacterStyleAttrs(doc, tAtt, newStyle);
5068 				story.setCharStyle(story.length() - 1, 1, newStyle);
5069 				lastStyle->StyleStart = story.length() - 1;
5070 				lastStyle->Style = newStyle;
5071 			}
5072 		}
5073 	}
5074 	delete lastStyle;
5075 
5076 	return !reader.hasError();
5077 }
5078 
readItemText(StoryText & story,ScXmlStreamAttributes & attrs,LastStyles * last)5079 bool Scribus150Format::readItemText(StoryText& story, ScXmlStreamAttributes& attrs, LastStyles* last)
5080 {
5081 	QString tmp2;
5082 	CharStyle newStyle;
5083 	ScribusDoc* doc = story.doc();
5084 
5085 	readCharacterStyleAttrs(doc, attrs, newStyle);
5086 
5087 	if (attrs.hasAttribute(QLatin1String("Unicode")))
5088 	{
5089 		tmp2 = QChar(attrs.valueAsInt("Unicode"));
5090 	}
5091 	else
5092 	{
5093 		tmp2 = attrs.valueAsString("CH");
5094 
5095 		// legacy stuff:
5096 		tmp2.replace(QRegExp("\r"), QChar(13));
5097 		tmp2.replace(QRegExp("\n"), QChar(13));
5098 		tmp2.replace(QRegExp("\t"), QChar(9));
5099 	}
5100 
5101 	// more legacy stuff:
5102 	QString pstylename = attrs.valueAsString("PSTYLE", "");
5103 
5104 	fixLegacyCharStyle(newStyle);
5105 	last->ParaStyle = pstylename;
5106 	// end of legacy stuff
5107 
5108 	int iobj = attrs.valueAsInt("COBJ", -1);
5109 
5110 	for (int cxx = 0; cxx < tmp2.length(); ++cxx)
5111 	{
5112 		QChar ch = tmp2.at(cxx);
5113 		{ // Legacy mode
5114 			if (ch == QChar(5))
5115 				ch = SpecialChars::PARSEP;
5116 			if (ch == QChar(4))
5117 				ch = SpecialChars::TAB;
5118 		}
5119 
5120 		int pos = story.length();
5121 		if (ch == SpecialChars::OBJECT)
5122 		{
5123 			if (LinkID.contains(iobj))
5124 			{
5125 				if (FrameItems.contains(LinkID[iobj]))
5126 				{
5127 					int fIndex = doc->addToInlineFrames(LinkID[iobj]);
5128 					story.insertObject(pos, fIndex);
5129 				}
5130 			}
5131 			else
5132 			{
5133 				if (doc->FrameItems.contains(iobj))
5134 					story.insertObject(pos, iobj);
5135 				else
5136 					qDebug() << QString("scribus150format: invalid inline frame used in text object : %1").arg(iobj);
5137 			}
5138 		}
5139 		else if (ch == SpecialChars::SHYPHEN && pos > 0)
5140 		{
5141 //			qDebug() << QString("scribus150format: SHYPHEN at %1").arg(pos);
5142 			// double SHY means user provided SHY, single SHY is automatic one
5143 			if (story.hasFlag(pos-1, ScLayout_HyphenationPossible))
5144 			{
5145 				story.clearFlag(pos-1, ScLayout_HyphenationPossible);
5146 				story.insertChars(pos, QString(ch));
5147 			}
5148 			else
5149 			{
5150 				story.setFlag(pos-1, ScLayout_HyphenationPossible);
5151 			}
5152 		}
5153 		else {
5154 			story.insertChars(pos, QString(ch));
5155 		}
5156 //		qDebug() << QString("style at %1: %2 ^ %3 = %4 (%5)").arg(pos).arg((uint)newStyle.effects()).arg((uint)last->Style.effects()).arg((uint)(newStyle.effects() ^ last->Style.effects())).arg(newStyle != last->Style);
5157 		if (newStyle != last->Style) // || (newStyle.effects() ^ last->Style.effects()) == ScStyle_HyphenationPossible)
5158 		{  // FIXME StyleFlag operator== ignores hyphen flag
5159 //			qDebug() << QString("new style at %1: %2 -> %3").arg(pos).arg(last->Style.asString()).arg(newStyle.asString());
5160 			story.setCharStyle(last->StyleStart, pos-last->StyleStart, last->Style);
5161 			last->Style = newStyle;
5162 			last->StyleStart = pos;
5163 		}
5164 		if (ch == SpecialChars::PARSEP) {
5165 			ParagraphStyle pstyle;
5166 			// Qt4 if (last->ParaStyle >= 0) {
5167 			if (!last->ParaStyle.isEmpty()) {
5168 				pstyle.setParent( last->ParaStyle );
5169 			}
5170 			story.applyStyle(pos, pstyle);
5171 		}
5172 	}
5173 
5174 	story.setCharStyle(last->StyleStart, story.length()-last->StyleStart, last->Style);
5175 	last->StyleStart = story.length();
5176 /*
5177 	QString dbg("");
5178 	for (int i=0; i < story.length(); ++i)
5179 	{
5180 		dbg += story.text(i,1);
5181 		if (story.item(i)->effects() & ScStyle_HyphenationPossible)
5182 			dbg += "~";
5183 	}
5184 	qDebug("scribus150format: read itemtext %d '%s'", story.length(), dbg.latin1());
5185 	*/
5186 	ParagraphStyle pstyle;
5187 
5188 	if (!last->ParaStyle.isEmpty())
5189 	{
5190 		pstyle.setParent(last->ParaStyle);
5191 		story.applyStyle(story.length() - 1, pstyle);
5192 	}
5193 
5194 	return true;
5195 }
5196 
readPageItemAttributes(PageItem * item,ScXmlStreamReader & reader)5197 bool Scribus150Format::readPageItemAttributes(PageItem* item, ScXmlStreamReader& reader)
5198 {
5199 	QStringRef tagName = reader.name();
5200 	ObjAttrVector pageItemAttributes;
5201 	while (!reader.atEnd() && !reader.hasError())
5202 	{
5203 		reader.readNext();
5204 		if (reader.isEndElement() && reader.name() == tagName)
5205 			break;
5206 		if (reader.isStartElement() && reader.name() == "ItemAttribute")
5207 		{
5208 			ScXmlStreamAttributes tAtt = reader.scAttributes();
5209 			ObjectAttribute objattr;
5210 			objattr.name  = tAtt.valueAsString("Name");
5211 			objattr.type  = tAtt.valueAsString("Type");
5212 			objattr.value = tAtt.valueAsString("Value");
5213 			objattr.parameter = tAtt.valueAsString("Parameter");
5214 			objattr.relationship   = tAtt.valueAsString("Relationship");
5215 			objattr.relationshipto = tAtt.valueAsString("RelationshipTo");
5216 			objattr.autoaddto = tAtt.valueAsString("AutoAddTo");
5217 			pageItemAttributes.append(objattr);
5218 		}
5219 	}
5220 	item->setObjectAttributes(&pageItemAttributes);
5221 	return !reader.hasError();
5222 }
5223 
pasteItem(ScribusDoc * doc,ScXmlStreamAttributes & attrs,const QString & baseDir,PageItem::ItemKind itemKind,int pageNr)5224 PageItem* Scribus150Format::pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, PageItem::ItemKind itemKind, int pageNr)
5225 {
5226 	int z = 0;
5227 	struct ImageLoadRequest loadingInfo;
5228 	PageItem::ItemType pt = static_cast<PageItem::ItemType>(attrs.valueAsInt("PTYPE"));
5229 	bool isGroupFlag = attrs.valueAsBool("isGroupControl", false);
5230 	if (isGroupFlag)
5231 		pt = PageItem::Group;
5232 	bool isNoteFrameFlag = attrs.valueAsBool("isNoteFrame", false);
5233 	if (isNoteFrameFlag && (pt == PageItem::TextFrame))
5234 		pt = PageItem::NoteFrame;
5235 	double xf, yf;
5236 	double x   = attrs.valueAsDouble("XPOS");
5237 	double y   = attrs.valueAsDouble("YPOS");
5238 	x = Xp + x - GrX;
5239 	y = Yp + y - GrY;
5240 	double w   = attrs.valueAsDouble("WIDTH");
5241 	double h   = attrs.valueAsDouble("HEIGHT");
5242 	double pw  = attrs.valueAsDouble("PWIDTH");
5243 	double imageXOffset = attrs.valueAsDouble("LOCALX");
5244 	double imageYOffset = attrs.valueAsDouble("LOCALY");
5245 	double imageXScale  = attrs.valueAsDouble("LOCALSCX");
5246 	double imageYScale  = attrs.valueAsDouble("LOCALSCY");
5247 	QString Pcolor = attrs.valueAsString("PCOLOR");
5248 	if (Pcolor.isEmpty())
5249 		Pcolor = CommonStrings::None;
5250 	QString Pcolor2 = attrs.valueAsString("PCOLOR2");
5251 	if (Pcolor2.isEmpty())
5252 		Pcolor2 = CommonStrings::None;
5253 	QColor tmpc;
5254 	PageItem *currItem=nullptr;
5255 	QString tmp, clPath;
5256 	switch (pt)
5257 	{
5258 	// OBSOLETE CR 2005-02-06
5259 	case PageItem::ItemType1:
5260 		z = doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5261 		currItem = doc->Items->at(z);
5262 		if (pageNr > -2)
5263 			currItem->setOwnerPage(pageNr);
5264 		break;
5265 	//
5266 	case PageItem::ImageFrame:
5267 	case PageItem::OSGFrame:
5268 	case PageItem::LatexFrame: /*Everything that is valid for image frames is also valid for latex frames*/
5269 		z = doc->itemAdd(pt, PageItem::Unspecified, x, y, w, h, 1, doc->itemToolPrefs().imageFillColor, doc->itemToolPrefs().imageStrokeColor, itemKind);
5270 		currItem = doc->Items->at(z);
5271 		if (pageNr > -2)
5272 			currItem->setOwnerPage(pageNr);
5273 		UndoManager::instance()->setUndoEnabled(false);
5274 		currItem->ScaleType   = attrs.valueAsInt("SCALETYPE", 1);
5275 		currItem->AspectRatio = attrs.valueAsInt("RATIO", 0);
5276 		currItem->setImageXYScale(imageXScale, imageYScale);
5277 		currItem->setImageXYOffset(imageXOffset, imageYOffset);
5278 		currItem->setImageRotation(attrs.valueAsDouble("LOCALROT"));
5279 //		if (!currItem->isLatexFrame())
5280 #ifdef HAVE_OSG
5281 		if ((currItem->isImageFrame() || currItem->isOSGFrame()) && (!currItem->isLatexFrame()))
5282 #else
5283 		if ((currItem->isImageFrame()) && (!currItem->isLatexFrame()))
5284 #endif
5285 		{
5286 			bool inlineF = attrs.valueAsBool("isInlineImage", false);
5287 			QString dat  = attrs.valueAsString("ImageData", "");
5288 			QByteArray inlineImageData;
5289 			inlineImageData.append(dat.toUtf8());
5290 			QString inlineImageExt = attrs.valueAsString("inlineImageExt", "");
5291 			if (inlineF)
5292 			{
5293 				if (inlineImageData.size() > 0)
5294 				{
5295 					QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + inlineImageExt);
5296 					tempFile->setAutoRemove(false);
5297 					tempFile->open();
5298 					QString fileName = getLongPathName(tempFile->fileName());
5299 					tempFile->close();
5300 					inlineImageData = qUncompress(QByteArray::fromBase64(inlineImageData));
5301 					QFile outFil(fileName);
5302 					if (outFil.open(QIODevice::WriteOnly))
5303 					{
5304 						outFil.write(inlineImageData);
5305 						outFil.close();
5306 						currItem->isInlineImage = true;
5307 						currItem->Pfile = QDir::fromNativeSeparators(fileName);
5308 						currItem->isTempFile = true;
5309 					}
5310 					delete tempFile;
5311 				}
5312 			}
5313 			else
5314 			{
5315 				currItem->Pfile = Relative2Path(attrs.valueAsString("PFILE"), baseDir);
5316 				currItem->Pfile = QDir::fromNativeSeparators(currItem->Pfile);
5317 			}
5318 #ifdef HAVE_OSG
5319 			if (currItem->isOSGFrame())
5320 			{
5321 				PageItem_OSGFrame *osgframe = currItem->asOSGFrame();
5322 				osgframe->modelFile = Relative2Path(attrs.valueAsString("modelFile"), baseDir);
5323 				osgframe->currentView = attrs.valueAsString("currentViewName", "");
5324 				osgframe->loadModel();
5325 			}
5326 #endif
5327 		}
5328 		currItem->ImageProfile    = attrs.valueAsString("PRFILE", "");
5329 		currItem->ImageIntent     = (eRenderIntent) attrs.valueAsInt("IRENDER", 1);
5330 		currItem->EmbeddedProfile = attrs.valueAsString("EPROF" , "");
5331 		currItem->UseEmbedded = attrs.valueAsInt("EMBEDDED", 1);
5332 		currItem->pixm.imgInfo.lowResType = attrs.valueAsInt("ImageRes", 1);
5333 		currItem->pixm.imgInfo.actualPageNumber = attrs.valueAsInt("Pagenumber", 0);
5334 		if ((currItem->OverrideCompressionMethod = attrs.hasAttribute("COMPRESSIONMETHOD")))
5335 			currItem->CompressionMethodIndex = attrs.valueAsInt("COMPRESSIONMETHOD", 0);
5336 		if ((currItem->OverrideCompressionQuality = attrs.hasAttribute("COMPRESSIONQUALITY")))
5337 			currItem->CompressionQualityIndex = attrs.valueAsInt("COMPRESSIONQUALITY");
5338 		currItem->setImageXYScale(imageXScale, imageYScale);
5339 		currItem->setImageRotation(attrs.valueAsDouble("LOCALROT"));
5340 		clPath = attrs.valueAsString("ImageClip", "");
5341 		if (!clPath.isEmpty())
5342 		{
5343 			clipPath = clPath;
5344 			layerFound = true;
5345 		}
5346 		currItem->setImageVisible( attrs.valueAsInt("PICART"));
5347 		currItem->setLineWidth(pw);
5348 		UndoManager::instance()->setUndoEnabled(true);
5349 		break;
5350 	// OBSOLETE CR 2005-02-06
5351 	case PageItem::ItemType3:
5352 		z = doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5353 		currItem = doc->Items->at(z);
5354 		if (pageNr > -2)
5355 			currItem->setOwnerPage(pageNr);
5356 		break;
5357 	//
5358 	case PageItem::PathText:
5359 		z = doc->itemAdd(PageItem::PathText, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, itemKind);
5360 		currItem = doc->Items->at(z);
5361 		if (pageNr > -2)
5362 			currItem->setOwnerPage(pageNr);
5363 		break;
5364 	case PageItem::NoteFrame:
5365 	case PageItem::TextFrame:
5366 		z = doc->itemAdd(pt, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, itemKind);
5367 		currItem = doc->Items->at(z);
5368 		if (pageNr > -2)
5369 			currItem->setOwnerPage(pageNr);
5370 		break;
5371 	case PageItem::Line:
5372 		z = doc->itemAdd(PageItem::Line, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor2, itemKind);
5373 		currItem = doc->Items->at(z);
5374 		if (pageNr > -2)
5375 			currItem->setOwnerPage(pageNr);
5376 		break;
5377 	case PageItem::Polygon:
5378 		z = doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5379 		currItem = doc->Items->at(z);
5380 		if (pageNr > -2)
5381 			currItem->setOwnerPage(pageNr);
5382 		break;
5383 	case PageItem::PolyLine:
5384 		z = doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5385 		currItem = doc->Items->at(z);
5386 		if (pageNr > -2)
5387 			currItem->setOwnerPage(pageNr);
5388 		break;
5389 	case PageItem::Symbol:
5390 		z = doc->itemAdd(PageItem::Symbol, PageItem::Unspecified, x, y, w, h, 0, CommonStrings::None, CommonStrings::None, itemKind);
5391 		currItem = doc->Items->at(z);
5392 		if (pageNr > -2)
5393 			currItem->setOwnerPage(pageNr);
5394 		currItem->setPattern( attrs.valueAsString("pattern", "") );
5395 		break;
5396 	case PageItem::Group:
5397 		z = doc->itemAdd(PageItem::Group, PageItem::Unspecified, x, y, w, h, 0, CommonStrings::None, CommonStrings::None, itemKind);
5398 		currItem = doc->Items->at(z);
5399 		if (pageNr > -2)
5400 			currItem->setOwnerPage(pageNr);
5401 		currItem->groupWidth = attrs.valueAsDouble("groupWidth", w);
5402 		currItem->groupHeight = attrs.valueAsDouble("groupHeight", h);
5403 		doc->GroupCounter++;
5404 		break;
5405 	case PageItem::RegularPolygon:
5406 		z = doc->itemAdd(PageItem::RegularPolygon, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5407 		currItem = doc->Items->at(z);
5408 		if (pageNr > -2)
5409 			currItem->setOwnerPage(pageNr);
5410 		break;
5411 	case PageItem::Arc:
5412 		z = doc->itemAdd(PageItem::Arc, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5413 		currItem = doc->Items->at(z);
5414 		if (pageNr > -2)
5415 			currItem->setOwnerPage(pageNr);
5416 		break;
5417 	case PageItem::Spiral:
5418 		z = doc->itemAdd(PageItem::Spiral, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
5419 		currItem = doc->Items->at(z);
5420 		if (pageNr > -2)
5421 			currItem->setOwnerPage(pageNr);
5422 		break;
5423 	case PageItem::Table:
5424 		z = doc->itemAdd(PageItem::Table, PageItem::Unspecified, x, y, w, h, 0.0, CommonStrings::None, CommonStrings::None, itemKind);
5425 		currItem = doc->Items->at(z);
5426 		if (pageNr > -2)
5427 			currItem->setOwnerPage(pageNr);
5428 		break;
5429 	case PageItem::Multiple:
5430 		Q_ASSERT(false);
5431 		break;
5432 	}
5433 
5434 	currItem->setGroupClipping(attrs.valueAsBool("groupClips", true));
5435 	currItem->FrameType = attrs.valueAsInt("FRTYPE", 0);
5436 	int startArrowIndex = attrs.valueAsInt("startArrowIndex", 0);
5437 	if ((startArrowIndex < 0) || (startArrowIndex > static_cast<int>(doc->arrowStyles().size())))
5438 	{
5439 		qDebug() << QString("scribus150format: invalid arrow index: %").arg(startArrowIndex);
5440 		startArrowIndex = 0;
5441 	}
5442 	currItem->setStartArrowIndex(startArrowIndex);
5443 	int endArrowIndex = attrs.valueAsInt("endArrowIndex", 0);
5444 	if ((endArrowIndex < 0) || (endArrowIndex > static_cast<int>(doc->arrowStyles().size())))
5445 	{
5446 		qDebug() << QString("scribus150format: invalid arrow index: %").arg(endArrowIndex);
5447 		endArrowIndex = 0;
5448 	}
5449 	currItem->setEndArrowIndex(endArrowIndex);
5450 	currItem->setStartArrowScale(attrs.valueAsInt("startArrowScale", 100));
5451 	currItem->setEndArrowScale(attrs.valueAsInt("endArrowScale", 100));
5452 	currItem->NamedLStyle = attrs.valueAsString("NAMEDLST", "");
5453 	currItem->isBookmark  = attrs.valueAsInt("BOOKMARK", 0);
5454 	currItem->setImageFlippedH( attrs.valueAsInt("FLIPPEDH", 0));
5455 	currItem->setImageFlippedV( attrs.valueAsInt("FLIPPEDV", 0));
5456 	currItem->setCornerRadius( attrs.valueAsDouble("RADRECT", 0.0));
5457 	currItem->ClipEdited = attrs.valueAsInt("CLIPEDIT", 0);
5458 	currItem->setFillColor(Pcolor);
5459 	currItem->setLineColor(Pcolor2);
5460 	currItem->setFillShade(attrs.valueAsInt("SHADE", 100));
5461 	currItem->setLineShade(attrs.valueAsInt("SHADE2", 100));
5462 
5463 	ParagraphStyle pstyle;
5464 	if (attrs.hasAttribute("LINESP"))
5465 		pstyle.setLineSpacing(attrs.valueAsDouble("LINESP"));
5466 	if (attrs.hasAttribute("LINESPMode"))
5467 		pstyle.setLineSpacingMode(static_cast<ParagraphStyle::LineSpacingMode>(attrs.valueAsInt("LINESPMode", 0)));
5468 	if (attrs.hasAttribute("ALIGN"))
5469 		pstyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(attrs.valueAsInt("ALIGN", 0)));
5470 	if (attrs.valueAsBool("REVERS"))
5471 		pstyle.setDirection(ParagraphStyle::RTL);
5472 	if (attrs.hasAttribute("DIRECTION"))
5473 		pstyle.setDirection(static_cast<ParagraphStyle::DirectionType>(attrs.valueAsInt("DIRECTION", 0)));
5474 	if (attrs.hasAttribute("IFONT"))
5475 		pstyle.charStyle().setFont(m_AvailableFonts->findFont(attrs.valueAsString("IFONT"), doc));
5476 	if (attrs.hasAttribute("ISIZE"))
5477 		pstyle.charStyle().setFontSize(qRound(attrs.valueAsDouble("ISIZE") * 10));
5478 	if (attrs.hasAttribute("TXTSTROKE"))
5479 		pstyle.charStyle().setStrokeColor(attrs.valueAsString("TXTSTROKE"));
5480 	if (attrs.hasAttribute("TXTFILL"))
5481 		pstyle.charStyle().setFillColor(attrs.valueAsString("TXTFILL"));
5482 	if (attrs.hasAttribute("TXTSTRSH"))
5483 		pstyle.charStyle().setStrokeShade(attrs.valueAsInt("TXTSTRSH"));
5484 	if (attrs.hasAttribute("TXTFILLSH"))
5485 		pstyle.charStyle().setFillShade(attrs.valueAsInt("TXTFILLSH"));
5486 	if (attrs.hasAttribute("TXTSCALE"))
5487 		pstyle.charStyle().setScaleH(qRound(attrs.valueAsDouble("TXTSCALE") * 10));
5488 	if (attrs.hasAttribute("TXTSCALEV"))
5489 		pstyle.charStyle().setScaleV(qRound(attrs.valueAsDouble("TXTSCALEV") * 10));
5490 	if (attrs.hasAttribute("TXTBASE"))
5491 		pstyle.charStyle().setBaselineOffset(qRound(attrs.valueAsDouble("TXTBASE") * 10));
5492 	if (attrs.hasAttribute("TXTSHX"))
5493 		pstyle.charStyle().setShadowXOffset(qRound(attrs.valueAsDouble("TXTSHX") * 10));
5494 	if (attrs.hasAttribute("TXTSHY"))
5495 		pstyle.charStyle().setShadowYOffset(qRound(attrs.valueAsDouble("TXTSHY") * 10));
5496 	if (attrs.hasAttribute("TXTOUT"))
5497 		pstyle.charStyle().setOutlineWidth(qRound(attrs.valueAsDouble("TXTOUT") * 10));
5498 	if (attrs.hasAttribute("TXTULP"))
5499 		pstyle.charStyle().setUnderlineOffset(qRound(attrs.valueAsDouble("TXTULP") * 10));
5500 	if (attrs.hasAttribute("TXTULW"))
5501 		pstyle.charStyle().setUnderlineWidth(qRound(attrs.valueAsDouble("TXTULW") * 10));
5502 	if (attrs.hasAttribute("TXTSTP"))
5503 		pstyle.charStyle().setStrikethruOffset(qRound(attrs.valueAsDouble("TXTSTP") * 10));
5504 	if (attrs.hasAttribute("TXTSTW"))
5505 		pstyle.charStyle().setStrikethruWidth(qRound(attrs.valueAsDouble("TXTSTW") * 10));
5506 	if (attrs.hasAttribute("TXTFEATURES"))
5507 		pstyle.charStyle().setFeatures(attrs.valueAsString("TXTFEATURES").split(" ", Qt::SkipEmptyParts));
5508 	if (attrs.hasAttribute("TXTKERN"))
5509 		pstyle.charStyle().setTracking(qRound(attrs.valueAsDouble("TXTKERN", 0.0) * 10));
5510 	if (attrs.hasAttribute("wordTrack"))
5511 		pstyle.charStyle().setWordTracking(attrs.valueAsDouble("wordTrack"));
5512 	if (attrs.hasAttribute("MinWordTrack"))
5513 		pstyle.setMinWordTracking(attrs.valueAsDouble("MinWordTrack"));
5514 	if (attrs.hasAttribute("MinGlyphShrink"))
5515 		pstyle.setMinGlyphExtension(attrs.valueAsDouble("MinGlyphShrink"));
5516 	if (attrs.hasAttribute("MaxGlyphExtend"))
5517 		pstyle.setMaxGlyphExtension(attrs.valueAsDouble("MaxGlyphExtend"));
5518 	if (attrs.hasAttribute("OpticalMargins"))
5519 		pstyle.setOpticalMargins(attrs.valueAsInt("OpticalMargins"));
5520 	if (attrs.hasAttribute("HyphenationMode"))
5521 		pstyle.setHyphenationMode(attrs.valueAsInt("HyphenationMode"));
5522 	if (attrs.hasAttribute("leftMargin"))
5523 		pstyle.setLeftMargin(attrs.valueAsDouble("leftMargin"));
5524 	if (attrs.hasAttribute("rightMargin"))
5525 		pstyle.setRightMargin(attrs.valueAsDouble("rightMargin"));
5526 	if (attrs.hasAttribute("firstIndent"))
5527 		pstyle.setFirstIndent(attrs.valueAsDouble("firstIndent"));
5528 	if (attrs.hasAttribute("keepLinesStart"))
5529 		pstyle.setKeepLinesStart(attrs.valueAsInt("keepLinesStart"));
5530 	if (attrs.hasAttribute("keepLinesEnd"))
5531 		pstyle.setKeepLinesEnd(attrs.valueAsInt("keepLinesEnd"));
5532 	if (attrs.hasAttribute("keepWithNext"))
5533 		pstyle.setKeepWithNext(attrs.valueAsBool("keepWithNext"));
5534 	if (attrs.hasAttribute("keepTogether"))
5535 		pstyle.setKeepTogether(attrs.valueAsBool("keepTogether"));
5536 	if (attrs.hasAttribute("ParagraphEffectCharStyle"))
5537 		pstyle.setPeCharStyleName(attrs.valueAsString("ParagraphEffectCharStyle"));
5538 	if (attrs.hasAttribute("ParagraphEffectOffset"))
5539 		pstyle.setParEffectOffset(attrs.valueAsDouble("ParagraphEffectOffset"));
5540 	if (attrs.hasAttribute("ParagraphEffectIndent"))
5541 		pstyle.setParEffectIndent(attrs.valueAsDouble("ParagraphEffectIndent"));
5542 	if (attrs.hasAttribute("DROP"))
5543 		pstyle.setHasDropCap(static_cast<bool>(attrs.valueAsInt("DROP")));
5544 	if (attrs.hasAttribute("DROPLIN"))
5545 		pstyle.setDropCapLines(attrs.valueAsInt("DROPLIN"));
5546 	if (attrs.hasAttribute("DROPDIST"))
5547 		pstyle.setParEffectOffset(attrs.valueAsDouble("DROPDIST"));
5548 	if (attrs.hasAttribute("Bullet"))
5549 		pstyle.setHasBullet(static_cast<bool>(attrs.valueAsInt("Bullet")));
5550 	if (attrs.hasAttribute("BulletStr"))
5551 		pstyle.setBulletStr(attrs.valueAsString("BulletStr"));
5552 	if (attrs.hasAttribute("Numeration"))
5553 		pstyle.setHasNum(static_cast<bool>(attrs.valueAsInt("Numeration")));
5554 	if (attrs.hasAttribute("NumerationName"))
5555 		pstyle.setNumName(attrs.valueAsString("NumerationName"));
5556 	if (attrs.hasAttribute("NumerationFormat"))
5557 		pstyle.setNumFormat(attrs.valueAsInt("NumerationFormat"));
5558 	if (attrs.hasAttribute("NumerationLevel"))
5559 		pstyle.setNumLevel(attrs.valueAsInt("NumerationLevel"));
5560 	if (attrs.hasAttribute("NumerationStart"))
5561 		pstyle.setNumStart(attrs.valueAsInt("NumerationStart"));
5562 	if (attrs.hasAttribute("NumerationPrefix"))
5563 		pstyle.setNumPrefix(attrs.valueAsString("NumerationPrefix"));
5564 	if (attrs.hasAttribute("NumerationSuffix"))
5565 		pstyle.setNumSuffix(attrs.valueAsString("NumerationSuffix"));
5566 	if (attrs.hasAttribute("NumerationRestart"))
5567 	{
5568 		NumerationRange numRange = (NumerationRange) attrs.valueAsInt("NumerationRestart");
5569 		// Fix deprecated numeration ranges
5570 		if (numRange != NSRdocument && numRange != NSRstory)
5571 			numRange = NSRstory;
5572 		pstyle.setNumRestart(static_cast<int>(numRange));
5573 	}
5574 	if (attrs.hasAttribute("NumeartionOther"))
5575 		pstyle.setNumOther(static_cast<bool>(attrs.valueAsInt("NumeartionOther")));
5576 	if (attrs.hasAttribute("NumerationHigher"))
5577 		pstyle.setNumHigher(static_cast<bool>(attrs.valueAsInt("NumerationHigher")));
5578 	currItem->itemText.setDefaultStyle(pstyle);
5579 
5580 	if (attrs.hasAttribute("PSTYLE"))
5581 	{
5582 		QString pstyleName = attrs.valueAsString("PSTYLE");
5583 		if (!pstyleName.isEmpty())
5584 		{
5585 			ParagraphStyle defStyle(currItem->itemText.defaultStyle());
5586 			defStyle.setParent(pstyleName);
5587 			currItem->itemText.setDefaultStyle(defStyle);
5588 		}
5589 	}
5590 	currItem->setRotation( attrs.valueAsDouble("ROT", 0.0) );
5591 	currItem->oldRot = currItem->rotation();
5592 	currItem->setTextToFrameDist(attrs.valueAsDouble("EXTRA", 0.0),
5593 								attrs.valueAsDouble("REXTRA", 0.0),
5594 								attrs.valueAsDouble("TEXTRA", 0.0),
5595 								attrs.valueAsDouble("BEXTRA", 0.0));
5596 	currItem->setVerticalAlignment(attrs.valueAsInt("VAlign", 0));
5597 	currItem->setFirstLineOffset(static_cast<FirstLineOffsetPolicy>(attrs.valueAsInt("FLOP")));
5598 
5599 	currItem->PLineArt  = Qt::PenStyle(attrs.valueAsInt("PLINEART", 0));
5600 	currItem->PLineEnd  = Qt::PenCapStyle(attrs.valueAsInt("PLINEEND", 0));
5601 	currItem->PLineJoin = Qt::PenJoinStyle(attrs.valueAsInt("PLINEJOIN", 0));
5602 	currItem->setPrintEnabled( attrs.valueAsInt("PRINTABLE", 1));
5603 	currItem->setIsAnnotation( attrs.valueAsInt("ANNOTATION", 0));
5604 	currItem->annotation().setType( attrs.valueAsInt("ANTYPE", 0));
5605 	QString itemName = attrs.valueAsString("ANNAME","");
5606 	if (!itemName.isEmpty())
5607 	{
5608 		if (currItem->itemName() == itemName)
5609 			currItem->AutoName = true;
5610 		else
5611 		{
5612 			currItem->setItemName(itemName);
5613 			currItem->AutoName = false;
5614 		}
5615 	}
5616 
5617 	currItem->annotation().setAction( attrs.valueAsString("ANACTION","") );
5618 	currItem->annotation().setE_act ( attrs.valueAsString("ANEACT","") );
5619 	currItem->annotation().setX_act ( attrs.valueAsString("ANXACT","") );
5620 	currItem->annotation().setD_act ( attrs.valueAsString("ANDACT","") );
5621 	currItem->annotation().setFo_act( attrs.valueAsString("ANFOACT","") );
5622 	currItem->annotation().setBl_act( attrs.valueAsString("ANBLACT","") );
5623 	currItem->annotation().setK_act ( attrs.valueAsString("ANKACT","") );
5624 	currItem->annotation().setF_act ( attrs.valueAsString("ANFACT","") );
5625 	currItem->annotation().setV_act ( attrs.valueAsString("ANVACT","") );
5626 	currItem->annotation().setC_act ( attrs.valueAsString("ANCACT","") );
5627 	currItem->annotation().setActionType(attrs.valueAsInt("ANACTYP", 0));
5628 	currItem->annotation().setExtern( attrs.valueAsString("ANEXTERN",""));
5629 	if ((!currItem->annotation().Extern().isEmpty()) && (currItem->annotation().ActionType() != 8))
5630 		currItem->annotation().setExtern(Relative2Path(attrs.valueAsString("ANEXTERN", "") , baseDir));
5631 	currItem->annotation().setZiel( attrs.valueAsInt("ANZIEL", 0));
5632 	currItem->annotation().setToolTip ( attrs.valueAsString("ANTOOLTIP",""));
5633 	currItem->annotation().setRollOver( attrs.valueAsString("ANROLL",""));
5634 	currItem->annotation().setDown( attrs.valueAsString("ANDOWN",""));
5635 	currItem->annotation().setBorderWidth( attrs.valueAsInt("ANBWID", 1));
5636 	currItem->annotation().setBorderStyle( attrs.valueAsInt("ANBSTY", 0));
5637 	currItem->annotation().setFeed( attrs.valueAsInt("ANFEED", 1));
5638 	currItem->annotation().setFlag( attrs.valueAsInt("ANFLAG", 0));
5639 	currItem->annotation().setFont( attrs.valueAsInt("ANFONT", 4));
5640 	currItem->annotation().setFormat( attrs.valueAsInt("ANFORMAT", 0));
5641 	currItem->annotation().setVis( attrs.valueAsInt("ANVIS", 0));
5642 	currItem->annotation().setIsChk( attrs.valueAsBool("ANCHK", false) );
5643 	currItem->annotation().setCheckState(currItem->annotation().IsChk());
5644 	currItem->annotation().setAAact( attrs.valueAsBool("ANAA", false) );
5645 	currItem->annotation().setHTML ( attrs.valueAsInt("ANHTML", 0));
5646 	currItem->annotation().setUseIcons( attrs.valueAsBool("ANICON", false));
5647 	currItem->annotation().setChkStil ( attrs.valueAsInt("ANCHKS", 0));
5648 	currItem->annotation().setMaxChar ( attrs.valueAsInt("ANMC", -1));
5649 	currItem->annotation().setBorderColor( attrs.valueAsString("ANBCOL", CommonStrings::None));
5650 	currItem->annotation().setIPlace(attrs.valueAsInt("ANPLACE", 1));
5651 	currItem->annotation().setScaleW(attrs.valueAsInt("ANSCALE", 0));
5652 	currItem->annotation().setIcon(attrs.valueAsInt("ANITYP", 0));
5653 	currItem->annotation().setAnOpen(attrs.valueAsBool("ANOPEN", false) );
5654 
5655 	if (currItem->isTextFrame() || currItem->isPathText())
5656 	{
5657 		UndoManager::instance()->setUndoEnabled(false);
5658 		if (currItem->isAnnotation() && currItem->annotation().UseIcons())
5659 		{
5660 			currItem->setImageXYScale(imageXScale, imageYScale);
5661 			currItem->setImageXYOffset(imageXOffset, imageYOffset);
5662 			currItem->setImageRotation(attrs.valueAsDouble("LOCALROT"));
5663 			currItem->Pfile  = Relative2Path(attrs.valueAsString("PFILE" , ""), baseDir);
5664 			currItem->Pfile2 = Relative2Path(attrs.valueAsString("PFILE2", ""), baseDir);
5665 			currItem->Pfile3 = Relative2Path(attrs.valueAsString("PFILE3", ""), baseDir);
5666 			currItem->Pfile  = QDir::fromNativeSeparators(currItem->Pfile);
5667 			currItem->Pfile2 = QDir::fromNativeSeparators(currItem->Pfile2);
5668 			currItem->Pfile3 = QDir::fromNativeSeparators(currItem->Pfile3);
5669 			currItem->ImageProfile    = attrs.valueAsString("PRFILE", "");
5670 			currItem->ImageIntent     = (eRenderIntent) attrs.valueAsInt("IRENDER" , 1);
5671 			currItem->EmbeddedProfile = attrs.valueAsString("EPROF", "");
5672 			currItem->UseEmbedded = attrs.valueAsInt("EMBEDDED", 1);
5673 			doc->loadPict(currItem->Pfile, currItem);
5674 			currItem->setImageXYScale(imageXScale, imageYScale);
5675 			currItem->setImageVisible( attrs.valueAsInt("PICART"));
5676 /*			currItem->BBoxX = ScCLocale::toDoubleC( obj->attribute("BBOXX"));
5677 			currItem->BBoxH = ScCLocale::toDoubleC( obj->attribute("BBOXH")); */
5678 			currItem->ScaleType   = attrs.valueAsInt("SCALETYPE", 1);
5679 			currItem->AspectRatio = attrs.valueAsInt("RATIO", 0);
5680 		}
5681 		UndoManager::instance()->setUndoEnabled(true);
5682 	}
5683 
5684 	if (currItem->isTable())
5685 	{
5686 		doc->dontResize = true;
5687 		PageItem_Table *tableitem = currItem->asTable();
5688 		int rows=attrs.valueAsInt("Rows",1);
5689 		int cols=attrs.valueAsInt("Columns",1);
5690 		tableitem->insertRows(1,rows-1);
5691 		tableitem->insertColumns(1,cols-1);
5692 		tableitem->setStyle(attrs.valueAsString("TableStyle"));
5693 //		QString rowPositions(attrs.valueAsString("RowPositions"));
5694 //		QStringList slRowPositions=rowPositions.split(" ");
5695 //		qDebug()<<"RowCount"<<rows<<"row positions"<<slRowPositions.count();
5696 		doc->dontResize = true;
5697 
5698 		QString rowHeights(attrs.valueAsString("RowHeights",""));
5699 		if (!rowHeights.isEmpty())
5700 		{
5701 			QStringList slRowHeights=rowHeights.split(" ");
5702 			int i=0;
5703 			foreach(const QString& pos, slRowHeights)
5704 				tableitem->resizeRow(i++, pos.toDouble());
5705 		}
5706 //		QString colPositions(attrs.valueAsString("ColumnPositions"));
5707 //		QStringList slColPositions=colPositions.split(" ");
5708 		QString colWidths(attrs.valueAsString("ColumnWidths",""));
5709 		if (!colWidths.isEmpty())
5710 		{
5711 			QStringList slColWidths=colWidths.split(" ");
5712 			int i=0;
5713 			foreach(const QString& pos, slColWidths)
5714 				tableitem->resizeColumn(i++, pos.toDouble());
5715 		}
5716 		QString cellAreas(attrs.valueAsString("CellAreas"));
5717 		if (!cellAreas.isEmpty())
5718 		{
5719 			QStringList slCellAreas=cellAreas.split(" ");
5720 			if (slCellAreas.count()%4!=0)
5721 				qDebug()<<"Cell Area Count on load ! % 4";
5722 			for (int i = 0; i < slCellAreas.size(); i+=4)
5723 			{
5724 				int rows=slCellAreas.at(i).toInt();
5725 				int columns=slCellAreas.at(i+1).toInt();
5726 				int height=slCellAreas.at(i+2).toInt();
5727 				int width=slCellAreas.at(i+3).toInt();
5728 				tableitem->mergeCells(rows,columns,height,width);
5729 			}
5730 		}
5731 		doc->dontResize = false;
5732 	}
5733 
5734 	currItem->TopLine      = attrs.valueAsBool("TopLine", false);
5735 	currItem->LeftLine     = attrs.valueAsBool("LeftLine", false);
5736 	currItem->RightLine    = attrs.valueAsBool("RightLine", false);
5737 	currItem->BottomLine   = attrs.valueAsBool("BottomLine", false);
5738 	currItem->isTableItem  = attrs.valueAsBool("isTableItem", false);
5739 	currItem->TopLinkID    = attrs.valueAsInt("TopLINK", -1);
5740 	currItem->LeftLinkID   = attrs.valueAsInt("LeftLINK", -1);
5741 	currItem->RightLinkID  = attrs.valueAsInt("RightLINK", -1);
5742 	currItem->BottomLinkID = attrs.valueAsInt("BottomLINK", -1);
5743 	currItem->PoShow       = attrs.valueAsInt("PLTSHOW", 0);
5744 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
5745 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
5746 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
5747 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
5748 		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
5749 	else if ( attrs.valueAsInt("TEXTFLOW", 0) != 0)
5750 	{
5751 		if (attrs.valueAsInt("TEXTFLOW2", 0))
5752 			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox);
5753 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
5754 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
5755 		else
5756 			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
5757 	}
5758 	else
5759 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
5760 	currItem->setLocked (attrs.valueAsBool("LOCK", false));
5761 	currItem->setSizeLocked(attrs.valueAsBool("LOCKR", false));
5762 	currItem->fillRule    = attrs.valueAsBool("fillRule", true);
5763 	currItem->doOverprint = attrs.valueAsBool("doOverprint", false);
5764 	currItem->setFillTransparency(attrs.valueAsDouble("TransValue", 0.0));
5765 	currItem->setLineTransparency(attrs.valueAsDouble("TransValueS", 0.0));
5766 	currItem->setFillBlendmode(attrs.valueAsInt("TransBlend", 0));
5767 	currItem->setLineBlendmode(attrs.valueAsInt("TransBlendS", 0));
5768 	if (attrs.valueAsInt("TRANSPARENT", 0) == 1)
5769 		currItem->setFillColor(CommonStrings::None);
5770 	currItem->m_columns   = attrs.valueAsInt("COLUMNS", 1);
5771 	currItem->m_columnGap = attrs.valueAsDouble("COLGAP", 0.0);
5772 	if (attrs.valueAsInt("LAYER", 0) != -1)
5773 	{
5774 		currItem->setLayer(attrs.valueAsInt("LAYER", 0));
5775 		uint layerCount = doc->Layers.count();
5776 		bool found = false;
5777 		for (uint i = 0; i < layerCount; ++i)
5778 		{
5779 			if (doc->Layers[i].ID == currItem->m_layerID)
5780 			{
5781 				found = true;
5782 				break;
5783 			}
5784 		}
5785 		if (!found)
5786 			currItem->setLayer(doc->firstLayerID());
5787 	}
5788 	tmp = "";
5789 	if ((attrs.hasAttribute("NUMDASH")) && (attrs.valueAsInt("NUMDASH", 0) != 0))
5790 	{
5791 		tmp = attrs.valueAsString("DASHS");
5792 		ScTextStream dgv(&tmp, QIODevice::ReadOnly);
5793 		currItem->DashValues.clear();
5794 		int numDash = attrs.valueAsInt("NUMDASH", 0);
5795 		for (int cxv = 0; cxv < numDash; ++cxv)
5796 		{
5797 			dgv >> xf;
5798 			currItem->DashValues.append(xf);
5799 		}
5800 		tmp = "";
5801 	}
5802 	else
5803 		currItem->DashValues.clear();
5804 	currItem->DashOffset = attrs.valueAsDouble("DASHOFF", 0.0);
5805 
5806 	if (currItem->isRegularPolygon())
5807 	{
5808 		PageItem_RegularPolygon *regitem = currItem->asRegularPolygon();
5809 		regitem->polyCorners      = attrs.valueAsInt("POLYC", 4);
5810 		regitem->polyFactor       = attrs.valueAsDouble("POLYF", 0.5);
5811 		regitem->polyRotation     = attrs.valueAsDouble("POLYR", 0.0);
5812 		regitem->polyInnerRot     = attrs.valueAsDouble("POLYIR", 0.0);
5813 		regitem->polyCurvature    = attrs.valueAsDouble("POLYCUR", 0.0);
5814 		regitem->polyOuterCurvature    = attrs.valueAsDouble("POLYOCUR", 0.0);
5815 		regitem->polyUseFactor    = attrs.valueAsBool("POLYS", false);
5816 		regitem->recalcPath();
5817 	}
5818 	else if (currItem->isArc())
5819 	{
5820 		PageItem_Arc *arcitem = currItem->asArc();
5821 		arcitem->arcHeight     = attrs.valueAsDouble("arcHeight", 1.0);
5822 		arcitem->arcWidth      = attrs.valueAsDouble("arcWidth", 1.0);
5823 		arcitem->arcStartAngle = attrs.valueAsDouble("arcStartAngle", 30.0);
5824 		arcitem->arcSweepAngle = attrs.valueAsDouble("arcSweepAngle", 300.0);
5825 		arcitem->recalcPath();
5826 	}
5827 	else if (currItem->isSpiral())
5828 	{
5829 		PageItem_Spiral *arcitem = currItem->asSpiral();
5830 		arcitem->FrameType = 3; // Workaround for old docs, otherwise undo breaks spirals
5831 		arcitem->spiralStartAngle = attrs.valueAsDouble("spiralStartAngle", 0.0);
5832 		arcitem->spiralEndAngle = attrs.valueAsDouble("spiralEndAngle", 360.0);
5833 		arcitem->spiralFactor = attrs.valueAsDouble("spiralFactor", 1.2);
5834 		arcitem->recalcPath();
5835 	}
5836 	else
5837 	{
5838 		tmp = "";
5839 		if (attrs.hasAttribute("NUMPO"))
5840 		{
5841 			currItem->PoLine.resize(attrs.valueAsUInt("NUMPO"));
5842 			tmp = attrs.valueAsString("POCOOR");
5843 			double maxVal = std::numeric_limits<double>::max() / 2.0;
5844 			ScTextStream fp(&tmp, QIODevice::ReadOnly);
5845 			uint numPo = attrs.valueAsUInt("NUMPO");
5846 			for (uint cx=0; cx < numPo; ++cx)
5847 			{
5848 				fp >> xf;
5849 				fp >> yf;
5850 				if (xf >= 999999)
5851 					xf = maxVal;
5852 				if (yf >= 999999)
5853 					yf = maxVal;
5854 				currItem->PoLine.setPoint(cx, xf, yf);
5855 			}
5856 		}
5857 		else
5858 		{
5859 			currItem->PoLine.resize(0);
5860 			currItem->PoLine.parseSVG(attrs.valueAsString("path"));
5861 		}
5862 	}
5863 	tmp = "";
5864 	if (attrs.hasAttribute("NUMCO"))
5865 	{
5866 		currItem->ContourLine.resize(attrs.valueAsUInt("NUMCO"));
5867 		tmp = attrs.valueAsString("COCOOR");
5868 		double maxVal = std::numeric_limits<double>::max() / 2.0;
5869 		ScTextStream fp(&tmp, QIODevice::ReadOnly);
5870 		uint numCo = attrs.valueAsUInt("NUMCO");
5871 		for (uint cx=0; cx < numCo; ++cx)
5872 		{
5873 			fp >> xf;
5874 			fp >> yf;
5875 			if (xf >= 999999)
5876 				xf = maxVal;
5877 			if (yf >= 999999)
5878 				yf = maxVal;
5879 			currItem->ContourLine.setPoint(cx, xf, yf);
5880 		}
5881 	}
5882 	else if (attrs.hasAttribute("copath"))
5883 	{
5884 		currItem->ContourLine.resize(0);
5885 		currItem->ContourLine.parseSVG(attrs.valueAsString("copath"));
5886 	}
5887 	else
5888 		currItem->ContourLine = currItem->PoLine.copy();
5889 
5890 	if (!currItem->isLine())
5891 		currItem->Clip = flattenPath(currItem->PoLine, currItem->Segments);
5892 	else
5893 	{
5894 		currItem->Segments.clear();
5895 		currItem->PoLine.resize(0);
5896 		currItem->setHeight(1.0);
5897 		currItem->asLine()->setLineClip();
5898 	}
5899 
5900 	if (currItem->isPathText())
5901 		currItem->updatePolyClip();
5902 	currItem->GrType = attrs.valueAsInt("GRTYP", 0);
5903 	QString GrColor;
5904 	QString GrColor2;
5905 	int GrShade = 0;
5906 	int GrShade2 = 0;
5907 	if (currItem->GrType != 0)
5908 	{
5909 		if (currItem->GrType == Gradient_Pattern)
5910 		{
5911 			currItem->setPattern( attrs.valueAsString("pattern", "") );
5912 			double patternScaleX   = attrs.valueAsDouble("pScaleX", 100.0);
5913 			double patternScaleY   = attrs.valueAsDouble("pScaleY", 100.0);
5914 			double patternOffsetX  = attrs.valueAsDouble("pOffsetX", 0.0);
5915 			double patternOffsetY  = attrs.valueAsDouble("pOffsetY", 0.0);
5916 			double patternRotation = attrs.valueAsDouble("pRotation", 0.0);
5917 			double patternSkewX    = attrs.valueAsDouble("pSkewX", 0.0);
5918 			double patternSkewY    = attrs.valueAsDouble("pSkewY", 0.0);
5919 			currItem->setPatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
5920 			bool mirrorX = attrs.valueAsBool("pMirrorX", false);
5921 			bool mirrorY = attrs.valueAsBool("pMirrorY", false);
5922 			currItem->setPatternFlip(mirrorX, mirrorY);
5923 		}
5924 		else if (currItem->GrType == Gradient_Mesh)
5925 		{
5926 			currItem->meshGradientArray.clear();
5927 			int mGArrayRows = attrs.valueAsInt("GMAX", 1);
5928 			int mGArrayCols = attrs.valueAsInt("GMAY", 1);
5929 			for (int mgr = 0; mgr < mGArrayRows; mgr++)
5930 			{
5931 				QList<MeshPoint> ml;
5932 				for (int mgc = 0; mgc < mGArrayCols; mgc++)
5933 				{
5934 					MeshPoint mp;
5935 					ml.append(mp);
5936 				}
5937 				currItem->meshGradientArray.append(ml);
5938 			}
5939 		}
5940 		else if (currItem->GrType == Gradient_PatchMesh)
5941 		{
5942 			currItem->meshGradientPatches.clear();
5943 			int mGArrayRows = attrs.valueAsInt("GMAX", 1);
5944 			for (int mgr = 0; mgr < mGArrayRows; mgr++)
5945 			{
5946 				meshGradientPatch patchM;
5947 				currItem->meshGradientPatches.append(patchM);
5948 			}
5949 		}
5950 		else if (currItem->GrType == Gradient_Hatch)
5951 		{
5952 			int hatchType = attrs.valueAsInt("HatchMode", 0);
5953 			double hatchDistance = attrs.valueAsDouble("HatchDist", 2);
5954 			double hatchAngle = attrs.valueAsDouble("HatchAngle", 0);
5955 			bool hatchUseBackground = attrs.valueAsBool("HatchSolidB", false);
5956 			QString hatchBackground = attrs.valueAsString("HatchBackG", CommonStrings::None);
5957 			QString hatchForeground = attrs.valueAsString("HatchForeC", CommonStrings::None);
5958 			currItem->setHatchParameters(hatchType, hatchDistance, hatchAngle, hatchUseBackground, hatchBackground, hatchForeground);
5959 		}
5960 		else
5961 		{
5962 			currItem->GrStartX = attrs.valueAsDouble("GRSTARTX", 0.0);
5963 			currItem->GrStartY = attrs.valueAsDouble("GRSTARTY", 0.0);
5964 			currItem->GrEndX   = attrs.valueAsDouble("GRENDX", currItem->width());
5965 			currItem->GrEndY   = attrs.valueAsDouble("GRENDY", 0.0);
5966 			currItem->GrFocalX = attrs.valueAsDouble("GRFOCALX", 0.0);
5967 			currItem->GrFocalY = attrs.valueAsDouble("GRFOCALY", 0.0);
5968 			currItem->GrScale  = attrs.valueAsDouble("GRSCALE", 1.0);
5969 			currItem->GrSkew  = attrs.valueAsDouble("GRSKEW", 0.0);
5970 			GrColor = attrs.valueAsString("GRCOLOR","");
5971 			if (!GrColor.isEmpty())
5972 			{
5973 				GrColor2 = attrs.valueAsString("GRCOLOR2","");
5974 				GrShade  = attrs.valueAsInt("GRSHADE", 100);
5975 				GrShade2 = attrs.valueAsInt("GRSHADE2", 100);
5976 			}
5977 			QString GrName = "";
5978 			GrName = attrs.valueAsString("GRNAME","");
5979 			if (!GrName.isEmpty())
5980 				currItem->setGradient(GrName);
5981 			if ((currItem->GrType == Gradient_4Colors) || (currItem->GrType == Gradient_Diamond))
5982 			{
5983 				currItem->GrControl1 = FPoint(attrs.valueAsDouble("GRC1X", 0.0), attrs.valueAsDouble("GRC1Y", 0.0));
5984 				currItem->GrControl2 = FPoint(attrs.valueAsDouble("GRC2X", 0.0), attrs.valueAsDouble("GRC2Y", 0.0));
5985 				currItem->GrControl3 = FPoint(attrs.valueAsDouble("GRC3X", 0.0), attrs.valueAsDouble("GRC3Y", 0.0));
5986 				currItem->GrControl4 = FPoint(attrs.valueAsDouble("GRC4X", 0.0), attrs.valueAsDouble("GRC4Y", 0.0));
5987 				currItem->GrControl5 = FPoint(attrs.valueAsDouble("GRC5X", 0.0), attrs.valueAsDouble("GRC5Y", 0.0));
5988 				currItem->GrColorP1  = attrs.valueAsString("GRCOLP1", "Black");
5989 				currItem->GrColorP2  = attrs.valueAsString("GRCOLP2", "Black");
5990 				currItem->GrColorP3  = attrs.valueAsString("GRCOLP3", "Black");
5991 				currItem->GrColorP4  = attrs.valueAsString("GRCOLP4", "Black");
5992 				currItem->GrCol1transp  = attrs.valueAsDouble("GRCOLT1", 1.0);
5993 				currItem->GrCol2transp  = attrs.valueAsDouble("GRCOLT2", 1.0);
5994 				currItem->GrCol3transp  = attrs.valueAsDouble("GRCOLT3", 1.0);
5995 				currItem->GrCol4transp  = attrs.valueAsDouble("GRCOLT4", 1.0);
5996 				currItem->GrCol1Shade  = attrs.valueAsInt("GRCOLS1", 100);
5997 				currItem->GrCol2Shade  = attrs.valueAsInt("GRCOLS2", 100);
5998 				currItem->GrCol3Shade  = attrs.valueAsInt("GRCOLS3", 100);
5999 				currItem->GrCol4Shade  = attrs.valueAsInt("GRCOLS4", 100);
6000 				currItem->set4ColorColors(currItem->GrColorP1, currItem->GrColorP2, currItem->GrColorP3, currItem->GrColorP4);
6001 			}
6002 		}
6003 	}
6004 	if (((currItem->GrType != 0) && (currItem->GrType != Gradient_Pattern) && (currItem->GrType != Gradient_Hatch)) && (currItem->gradient().isEmpty()))
6005 	{
6006 		currItem->fill_gradient.clearStops();
6007 		if ((!GrColor.isEmpty()) && (!GrColor2.isEmpty()))
6008 		{
6009 			if (currItem->GrType == Gradient_RadialLegacy5)
6010 			{
6011 				if ((GrColor != CommonStrings::None) && (!GrColor.isEmpty()))
6012 					currItem->SetQColor(&tmpc, GrColor, GrShade);
6013 				currItem->fill_gradient.addStop(tmpc, 0.0, 0.5, 1.0, GrColor, GrShade);
6014 				if ((GrColor2 != CommonStrings::None) && (!GrColor2.isEmpty()))
6015 					currItem->SetQColor(&tmpc, GrColor2, GrShade2);
6016 				currItem->fill_gradient.addStop(tmpc, 1.0, 0.5, 1.0, GrColor2, GrShade2);
6017 			}
6018 			else
6019 			{
6020 				if ((GrColor2 != CommonStrings::None) && (!GrColor2.isEmpty()))
6021 					currItem->SetQColor(&tmpc, GrColor2, GrShade2);
6022 				currItem->fill_gradient.addStop(tmpc, 0.0, 0.5, 1.0, GrColor2, GrShade2);
6023 				if ((GrColor != CommonStrings::None) && (!GrColor.isEmpty()))
6024 					currItem->SetQColor(&tmpc, GrColor, GrShade);
6025 				currItem->fill_gradient.addStop(tmpc, 1.0, 0.5, 1.0, GrColor, GrShade);
6026 			}
6027 		}
6028 //		currItem->updateGradientVectors();
6029 	}
6030 	switch (currItem->GrType)
6031 	{
6032 		case Gradient_LinearLegacy1:
6033 		case Gradient_LinearLegacy2:
6034 		case Gradient_LinearLegacy3:
6035 		case Gradient_LinearLegacy4:
6036 			currItem->GrType = Gradient_Linear;
6037 			break;
6038 		case Gradient_RadialLegacy5:
6039 			currItem->GrType = Gradient_Radial;
6040 			break;
6041 		default:
6042 			break;
6043 	}
6044 
6045 	currItem->setStrokePattern( attrs.valueAsString("patternS", "") );
6046 	double patternScaleX   = attrs.valueAsDouble("pScaleXS", 100.0);
6047 	double patternScaleY   = attrs.valueAsDouble("pScaleYS", 100.0);
6048 	double patternOffsetX  = attrs.valueAsDouble("pOffsetXS", 0.0);
6049 	double patternOffsetY  = attrs.valueAsDouble("pOffsetYS", 0.0);
6050 	double patternRotation = attrs.valueAsDouble("pRotationS", 0.0);
6051 	double patternSkewX    = attrs.valueAsDouble("pSkewXS", 0.0);
6052 	double patternSkewY    = attrs.valueAsDouble("pSkewYS", 0.0);
6053 	double patternSpace    = attrs.valueAsDouble("pSpaceS", 1.0);
6054 	currItem->setStrokePatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace);
6055 	bool mirrorX = attrs.valueAsBool("pMirrorXS", false);
6056 	bool mirrorY = attrs.valueAsBool("pMirrorYS", false);
6057 	bool atPath = attrs.valueAsBool("pAtPathS", false);
6058 	currItem->setPatternFlip(mirrorX, mirrorY);
6059 	currItem->setStrokePatternToPath(atPath);
6060 	currItem->GrTypeStroke = attrs.valueAsInt("GRTYPS", 0);
6061 	if (((currItem->GrTypeStroke != 0) && (currItem->GrTypeStroke != Gradient_Pattern)) && (currItem->strokeGradient().isEmpty()))
6062 		currItem->stroke_gradient.clearStops();
6063 	currItem->GrStrokeStartX = attrs.valueAsDouble("GRSTARTXS", 0.0);
6064 	currItem->GrStrokeStartY = attrs.valueAsDouble("GRSTARTYS", 0.0);
6065 	currItem->GrStrokeEndX   = attrs.valueAsDouble("GRENDXS", currItem->width());
6066 	currItem->GrStrokeEndY   = attrs.valueAsDouble("GRENDYS", 0.0);
6067 	currItem->GrStrokeFocalX = attrs.valueAsDouble("GRFOCALXS", 0.0);
6068 	currItem->GrStrokeFocalY = attrs.valueAsDouble("GRFOCALYS", 0.0);
6069 	currItem->GrStrokeScale  = attrs.valueAsDouble("GRSCALES", 1.0);
6070 	currItem->GrStrokeSkew  = attrs.valueAsDouble("GRSKEWS", 0.0);
6071 	QString GrNameS = "";
6072 	GrNameS = attrs.valueAsString("GRNAMES","");
6073 	if (!GrNameS.isEmpty())
6074 		currItem->setStrokeGradient(GrNameS);
6075 
6076 
6077 	currItem->setPatternMask( attrs.valueAsString("patternM", "") );
6078 	double patternScaleXm   = attrs.valueAsDouble("pScaleXM", 100.0);
6079 	double patternScaleYm   = attrs.valueAsDouble("pScaleYM", 100.0);
6080 	double patternOffsetXm  = attrs.valueAsDouble("pOffsetXM", 0.0);
6081 	double patternOffsetYm  = attrs.valueAsDouble("pOffsetYM", 0.0);
6082 	double patternRotationm = attrs.valueAsDouble("pRotationM", 0.0);
6083 	double patternSkewXm    = attrs.valueAsDouble("pSkewXM", 0.0);
6084 	double patternSkewYm    = attrs.valueAsDouble("pSkewYM", 0.0);
6085 	currItem->setMaskTransform(patternScaleXm, patternScaleYm, patternOffsetXm, patternOffsetYm, patternRotationm, patternSkewXm, patternSkewYm);
6086 	bool mirrorXm = attrs.valueAsBool("pMirrorXM", false);
6087 	bool mirrorYm = attrs.valueAsBool("pMirrorYM", false);
6088 	currItem->setMaskFlip(mirrorXm, mirrorYm);
6089 	QString GrNameM = "";
6090 	GrNameM = attrs.valueAsString("GRNAMEM","");
6091 	currItem->GrMask = attrs.valueAsInt("GRTYPM", 0);
6092 	if ((currItem->GrMask == GradMask_Linear) || (currItem->GrMask == GradMask_LinearLumAlpha))
6093 		currItem->mask_gradient = VGradient(VGradient::linear);
6094 	else if ((currItem->GrMask == GradMask_Radial) || (currItem->GrMask == GradMask_RadialLumAlpha))
6095 		currItem->mask_gradient = VGradient(VGradient::radial);
6096 	if (((currItem->GrMask == GradMask_Linear) || (currItem->GrMask == GradMask_Radial) || (currItem->GrMask == GradMask_LinearLumAlpha) || (currItem->GrMask == GradMask_RadialLumAlpha)) && (GrNameM.isEmpty()))
6097 		currItem->mask_gradient.clearStops();
6098 	currItem->GrMaskStartX = attrs.valueAsDouble("GRSTARTXM", 0.0);
6099 	currItem->GrMaskStartY = attrs.valueAsDouble("GRSTARTYM", 0.0);
6100 	currItem->GrMaskEndX   = attrs.valueAsDouble("GRENDXM", currItem->width());
6101 	currItem->GrMaskEndY   = attrs.valueAsDouble("GRENDYM", 0.0);
6102 	currItem->GrMaskFocalX = attrs.valueAsDouble("GRFOCALXM", 0.0);
6103 	currItem->GrMaskFocalY = attrs.valueAsDouble("GRFOCALYM", 0.0);
6104 	currItem->GrMaskScale  = attrs.valueAsDouble("GRSCALEM", 1.0);
6105 	currItem->GrMaskSkew  = attrs.valueAsDouble("GRSKEWM", 0.0);
6106 	if (!GrNameM.isEmpty())
6107 		currItem->setGradientMask(GrNameM);
6108 	if (attrs.hasAttribute("InID"))
6109 		currItem->inlineCharID = attrs.valueAsInt("InID", -1);
6110 	else
6111 		currItem->inlineCharID = -1;
6112 	currItem->setGradientExtend((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("GRExt", VGradient::pad)));
6113 	currItem->setStrokeGradientExtend((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("GRExtS", VGradient::pad)));
6114 	currItem->mask_gradient.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("GRExtM", VGradient::pad)));
6115 
6116 	currItem->setHasSoftShadow(attrs.valueAsBool("HASSOFTSHADOW", false));
6117 	currItem->setSoftShadowXOffset(attrs.valueAsDouble("SOFTSHADOWXOFFSET", 5.0));
6118 	currItem->setSoftShadowYOffset(attrs.valueAsDouble("SOFTSHADOWYOFFSET", 5.0));
6119 	currItem->setSoftShadowColor(attrs.valueAsString("SOFTSHADOWCOLOR", "Black"));
6120 	currItem->setSoftShadowShade(attrs.valueAsInt("SOFTSHADOWSHADE", 100));
6121 	currItem->setSoftShadowBlurRadius(attrs.valueAsDouble("SOFTSHADOWBLURRADIUS", 5.0));
6122 	currItem->setSoftShadowBlendMode(attrs.valueAsInt("SOFTSHADOWBLENDMODE", 0));
6123 	currItem->setSoftShadowOpacity(attrs.valueAsDouble("SOFTSHADOWOPACITY", 0.0));
6124 	currItem->setSoftShadowErasedByObject(attrs.valueAsBool("SOFTSHADOWERASE", false));
6125 	currItem->setSoftShadowHasObjectTransparency(attrs.valueAsBool("SOFTSHADOWOBJTRANS", false));
6126 
6127 	//currItem->setRedrawBounding();
6128 	//currItem->OwnPage = view->OnPage(currItem);
6129 	return currItem;
6130 }
6131 
readItemTableData(PageItem_Table * item,ScXmlStreamReader & reader,ScribusDoc * doc)6132 bool Scribus150Format::readItemTableData(PageItem_Table* item, ScXmlStreamReader& reader, ScribusDoc* doc)
6133 {
6134 	ScXmlStreamAttributes attrs = reader.scAttributes();
6135 	QString fColor = attrs.valueAsString("FillColor");
6136 	if ((fColor != CommonStrings::None) && (!fColor.isEmpty()))
6137 		item->setFillColor(fColor);
6138 	item->setFillShade(attrs.valueAsInt("FillShade", 100));
6139 	QStringRef tagName = reader.name();
6140 	LastStyles lastStyle;
6141 	doc->dontResize = true;
6142 	while (!reader.atEnd() && !reader.hasError())
6143 	{
6144 		reader.readNext();
6145 		if (reader.isEndElement() && reader.name() == tagName)
6146 			break;
6147 		if (!reader.isStartElement())
6148 			continue;
6149 
6150 		if (reader.name() == "Cell")
6151 		{
6152 			readItemTableCell(item, reader, doc);
6153 		}
6154 		else if (reader.name() == "TableBorderLeft")
6155 		{
6156 			TableBorder border;
6157 			QStringRef tagName = reader.name();
6158 			while (!reader.atEnd() && !reader.hasError())
6159 			{
6160 				reader.readNext();
6161 				if (reader.isEndElement() && reader.name() == tagName)
6162 					break;
6163 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6164 				{
6165 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6166 					double width = tAttB.valueAsDouble("Width", 0.0);
6167 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6168 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6169 					int style = tAttB.valueAsInt("PenStyle", 1);
6170 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6171 				}
6172 			}
6173 			item->setLeftBorder(border);
6174 		}
6175 		else if (reader.name() == "TableBorderRight")
6176 		{
6177 			TableBorder border;
6178 			QStringRef tagName = reader.name();
6179 			while (!reader.atEnd() && !reader.hasError())
6180 			{
6181 				reader.readNext();
6182 				if (reader.isEndElement() && reader.name() == tagName)
6183 					break;
6184 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6185 				{
6186 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6187 					double width = tAttB.valueAsDouble("Width", 0.0);
6188 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6189 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6190 					int style = tAttB.valueAsInt("PenStyle", 1);
6191 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6192 				}
6193 			}
6194 			item->setRightBorder(border);
6195 		}
6196 		else if (reader.name() == "TableBorderTop")
6197 		{
6198 			TableBorder border;
6199 			QStringRef tagName = reader.name();
6200 			while (!reader.atEnd() && !reader.hasError())
6201 			{
6202 				reader.readNext();
6203 				if (reader.isEndElement() && reader.name() == tagName)
6204 					break;
6205 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6206 				{
6207 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6208 					double width = tAttB.valueAsDouble("Width", 0.0);
6209 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6210 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6211 					int style = tAttB.valueAsInt("PenStyle", 1);
6212 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6213 				}
6214 			}
6215 			item->setTopBorder(border);
6216 		}
6217 		else if (reader.name() == "TableBorderBottom")
6218 		{
6219 			TableBorder border;
6220 			QStringRef tagName = reader.name();
6221 			while (!reader.atEnd() && !reader.hasError())
6222 			{
6223 				reader.readNext();
6224 				if (reader.isEndElement() && reader.name() == tagName)
6225 					break;
6226 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6227 				{
6228 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6229 					double width = tAttB.valueAsDouble("Width", 0.0);
6230 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6231 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6232 					int style = tAttB.valueAsInt("PenStyle", 1);
6233 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6234 				}
6235 			}
6236 			item->setBottomBorder(border);
6237 		}
6238 		else
6239 		{
6240 			reader.skipCurrentElement();
6241 		}
6242 	}
6243 	item->adjustTableToFrame();
6244 	item->adjustFrameToTable();
6245 	doc->dontResize = false;
6246 	return !reader.hasError();
6247 }
6248 
readItemTableCell(PageItem_Table * item,ScXmlStreamReader & reader,ScribusDoc * doc)6249 bool Scribus150Format::readItemTableCell(PageItem_Table* item, ScXmlStreamReader& reader, ScribusDoc *doc)
6250 {
6251 	QStringRef tagName = reader.name();
6252 	ScXmlStreamAttributes tAtt = reader.scAttributes();
6253 
6254 	int row = tAtt.valueAsInt("Row", -1);
6255 	int col = tAtt.valueAsInt("Column", -1);
6256 	if ((row >= 0) && (col >= 0))
6257 	{
6258 		if (tAtt.hasAttribute("Style"))
6259 		{
6260 			QString Style = tAtt.valueAsString("Style");
6261 			if (!Style.isEmpty())
6262 				item->cellAt(row, col).setStyle(Style);
6263 		}
6264 		QString fColor = tAtt.valueAsString("FillColor");
6265 		if ((fColor != CommonStrings::None) && (!fColor.isEmpty()))
6266 			item->cellAt(row, col).setFillColor(fColor);
6267 		double fShade = tAtt.valueAsDouble("FillShade", -1.0);
6268 		if (fShade >= 0 && fShade <= 100)
6269 			item->cellAt(row, col).setFillShade(fShade);
6270 		if (tAtt.hasAttribute("LeftPadding"))
6271 			item->cellAt(row, col).setLeftPadding(tAtt.valueAsDouble("LeftPadding", 0.0));
6272 		if (tAtt.hasAttribute("RightPadding"))
6273 			item->cellAt(row, col).setRightPadding(tAtt.valueAsDouble("RightPadding", 0.0));
6274 		if (tAtt.hasAttribute("TopPadding"))
6275 			item->cellAt(row, col).setTopPadding(tAtt.valueAsDouble("TopPadding", 0.0));
6276 		if (tAtt.hasAttribute("BottomPadding"))
6277 			item->cellAt(row, col).setBottomPadding(tAtt.valueAsDouble("BottomPadding", 0.0));
6278 
6279 		PageItem* newItem = item->cellAt(row, col).textFrame();
6280 		newItem->m_columns   = tAtt.valueAsInt("TextColumns", 1);
6281 		newItem->m_columnGap = tAtt.valueAsDouble("TextColGap", 0.0);
6282 		newItem->setTextToFrameDist(tAtt.valueAsDouble("TextDistLeft", 0.0),
6283 							tAtt.valueAsDouble("TextDistRight", 0.0),
6284 							tAtt.valueAsDouble("TextDistTop", 0.0),
6285 							tAtt.valueAsDouble("TextDistBottom", 0.0));
6286 		newItem->setVerticalAlignment(tAtt.valueAsInt("TextVertAlign", 0));
6287 		newItem->setFirstLineOffset(static_cast<FirstLineOffsetPolicy>(tAtt.valueAsInt("Flop")));
6288 	}
6289 
6290 	LastStyles lastStyle;
6291 	while (!reader.atEnd() && !reader.hasError())
6292 	{
6293 		reader.readNext();
6294 		if (reader.isEndElement() && reader.name() == tagName)
6295 			break;
6296 		if (!reader.isStartElement())
6297 			continue;
6298 
6299 		if (reader.name() == "TableBorderLeft")
6300 		{
6301 			TableBorder border;
6302 			QStringRef tagName = reader.name();
6303 			while (!reader.atEnd() && !reader.hasError())
6304 			{
6305 				reader.readNext();
6306 				if (reader.isEndElement() && reader.name() == tagName)
6307 					break;
6308 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6309 				{
6310 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6311 					double width = tAttB.valueAsDouble("Width", 0.0);
6312 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6313 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6314 					int style = tAttB.valueAsInt("PenStyle", 1);
6315 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6316 				}
6317 			}
6318 			item->cellAt(row, col).setLeftBorder(border);
6319 		}
6320 		else if (reader.name() == "TableBorderRight")
6321 		{
6322 			TableBorder border;
6323 			QStringRef tagName = reader.name();
6324 			while (!reader.atEnd() && !reader.hasError())
6325 			{
6326 				reader.readNext();
6327 				if (reader.isEndElement() && reader.name() == tagName)
6328 					break;
6329 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6330 				{
6331 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6332 					double width = tAttB.valueAsDouble("Width", 0.0);
6333 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6334 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6335 					int style = tAttB.valueAsInt("PenStyle", 1);
6336 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6337 				}
6338 			}
6339 			item->cellAt(row, col).setRightBorder(border);
6340 		}
6341 		else if (reader.name() == "TableBorderTop")
6342 		{
6343 			TableBorder border;
6344 			QStringRef tagName = reader.name();
6345 			while (!reader.atEnd() && !reader.hasError())
6346 			{
6347 				reader.readNext();
6348 				if (reader.isEndElement() && reader.name() == tagName)
6349 					break;
6350 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6351 				{
6352 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6353 					double width = tAttB.valueAsDouble("Width", 0.0);
6354 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6355 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6356 					int style = tAttB.valueAsInt("PenStyle", 1);
6357 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6358 				}
6359 			}
6360 			item->cellAt(row, col).setTopBorder(border);
6361 		}
6362 		else if (reader.name() == "TableBorderBottom")
6363 		{
6364 			TableBorder border;
6365 			QStringRef tagName = reader.name();
6366 			while (!reader.atEnd() && !reader.hasError())
6367 			{
6368 				reader.readNext();
6369 				if (reader.isEndElement() && reader.name() == tagName)
6370 					break;
6371 				if (reader.isStartElement() && reader.name() == "TableBorderLine")
6372 				{
6373 					ScXmlStreamAttributes tAttB = reader.scAttributes();
6374 					double width = tAttB.valueAsDouble("Width", 0.0);
6375 					QString color = tAttB.valueAsString("Color", CommonStrings::None);
6376 					double shade = tAttB.valueAsDouble("Shade", 100.0);
6377 					int style = tAttB.valueAsInt("PenStyle", 1);
6378 					border.addBorderLine(TableBorderLine(width, static_cast<Qt::PenStyle>(style), color, shade));
6379 				}
6380 			}
6381 			item->cellAt(row, col).setBottomBorder(border);
6382 		}
6383 		else if (reader.name() == "StoryText")
6384 		{
6385 			PageItem* newItem = item->cellAt(row, col).textFrame();
6386 			readStoryText(doc, reader, newItem->itemText, newItem);
6387 		}
6388 		else
6389 		{
6390 			reader.skipCurrentElement();
6391 		}
6392 	}
6393 
6394 	return !reader.hasError();
6395 }
6396 
readLatexInfo(PageItem_LatexFrame * latexitem,ScXmlStreamReader & reader)6397 bool Scribus150Format::readLatexInfo(PageItem_LatexFrame* latexitem, ScXmlStreamReader& reader)
6398 {
6399 	ScXmlStreamAttributes attrs = reader.scAttributes();
6400 	QStringRef tagName = reader.name();
6401 
6402 	latexitem->setConfigFile(attrs.valueAsString("ConfigFile"), true);
6403 	latexitem->setDpi(attrs.valueAsInt("DPI"));
6404 	latexitem->setUsePreamble(attrs.valueAsBool("USE_PREAMBLE"));
6405 
6406 	QString formula;
6407 	while (!reader.atEnd() && !reader.hasError())
6408 	{
6409 		reader.readNext();
6410 		if (reader.isEndElement() && reader.name() == tagName)
6411 			break;
6412 		if (reader.isCharacters())
6413 			formula += reader.text().toString();
6414 		if (reader.isStartElement() && reader.name() == "PROPERTY")
6415 		{
6416 			ScXmlStreamAttributes tAtt = reader.scAttributes();
6417 			QString name  = tAtt.valueAsString("name");
6418 			QString value = tAtt.valueAsString("value");
6419 			if (name.isEmpty()) continue;
6420 			latexitem->editorProperties[name] = value;
6421 		}
6422 	}
6423 	formula = formula.trimmed();
6424 	latexitem->setFormula(formula, false);
6425 
6426 	return !reader.hasError();
6427 }
6428 
loadPage(const QString & fileName,int pageNumber,bool Mpage,const QString & renamedPageName)6429 bool Scribus150Format::loadPage(const QString & fileName, int pageNumber, bool Mpage, const QString& renamedPageName)
6430 {
6431 // 	qDebug() << QString("loading page %2 from file '%1' from 1.3.x plugin").arg(fileName).arg(pageNumber);
6432 	if (m_Doc==nullptr || m_AvailableFonts==nullptr)
6433 	{
6434 		Q_ASSERT(m_Doc==nullptr || m_AvailableFonts==nullptr);
6435 		return false;
6436 	}
6437 
6438 	Xp = 0.0;
6439 	Yp = 0.0;
6440 	GrX = 0.0;
6441 	GrY = 0.0;
6442 	struct ScribusDoc::BookMa bok;
6443 	QMap<int, ScribusDoc::BookMa> bookmarks;
6444 
6445 	ScPage* newPage = nullptr;
6446 
6447 	QMap<int, PageItem*> TableID;
6448 	QList<PageItem*> TableItems;
6449 	QMap<int, PageItem*> WeldID;
6450 	QList<PageItem*> WeldItems;
6451 	QStack< QList<PageItem*> > groupStackFI;
6452 	QStack< QList<PageItem*> > groupStackMI;
6453 	QStack< QList<PageItem*> > groupStackPI;
6454 	QStack< QList<PageItem*> > groupStackF;
6455 	QStack< QList<PageItem*> > groupStackM;
6456 	QStack< QList<PageItem*> > groupStackP;
6457 	QStack<int> groupStackFI2;
6458 	QStack<int> groupStackMI2;
6459 	QStack<int> groupStackPI2;
6460 	double pageX = 0, pageY = 0;
6461 	QMap<int,int> layerTrans;
6462 	int maxLayer = 0, maxLevel = 0, a = 0;
6463 
6464 	layerTrans.clear();
6465 	uint layerCount=m_Doc->layerCount();
6466 	for (uint la2 = 0; la2 < layerCount; ++la2)
6467 	{
6468 		maxLayer = qMax(m_Doc->Layers[la2].ID, maxLayer);
6469 		maxLevel = qMax(m_Doc->Layers[la2].Level, maxLevel);
6470 	}
6471 
6472 	parStyleMap.clear();
6473 	charStyleMap.clear();
6474 	itemRemap.clear();
6475 	itemNext.clear();
6476 	itemCount = 0;
6477 	itemRemapM.clear();
6478 	itemNextM.clear();
6479 	itemCountM = 0;
6480 	itemRemapF.clear();
6481 	itemNextF.clear();
6482 
6483 	FrameItems.clear();
6484 	WeldItems.clear();
6485 	WeldID.clear();
6486 	LinkID.clear();
6487 
6488 	markeredItemsMap.clear();
6489 	markeredMarksMap.clear();
6490 	nsetRangeItemNamesMap.clear();
6491 	notesFramesData.clear();
6492 	notesMasterMarks.clear();
6493 	notesNSets.clear();
6494 
6495 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
6496 	if (ioDevice.isNull())
6497 	{
6498 		setFileReadError();
6499 		return false;
6500 	}
6501 
6502 	QString fileDir = QFileInfo(fileName).absolutePath();
6503 
6504 	ReadObjectParams readObjectParams;
6505 	readObjectParams.baseDir = fileDir;
6506 	readObjectParams.itemKind = PageItem::StandardItem;
6507 	readObjectParams.loadingPage = true;
6508 	readObjectParams.renamedMasterPage = Mpage ? renamedPageName : QString();
6509 
6510 	bool firstElement = true;
6511 	bool success = true;
6512 	isNewFormat = false;
6513 
6514 	ScXmlStreamReader reader(ioDevice.data());
6515 	ScXmlStreamAttributes attrs;
6516 	while (!reader.atEnd() && !reader.hasError())
6517 	{
6518 		QXmlStreamReader::TokenType tType = reader.readNext();
6519 		if (tType != QXmlStreamReader::StartElement)
6520 			continue;
6521 		QStringRef tagName = reader.name();
6522 		attrs = reader.scAttributes();
6523 
6524 		if (firstElement)
6525 		{
6526 			if (tagName != "SCRIBUSUTF8NEW")
6527 			{
6528 				success = false;
6529 				break;
6530 			}
6531 			firstElement = false;
6532 		}
6533 
6534 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
6535 		{
6536 			QString colorName = attrs.valueAsString("NAME");
6537 			if (m_Doc->PageColors.contains(colorName))
6538 				continue;
6539 			readColor(m_Doc->PageColors, attrs);
6540 		}
6541 		if (tagName == "Gradient" && attrs.valueAsString("Name") != CommonStrings::None)
6542 		{
6543 			VGradient gra;
6544 			QString grName = attrs.valueAsString("Name");
6545 			success = readGradient(m_Doc, gra, reader);
6546 			if (!success)
6547 				break;
6548 			gra.setRepeatMethod((VGradient::VGradientRepeatMethod)(attrs.valueAsInt("Ext", VGradient::pad)));
6549 			if (!grName.isEmpty() && !m_Doc->docGradients.contains(grName))
6550 				m_Doc->docGradients.insert(grName, gra);
6551 		}
6552 		if (tagName == "JAVA")
6553 		{
6554 			QString name = attrs.valueAsString("NAME");
6555 			if (!name.isEmpty())
6556 				m_Doc->JavaScripts[name] = attrs.valueAsString("SCRIPT");
6557 		}
6558 		if (tagName == "LAYERS")
6559 		{
6560 			ScLayer newLayer;
6561 			readLayers(newLayer, attrs);
6562 			const ScLayer* la2 = m_Doc->Layers.layerByName(newLayer.Name);
6563 			if (la2)
6564 				layerTrans.insert(newLayer.ID, la2->ID);
6565 			else
6566 			{
6567 				maxLayer++;
6568 				maxLevel++;
6569 				layerTrans.insert(newLayer.ID, maxLayer);
6570 				newLayer.ID = maxLayer;
6571 				newLayer.Level = maxLevel;
6572 				m_Doc->Layers.append(newLayer);
6573 			}
6574 		}
6575 		if (tagName == "Arrows")
6576 		{
6577 			success = readArrows(m_Doc, attrs);
6578 			if (!success) break;
6579 		}
6580 		if (tagName == "MultiLine")
6581 		{
6582 			multiLine ml;
6583 			QString mlName  = attrs.valueAsString("Name");
6584 			QString mlName2 = mlName;
6585 			readMultiline(ml, reader);
6586 			QHash<QString, multiLine>::ConstIterator mlit = m_Doc->docLineStyles.constFind(mlName2);
6587 			if (mlit != m_Doc->docLineStyles.constEnd() && ml != mlit.value())
6588 				mlName2 = getUniqueName(mlName2, m_Doc->docLineStyles);
6589 			m_Doc->docLineStyles.insert(mlName2, ml);
6590 		}
6591 		if (tagName == "Pattern")
6592 		{
6593 			success = readPattern(m_Doc, reader, fileDir);
6594 			if (!success) break;
6595 		}
6596 		if (tagName == "Bookmark")
6597 		{
6598 			int bmElem = 0;
6599 			struct ScribusDoc::BookMa bookmark;
6600 			success = readBookMark(bookmark, bmElem, attrs);
6601 			if (!success) break;
6602 			bookmarks.insert(bmElem, bookmark);
6603 		}
6604 		if (tagName == "STYLE")
6605 		{
6606 			ParagraphStyle pstyle;
6607 			getStyle(pstyle, reader, nullptr, m_Doc, true);
6608 		}
6609 		if (tagName == "CHARSTYLE")
6610 		{
6611 			CharStyle cstyle;
6612 			getStyle(cstyle, reader, nullptr, m_Doc, true);
6613 		}
6614 		if (tagName == "TableStyle")
6615 		{
6616 			TableStyle tstyle;
6617 			readTableStyle(m_Doc, reader, tstyle);
6618 			// FIXME: import style under new name if existing
6619 			// Do not break current doc for now
6620 			if (m_Doc->tableStyles().contains(tstyle.name()))
6621 				continue;
6622 			StyleSet<TableStyle> temp;
6623 			temp.create(tstyle);
6624 			m_Doc->redefineTableStyles(temp, false);
6625 		}
6626 		if (tagName == "CellStyle")
6627 		{
6628 			CellStyle tstyle;
6629 			readCellStyle(m_Doc, reader, tstyle);
6630 			// FIXME: import style under new name if existing
6631 			// Do not break current doc for now
6632 			if (m_Doc->cellStyles().contains(tstyle.name()))
6633 				continue;
6634 			StyleSet<CellStyle> temp;
6635 			temp.create(tstyle);
6636 			m_Doc->redefineCellStyles(temp, false);
6637 		}
6638 		if (((tagName == "PAGE") || (tagName == "MASTERPAGE")) && (attrs.valueAsInt("NUM") == pageNumber))
6639 		{
6640 			if (Mpage && (tagName != "MASTERPAGE"))
6641 				continue;
6642 			a = m_Doc->currentPage()->pageNr();
6643 			newPage = m_Doc->Pages->at(a);
6644 			SimpleState *ss = nullptr;
6645 			if (UndoManager::undoEnabled())
6646 			{
6647 				ss = new SimpleState(Um::ChangePageAttrs, "", Um::ICreate);
6648 				ss->set("PAGE_ATTRS");
6649 				ss->set("LEFT_OLD", newPage->LeftPg);
6650 				ss->set("NAME_OLD", newPage->pageName());
6651 				ss->set("ORIENTATION_OLD", newPage->orientation());
6652 				ss->set("SIZE_OLD", newPage->size());
6653 				ss->set("WIDTH_OLD", newPage->width());
6654 				ss->set("HEIGHT_OLD", newPage->height());
6655 				ss->set("INIT_HEIGHT_OLD", newPage->initialHeight());
6656 				ss->set("INIT_WIDTH_OLD", newPage->initialWidth());
6657 				ss->set("INIT_MARGINTOP_OLD", newPage->initialMargins.top());
6658 				ss->set("INIT_MARGINBOTTOM_OLD", newPage->initialMargins.bottom());
6659 				ss->set("INIT_MARGINRIGHT_OLD", newPage->initialMargins.right());
6660 				ss->set("INIT_MARGINLEFT_OLD", newPage->initialMargins.left());
6661 				ss->set("MARGINTOP_OLD", newPage->Margins.top());
6662 				ss->set("MARGINBOTTOM_OLD", newPage->Margins.bottom());
6663 				ss->set("MARGINPRESET_OLD", newPage->marginPreset);
6664 				ss->set("HORIZONTAL_AUTOGAP_OLD", newPage->guides.horizontalAutoGap());
6665 				ss->set("VERTICAL_AUTOGAP_OLD", newPage->guides.verticalAutoGap());
6666 				ss->set("HORIZONTAL_AUTOCOUNT_OLD", newPage->guides.horizontalAutoCount());
6667 				ss->set("VERTICAL_AUTOCOUNT_OLD", newPage->guides.verticalAutoCount());
6668 				ss->set("HORIZONTAL_AUTOREFER_OLD", newPage->guides.horizontalAutoRefer());
6669 				ss->set("VERTICAL_AUTOREFER_OLD", newPage->guides.verticalAutoRefer());
6670 			}
6671 			if (Mpage)
6672 			{
6673 				newPage->LeftPg = attrs.valueAsInt("LEFT", 0);
6674 
6675 				if (!renamedPageName.isEmpty())
6676 					newPage->setPageName(renamedPageName);
6677 				else
6678 					newPage->setPageName(attrs.valueAsString("NAM",""));
6679 			}
6680 			if (attrs.hasAttribute("Size"))
6681 				newPage->setSize(attrs.valueAsString("Size"));
6682 			if (attrs.hasAttribute("Orientation"))
6683 				newPage->setOrientation(attrs.valueAsInt("Orientation"));
6684 			if (attrs.hasAttribute("PAGEWIDTH"))
6685 				newPage->setWidth( attrs.valueAsDouble("PAGEWIDTH") );
6686 			else
6687 				newPage->setWidth( attrs.valueAsDouble("PAGEWITH") );
6688 			newPage->setHeight( attrs.valueAsDouble("PAGEHEIGHT") );
6689 			newPage->setInitialHeight(newPage->height());
6690 			newPage->setInitialWidth(newPage->width());
6691 			newPage->initialMargins.setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
6692 			newPage->initialMargins.setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
6693 			newPage->initialMargins.setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
6694 			newPage->initialMargins.setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
6695 			newPage->marginPreset = attrs.valueAsInt("PRESET", 0);
6696 			newPage->Margins.setTop(newPage->initialMargins.top());
6697 			newPage->Margins.setBottom(newPage->initialMargins.bottom());
6698 			pageX = attrs.valueAsDouble("PAGEXPOS");
6699 			pageY = attrs.valueAsDouble("PAGEYPOS");
6700 
6701 			// guides reading
6702 			newPage->guides.setHorizontalAutoGap(attrs.valueAsDouble("AGhorizontalAutoGap", 0.0));
6703 			newPage->guides.setVerticalAutoGap(attrs.valueAsDouble("AGverticalAutoGap", 0.0));
6704 			newPage->guides.setHorizontalAutoCount(attrs.valueAsInt("AGhorizontalAutoCount", 0));
6705 			newPage->guides.setVerticalAutoCount(attrs.valueAsInt("AGverticalAutoCount", 0));
6706 			newPage->guides.setHorizontalAutoRefer(attrs.valueAsInt("AGhorizontalAutoRefer", 0));
6707 			newPage->guides.setVerticalAutoRefer(attrs.valueAsInt("AGverticalAutoRefer", 0));
6708 			GuideManagerIO::readVerticalGuides(attrs.valueAsString("VerticalGuides"),
6709 											newPage,
6710 											GuideManagerCore::Standard,
6711 											attrs.hasAttribute("NumVGuides"));
6712 			GuideManagerIO::readHorizontalGuides(attrs.valueAsString("HorizontalGuides"),
6713 											newPage,
6714 											GuideManagerCore::Standard,
6715 											attrs.hasAttribute("NumHGuides"));
6716 			GuideManagerIO::readSelection(attrs.valueAsString("AGSelection"), newPage);
6717 
6718 			newPage->guides.addHorizontals(newPage->guides.getAutoHorizontals(newPage), GuideManagerCore::Auto);
6719 			newPage->guides.addVerticals(newPage->guides.getAutoVerticals(newPage), GuideManagerCore::Auto);
6720 			if (UndoManager::undoEnabled())
6721 			{
6722 				ss->set("LEFT", newPage->LeftPg);
6723 				ss->set("NAME", newPage->pageName());
6724 				ss->set("ORIENTATION", newPage->orientation());
6725 				ss->set("SIZE", newPage->size());
6726 				ss->set("WIDTH", newPage->width());
6727 				ss->set("HEIGHT", newPage->height());
6728 				ss->set("INIT_HEIGHT", newPage->initialHeight());
6729 				ss->set("INIT_WIDTH", newPage->initialWidth());
6730 				ss->set("INIT_MARGINTOP", newPage->initialMargins.top());
6731 				ss->set("INIT_MARGINBOTTOM", newPage->initialMargins.bottom());
6732 				ss->set("INIT_MARGINRIGHT", newPage->initialMargins.right());
6733 				ss->set("INIT_MARGINLEFT", newPage->initialMargins.left());
6734 				ss->set("MARGINTOP", newPage->Margins.top());
6735 				ss->set("MARGINBOTTOM", newPage->Margins.bottom());
6736 				ss->set("MARGINPRESET", newPage->marginPreset);
6737 				ss->set("HORIZONTAL_AUTOGAP", newPage->guides.horizontalAutoGap());
6738 				ss->set("VERTICAL_AUTOGAP", newPage->guides.verticalAutoGap());
6739 				ss->set("HORIZONTAL_AUTOCOUNT", newPage->guides.horizontalAutoCount());
6740 				ss->set("VERTICAL_AUTOCOUNT", newPage->guides.verticalAutoCount());
6741 				ss->set("HORIZONTAL_AUTOREFER", newPage->guides.horizontalAutoRefer());
6742 				ss->set("VERTICAL_AUTOREFER", newPage->guides.verticalAutoRefer());
6743 				undoManager->action(newPage, ss);
6744 			}
6745 		}
6746 		if ((tagName == "PAGEOBJECT") || (tagName == "MASTEROBJECT") || (tagName == "FRAMEOBJECT"))
6747 		{
6748 			if ((Mpage && tagName != "MASTEROBJECT") || (!Mpage && tagName == "MASTEROBJECT"))
6749 			{
6750 				// Go to end of node
6751 				reader.readToElementEnd();
6752 				continue;
6753 			}
6754 			if (attrs.valueAsInt("OwnPage") != pageNumber)
6755 			{
6756 				if (tagName == "PAGEOBJECT")
6757 					itemRemap[itemCount++] = -1;
6758 				else if (tagName == "MASTEROBJECT")
6759 					itemRemapM[itemCountM++] = -1;
6760 				reader.readToElementEnd();
6761 			}
6762 			else
6763 			{
6764 				ItemInfo itemInfo;
6765 				success = readObject(m_Doc, reader, readObjectParams, itemInfo);
6766 				if (!success) break;
6767 
6768 				PageItem* newItem = itemInfo.item;
6769 				newItem->moveBy(-pageX + newPage->xOffset(), - pageY + newPage->yOffset());
6770 				newItem->setOwnerPage(m_Doc->currentPageNumber());
6771 				if (tagName == "PAGEOBJECT")
6772 					newItem->setMasterPageName(QString());
6773 				else if (Mpage && !renamedPageName.isEmpty())
6774 					newItem->setMasterPageName(renamedPageName);
6775 				newItem->setLayer(layerTrans.value(newItem->m_layerID, newItem->m_layerID));
6776 				if (isNewFormat)
6777 				{
6778 					if (itemInfo.nextItem != -1)
6779 						itemNext[itemInfo.itemID] = itemInfo.nextItem;
6780 					if (itemInfo.item->isTableItem)
6781 						TableItems.append(itemInfo.item);
6782 					if (itemInfo.isWeldFlag)
6783 						WeldItems.append(itemInfo.item);
6784 				}
6785 				else
6786 				{
6787 					// first of linked chain?
6788 					if (tagName == "PAGEOBJECT")
6789 					{
6790 						itemRemap[itemCount++] = m_Doc->DocItems.count();
6791 						if (attrs.valueAsInt("NEXTITEM", -1) != -1)
6792 							itemNext[m_Doc->DocItems.count()] = attrs.valueAsInt("NEXTITEM");
6793 					}
6794 					else if (tagName == "MASTEROBJECT")
6795 					{
6796 						itemRemapM[itemCountM++] = m_Doc->MasterItems.count();
6797 						if (attrs.valueAsInt("NEXTITEM", -1) != -1)
6798 							itemNextM[m_Doc->MasterItems.count()] = attrs.valueAsInt("NEXTITEM");
6799 					}
6800 					if (newItem->isTableItem)
6801 					{
6802 						TableItems.append(newItem);
6803 						TableID.insert(itemInfo.ownLink, newItem);
6804 					}
6805 					if (itemInfo.isWeldFlag)
6806 					{
6807 						WeldItems.append(itemInfo.item);
6808 						WeldID.insert(itemInfo.ownWeld, itemInfo.item);
6809 					}
6810 				}
6811 
6812 				if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
6813 				{
6814 					groupStackPI.top().append(itemInfo.item);
6815 					while (itemInfo.ownNr == groupStackPI2.top())
6816 					{
6817 						groupStackP.push(groupStackPI.pop());
6818 						groupStackPI2.pop();
6819 						if (groupStackPI2.count() == 0)
6820 							break;
6821 					}
6822 				}
6823 				else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
6824 				{
6825 					groupStackFI.top().append(itemInfo.item);
6826 					while (itemInfo.ownNr == groupStackFI2.top())
6827 					{
6828 						groupStackF.push(groupStackFI.pop());
6829 						groupStackFI2.pop();
6830 						if (groupStackFI2.count() == 0)
6831 							break;
6832 					}
6833 				}
6834 				else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
6835 				{
6836 					groupStackMI.top().append(itemInfo.item);
6837 					while (itemInfo.ownNr == groupStackMI2.top())
6838 					{
6839 						groupStackM.push(groupStackMI.pop());
6840 						groupStackMI2.pop();
6841 						if (groupStackMI2.count() == 0)
6842 							break;
6843 					}
6844 				}
6845 
6846 				if (itemInfo.isGroupFlag)
6847 				{
6848 					QList<PageItem*> groupItems;
6849 					groupItems.append(itemInfo.item);
6850 					if (tagName == "PAGEOBJECT")
6851 					{
6852 						groupStackPI.push(groupItems);
6853 						groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
6854 					}
6855 					else if (tagName == "FRAMEOBJECT")
6856 					{
6857 						groupStackFI.push(groupItems);
6858 						groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
6859 					}
6860 					else
6861 					{
6862 						groupStackMI.push(groupItems);
6863 						groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
6864 					}
6865 				}
6866 			}
6867 		}
6868 	}
6869 
6870 	if (reader.hasError())
6871 	{
6872 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
6873 		return false;
6874 	}
6875 
6876 	QMap<int, ScribusDoc::BookMa>::Iterator it;
6877 	for (it = bookmarks.begin(); it != bookmarks.end(); ++it)
6878 	{
6879 		int elem = it.key();
6880 		PageItem* item = LinkID.value(elem, (PageItem*) nullptr);
6881 		if (!item)
6882 			continue;
6883 		ScribusDoc::BookMa bookmark = it.value();
6884 		bookmark.PageObject = item;
6885 		m_Doc->BookMarks.append( bookmark );
6886 	}
6887 
6888 	if (isNewFormat)
6889 	{
6890 		if (TableItems.count() != 0)
6891 		{
6892 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
6893 			{
6894 				PageItem* ta = TableItems.at(ttc);
6895 				if (ta->TopLinkID != -1)
6896 					ta->m_topLink = LinkID[ta->TopLinkID];
6897 				else
6898 					ta->m_topLink = nullptr;
6899 				if (ta->LeftLinkID != -1)
6900 					ta->m_leftLink = LinkID[ta->LeftLinkID];
6901 				else
6902 					ta->m_leftLink = nullptr;
6903 				if (ta->RightLinkID != -1)
6904 					ta->m_rightLink = LinkID[ta->RightLinkID];
6905 				else
6906 					ta->m_rightLink = nullptr;
6907 				if (ta->BottomLinkID != -1)
6908 					ta->m_bottomLink = LinkID[ta->BottomLinkID];
6909 				else
6910 					ta->m_bottomLink = nullptr;
6911 			}
6912 		}
6913 		if (WeldItems.count() != 0)
6914 		{
6915 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
6916 			{
6917 				PageItem* ta = WeldItems.at(ttc);
6918 				for (int i = 0 ; i < ta->weldList.count(); ++i)
6919 				{
6920 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
6921 					ta->weldList[i].weldItem = LinkID.value(wInf.weldID, 0);
6922 					if (ta->weldList[i].weldItem == nullptr)
6923 						ta->weldList.removeAt(i--);
6924 				}
6925 			}
6926 		}
6927 		if (itemNext.count() != 0)
6928 		{
6929 			QMap<int,int>::Iterator lc;
6930 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
6931 			{
6932 				if (lc.value() >= 0)
6933 				{
6934 					PageItem * Its = LinkID[lc.key()];
6935 					PageItem * Itn = LinkID[lc.value()];
6936 					if (!Its->canBeLinkedTo(Itn))
6937 					{
6938 						qDebug() << "scribus150format: corruption in linked textframes detected";
6939 						continue;
6940 					}
6941 					Its->link(Itn);
6942 				}
6943 			}
6944 		}
6945 	}
6946 	else
6947 	{
6948 		if (TableItems.count() != 0)
6949 		{
6950 			for (int ttc = 0; ttc < TableItems.count(); ++ttc)
6951 			{
6952 				PageItem* ta = TableItems.at(ttc);
6953 				if (ta->TopLinkID != -1)
6954 					ta->m_topLink = TableID[ta->TopLinkID];
6955 				else
6956 					ta->m_topLink = nullptr;
6957 				if (ta->LeftLinkID != -1)
6958 					ta->m_leftLink = TableID[ta->LeftLinkID];
6959 				else
6960 					ta->m_leftLink = nullptr;
6961 				if (ta->RightLinkID != -1)
6962 					ta->m_rightLink = TableID[ta->RightLinkID];
6963 				else
6964 					ta->m_rightLink = nullptr;
6965 				if (ta->BottomLinkID != -1)
6966 					ta->m_bottomLink = TableID[ta->BottomLinkID];
6967 				else
6968 					ta->m_bottomLink = nullptr;
6969 			}
6970 		}
6971 		if (WeldItems.count() != 0)
6972 		{
6973 			for (int ttc = 0; ttc < WeldItems.count(); ++ttc)
6974 			{
6975 				PageItem* ta = WeldItems.at(ttc);
6976 				for (int i = 0 ; i < ta->weldList.count(); ++i)
6977 				{
6978 					PageItem::WeldingInfo wInf = ta->weldList.at(i);
6979 					ta->weldList[i].weldItem = WeldID.value(wInf.weldID, 0);
6980 					if (ta->weldList[i].weldItem == nullptr)
6981 						ta->weldList.removeAt(i--);
6982 				}
6983 			}
6984 		}
6985 		// reestablish textframe links
6986 		if (itemNext.count() != 0 && !Mpage)
6987 		{
6988 			QMap<int,int>::Iterator lc;
6989 			for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
6990 			{
6991 				if (itemRemap[lc.value()] >= 0)
6992 				{
6993 					PageItem *Its(nullptr), *Itn(nullptr);
6994 					if (lc.key() < m_Doc->Items->count())
6995 						Its = m_Doc->DocItems.at(lc.key());
6996 					if (itemRemap[lc.value()] < m_Doc->DocItems.count())
6997 						Itn = m_Doc->DocItems.at(itemRemap[lc.value()]);
6998 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
6999 					{
7000 						qDebug() << "scribus150format: corruption in linked textframes detected";
7001 						continue;
7002 					}
7003 					Its->link(Itn);
7004 				}
7005 			}
7006 		}
7007 		else if (itemNextM.count() != 0 && Mpage)
7008 		{
7009 			QMap<int,int>::Iterator lc;
7010 			for (lc = itemNextM.begin(); lc != itemNextM.end(); ++lc)
7011 			{
7012 				if (itemRemapM[lc.value()] >= 0)
7013 				{
7014 					PageItem *Its(nullptr), *Itn(nullptr);
7015 					if (lc.key() < m_Doc->MasterItems.count())
7016 						Its = m_Doc->MasterItems.at(lc.key());
7017 					if (itemRemapM[lc.value()] < m_Doc->MasterItems.count())
7018 						Itn = m_Doc->MasterItems.at(itemRemapM[lc.value()]);
7019 					if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
7020 					{
7021 						qDebug() << "scribus150format: corruption in linked textframes detected";
7022 						continue;
7023 					}
7024 					Its->link(Itn);
7025 				}
7026 			}
7027 		}
7028 	}
7029 
7030 	while (groupStackP.count() > 0)
7031 	{
7032 		bool isTableIt = false;
7033 		QList<PageItem*> gpL = groupStackP.pop();
7034 		PageItem* gItem = gpL.takeFirst();
7035 		for (int id = 0; id < gpL.count(); id++)
7036 		{
7037 			PageItem* cItem = gpL.at(id);
7038 			isTableIt = cItem->isTableItem;
7039 			cItem->gXpos = cItem->xPos() - gItem->xPos();
7040 			cItem->gYpos = cItem->yPos() - gItem->yPos();
7041 			cItem->Parent = gItem;
7042 			if (gItem->rotation() != 0)
7043 			{
7044 				QTransform ma;
7045 				ma.rotate(-gItem->rotation());
7046 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
7047 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
7048 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
7049 				cItem->setRotation(cItem->rotation() - gItem->rotation());
7050 				cItem->oldRot = cItem->rotation();
7051 			}
7052 			m_Doc->DocItems.removeOne(cItem);
7053 		}
7054 		bool converted = false;
7055 		if (isTableIt)
7056 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
7057 		if (!converted)
7058 			gItem->groupItemList = gpL;
7059 	}
7060 
7061 	while (groupStackF.count() > 0)
7062 	{
7063 		bool isTableIt = false;
7064 		QList<PageItem*> gpL = groupStackF.pop();
7065 		PageItem* gItem = gpL.takeFirst();
7066 		for (int id = 0; id < gpL.count(); id++)
7067 		{
7068 			PageItem* cItem = gpL.at(id);
7069 			isTableIt = cItem->isTableItem;
7070 			cItem->gXpos = cItem->xPos() - gItem->xPos();
7071 			cItem->gYpos = cItem->yPos() - gItem->yPos();
7072 			cItem->Parent = gItem;
7073 			if (gItem->rotation() != 0)
7074 			{
7075 				QTransform ma;
7076 				ma.rotate(-gItem->rotation());
7077 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
7078 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
7079 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
7080 				cItem->setRotation(cItem->rotation() - gItem->rotation());
7081 				cItem->oldRot = cItem->rotation();
7082 			}
7083 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
7084 		}
7085 		bool converted = false;
7086 		if (isTableIt)
7087 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
7088 		if (!converted)
7089 			gItem->groupItemList = gpL;
7090 	}
7091 
7092 	while (groupStackM.count() > 0)
7093 	{
7094 		bool isTableIt = false;
7095 		QList<PageItem*> gpL = groupStackM.pop();
7096 		PageItem* gItem = gpL.takeFirst();
7097 		for (int id = 0; id < gpL.count(); id++)
7098 		{
7099 			PageItem* cItem = gpL.at(id);
7100 			isTableIt = cItem->isTableItem;
7101 			cItem->gXpos = cItem->xPos() - gItem->xPos();
7102 			cItem->gYpos = cItem->yPos() - gItem->yPos();
7103 			cItem->Parent = gItem;
7104 			if (gItem->rotation() != 0)
7105 			{
7106 				QTransform ma;
7107 				ma.rotate(-gItem->rotation());
7108 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
7109 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
7110 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
7111 				cItem->setRotation(cItem->rotation() - gItem->rotation());
7112 				cItem->oldRot = cItem->rotation();
7113 			}
7114 			m_Doc->MasterItems.removeOne(cItem);
7115 		}
7116 		bool converted = false;
7117 		if (isTableIt)
7118 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
7119 		if (!converted)
7120 			gItem->groupItemList = gpL;
7121 	}
7122 
7123 	// reestablish first/lastAuto
7124 	m_Doc->FirstAuto = m_Doc->LastAuto;
7125 	if (m_Doc->LastAuto)
7126 	{
7127 		while (m_Doc->LastAuto->nextInChain())
7128 			m_Doc->LastAuto = m_Doc->LastAuto->nextInChain();
7129 		while (m_Doc->FirstAuto->prevInChain())
7130 			m_Doc->FirstAuto = m_Doc->FirstAuto->prevInChain();
7131 	}
7132 
7133 	return true;
7134 }
7135 
getStyle(ParagraphStyle & style,ScXmlStreamReader & reader,StyleSet<ParagraphStyle> * tempStyles,ScribusDoc * doc,bool equiv)7136 void Scribus150Format::getStyle(ParagraphStyle& style, ScXmlStreamReader& reader, StyleSet<ParagraphStyle> *tempStyles, ScribusDoc* doc, bool equiv)
7137 {
7138 	bool  found(false);
7139 	const StyleSet<ParagraphStyle> &docParagraphStyles = tempStyles ? *tempStyles : doc->paragraphStyles();
7140 
7141 	style.erase();
7142 	readParagraphStyle(doc, reader, style);
7143 
7144 	// Do not duplicate default style
7145 	if (style.isDefaultStyle())
7146 		style.setDefaultStyle(false);
7147 
7148 	const ParagraphStyle* foundStyle = docParagraphStyles.getPointer(style.name());
7149 	if (foundStyle)
7150 	{
7151 		found = style.equiv(*foundStyle);
7152 		if (found)
7153 			return;
7154 		QString newName = docParagraphStyles.getUniqueCopyName(style.name());
7155 		parStyleMap[style.name()] = newName;
7156 		style.setName(newName);
7157 	}
7158 
7159 	if (equiv)
7160 	{
7161 		const ParagraphStyle* equivStyle = docParagraphStyles.findEquivalent(style);
7162 		if (equivStyle)
7163 		{
7164 			parStyleMap[style.name()] = equivStyle->name();
7165 			style.setName(equivStyle->name());
7166 			return;
7167 		}
7168 	}
7169 
7170 	if (tempStyles)
7171 		tempStyles->create(style);
7172 	else
7173 	{
7174 		StyleSet<ParagraphStyle> tmp;
7175 		tmp.create(style);
7176 		doc->redefineStyles(tmp, false);
7177 	}
7178 }
7179 
getStyle(CharStyle & style,ScXmlStreamReader & reader,StyleSet<CharStyle> * tempStyles,ScribusDoc * doc,bool equiv)7180 void Scribus150Format::getStyle(CharStyle& style, ScXmlStreamReader& reader, StyleSet<CharStyle> *tempStyles, ScribusDoc* doc, bool equiv)
7181 {
7182 	bool  found(false);
7183 	const StyleSet<CharStyle> &docCharStyles = tempStyles ? *tempStyles : doc->charStyles();
7184 
7185 	style.erase();
7186 	ScXmlStreamAttributes attrs = reader.scAttributes();
7187 	readNamedCharacterStyleAttrs(m_Doc, attrs, style);
7188 
7189 	// Do not duplicate default style
7190 	if (style.isDefaultStyle())
7191 		style.setDefaultStyle(false);
7192 
7193 	const CharStyle* foundStyle = docCharStyles.getPointer(style.name());
7194 	if (foundStyle)
7195 	{
7196 		found = style.equiv(*foundStyle);
7197 		if (found)
7198 			return;
7199 		QString newName = docCharStyles.getUniqueCopyName(style.name());
7200 		parStyleMap[style.name()] = newName;
7201 		style.setName(newName);
7202 	}
7203 
7204 	if (equiv)
7205 	{
7206 		const CharStyle* equivStyle = docCharStyles.findEquivalent(style);
7207 		if (equivStyle)
7208 		{
7209 			charStyleMap[style.name()] = equivStyle->name();
7210 			style.setName(equivStyle->name());
7211 			return;
7212 		}
7213 	}
7214 
7215 	if (tempStyles)
7216 		tempStyles->create(style);
7217 	else
7218 	{
7219 		StyleSet<CharStyle> tmp;
7220 		tmp.create(style);
7221 		doc->redefineCharStyles(tmp, false);
7222 	}
7223 }
7224 
readStyles(const QString & fileName,ScribusDoc * doc,StyleSet<ParagraphStyle> & docParagraphStyles)7225 bool Scribus150Format::readStyles(const QString& fileName, ScribusDoc* doc, StyleSet<ParagraphStyle> &docParagraphStyles)
7226 {
7227 	ParagraphStyle pstyle;
7228 	bool firstElement = true;
7229 	bool success = true;
7230 
7231 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
7232 	if (ioDevice.isNull())
7233 		return false;
7234 
7235 	parStyleMap.clear();
7236 	charStyleMap.clear();
7237 
7238 	ScXmlStreamReader reader(ioDevice.data());
7239 	ScXmlStreamAttributes attrs;
7240 	while (!reader.atEnd() && !reader.hasError())
7241 	{
7242 		QXmlStreamReader::TokenType tType = reader.readNext();
7243 		if (tType != QXmlStreamReader::StartElement)
7244 			continue;
7245 		QStringRef tagName = reader.name();
7246 		if (firstElement)
7247 		{
7248 			if (tagName != "SCRIBUSUTF8NEW")
7249 			{
7250 				success = false;
7251 				break;
7252 			}
7253 			firstElement = false;
7254 			continue;
7255 		}
7256 		if (tagName == "STYLE")
7257 		{
7258 			pstyle.erase();
7259 			getStyle(pstyle, reader, &docParagraphStyles, doc, false);
7260 		}
7261 	}
7262 	return success;
7263 }
7264 
readCharStyles(const QString & fileName,ScribusDoc * doc,StyleSet<CharStyle> & docCharStyles)7265 bool Scribus150Format::readCharStyles(const QString& fileName, ScribusDoc* doc, StyleSet<CharStyle> &docCharStyles)
7266 {
7267 	CharStyle cstyle;
7268 	bool firstElement = true;
7269 	//bool success = true;
7270 
7271 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
7272 	if (ioDevice.isNull())
7273 		return false;
7274 
7275 	parStyleMap.clear();
7276 	charStyleMap.clear();
7277 
7278 	ScXmlStreamReader reader(ioDevice.data());
7279 	ScXmlStreamAttributes attrs;
7280 	while (!reader.atEnd() && !reader.hasError())
7281 	{
7282 		QXmlStreamReader::TokenType tType = reader.readNext();
7283 		if (tType != QXmlStreamReader::StartElement)
7284 			continue;
7285 		QStringRef tagName = reader.name();
7286 		if (firstElement)
7287 		{
7288 			if (tagName != "SCRIBUSUTF8NEW")
7289 			{
7290 			//	success = false;
7291 				break;
7292 			}
7293 			firstElement = false;
7294 			continue;
7295 		}
7296 		if (tagName == "CHARSTYLE")
7297 		{
7298 			cstyle.erase();
7299 			attrs = reader.scAttributes();
7300 			readNamedCharacterStyleAttrs(doc, attrs, cstyle);
7301 			docCharStyles.create(cstyle);
7302 		}
7303 	}
7304 	return true;
7305 }
7306 
readLineStyles(const QString & fileName,QHash<QString,multiLine> * styles)7307 bool Scribus150Format::readLineStyles(const QString& fileName, QHash<QString,multiLine> *styles)
7308 {
7309 	bool firstElement = true;
7310 	bool success = true;
7311 
7312 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
7313 	if (ioDevice.isNull())
7314 		return false;
7315 
7316 	ScXmlStreamReader reader(ioDevice.data());
7317 	ScXmlStreamAttributes attrs;
7318 	while (!reader.atEnd() && !reader.hasError())
7319 	{
7320 		QXmlStreamReader::TokenType tType = reader.readNext();
7321 		if (tType != QXmlStreamReader::StartElement)
7322 			continue;
7323 		QStringRef tagName = reader.name();
7324 		if (firstElement)
7325 		{
7326 			if (tagName != "SCRIBUSUTF8NEW")
7327 			{
7328 				success = false;
7329 				break;
7330 			}
7331 			firstElement = false;
7332 			continue;
7333 		}
7334 		if (tagName == "MultiLine")
7335 		{
7336 			multiLine ml;
7337 			attrs = reader.scAttributes();
7338 			QString mlName  = attrs.valueAsString("Name");
7339 			QString mlName2 = mlName;
7340 			readMultiline(ml, reader);
7341 			int copyC = 1;
7342 			QHash<QString,multiLine>::ConstIterator mlit = styles->find(mlName2);
7343 			if (mlit != styles->constEnd() && ml != mlit.value())
7344 			{
7345 				while (styles->contains(mlName2))
7346 				{
7347 					mlName2 = tr("Copy #%1 of ").arg(copyC)+mlName;
7348 					copyC++;
7349 				}
7350 			}
7351 			styles->insert(mlName2, ml);
7352 		}
7353 	}
7354 	return success;
7355 }
7356 
readColors(const QString & fileName,ColorList & colors)7357 bool Scribus150Format::readColors(const QString& fileName, ColorList & colors)
7358 {
7359 	bool firstElement = true;
7360 	bool success = true;
7361 
7362 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
7363 	if (ioDevice.isNull())
7364 		return false;
7365 
7366 	ScXmlStreamReader reader(ioDevice.data());
7367 	ScXmlStreamAttributes attrs;
7368 	while (!reader.atEnd() && !reader.hasError())
7369 	{
7370 		QXmlStreamReader::TokenType tType = reader.readNext();
7371 		if (tType != QXmlStreamReader::StartElement)
7372 			continue;
7373 		QStringRef tagName = reader.name();
7374 		if (firstElement)
7375 		{
7376 			if (tagName != "SCRIBUSUTF8NEW")
7377 			{
7378 				success = false;
7379 				break;
7380 			}
7381 			firstElement = false;
7382 			continue;
7383 		}
7384 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
7385 		{
7386 			attrs = reader.scAttributes();
7387 			if (attrs.valueAsString("NAME") != CommonStrings::None)
7388 				readColor(colors, attrs);
7389 		}
7390 	}
7391 	return success;
7392 }
7393 
readPageCount(const QString & fileName,int * num1,int * num2,QStringList & masterPageNames)7394 bool Scribus150Format::readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames)
7395 {
7396 	QString pageName;
7397 	int counter = 0;
7398 	int counter2 = 0;
7399 	bool firstElement = true;
7400 	bool success = true;
7401 
7402 	markeredItemsMap.clear();
7403 	markeredMarksMap.clear();
7404 	nsetRangeItemNamesMap.clear();
7405 	notesFramesData.clear();
7406 	notesMasterMarks.clear();
7407 	notesNSets.clear();
7408 
7409 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
7410 	if (ioDevice.isNull())
7411 		return false;
7412 
7413 	ScXmlStreamReader reader(ioDevice.data());
7414 	ScXmlStreamAttributes attrs;
7415 	while (!reader.atEnd() && !reader.hasError())
7416 	{
7417 		QXmlStreamReader::TokenType tType = reader.readNext();
7418 		if (tType != QXmlStreamReader::StartElement)
7419 			continue;
7420 		QStringRef tagName = reader.name();
7421 		if (firstElement)
7422 		{
7423 			if (tagName != "SCRIBUSUTF8NEW")
7424 			{
7425 				success = false;
7426 				break;
7427 			}
7428 			firstElement = false;
7429 			continue;
7430 		}
7431 		if (tagName == "PAGE")
7432 			counter++;
7433 		if (tagName == "MASTERPAGE")
7434 		{
7435 			pageName = reader.scAttributes().valueAsString("NAM");
7436 			if (!pageName.isEmpty())
7437 			{
7438 				counter2++;
7439 				masterPageNames.append(pageName);
7440 			}
7441 		}
7442 	}
7443 	*num1 = counter;
7444 	*num2 = counter2;
7445 	return success;
7446 }
7447 
updateNames2Ptr()7448 void Scribus150Format::updateNames2Ptr() //after document load - items pointers should be updated
7449 {
7450 	if (!markeredItemsMap.isEmpty())
7451 	{
7452 		QMap<Mark*, int>::Iterator markIt;
7453 		QMap<Mark*, int>::Iterator end = markeredItemsMap.end();
7454 		for (markIt = markeredItemsMap.begin(); markIt != end; ++markIt)
7455 		{
7456 			Mark* mrk = markIt.key();
7457 			int ItemID = markIt.value();
7458 			if (LinkID.contains(ItemID))
7459 			{
7460 				mrk->setItemPtr(LinkID[ItemID]);
7461 				mrk->setString(m_Doc->getSectionPageNumberForPageIndex(mrk->getItemPtr()->OwnPage));
7462 			}
7463 			else
7464 			{
7465 				qWarning() << "Scribus150Format::updateNames2Ptr() : wrong mark [" << mrk->label << "] data - item [" << ItemID << "] not exists - DELETING MARK";
7466 				QString markLabel(mrk->label);
7467 				if (!m_Doc->eraseMark(mrk, true))
7468 					qWarning() << "Erase mark [" << markLabel << "] failed - was it defined?";
7469 			}
7470 		}
7471 		markeredItemsMap.clear();
7472 	}
7473 	if (!markeredMarksMap.isEmpty())
7474 	{
7475 		auto end = markeredMarksMap.end();
7476 		for (auto markIt = markeredMarksMap.begin(); markIt != end; ++markIt)
7477 		{
7478 			Mark* mark = markIt.key();
7479 			QMap<QString, MarkType> mark2map = markIt.value();
7480 			QString label2 = mark2map.begin().key();
7481 			MarkType type2 = mark2map.begin().value();
7482 			Mark* mark2 = m_Doc->getMark(label2, type2);
7483 			if (mark2 != nullptr)
7484 			{
7485 				mark->setMark(mark2);
7486 			}
7487 			else
7488 			{
7489 				qWarning() << "Scribus150Format::updateNames2Ptr() : wrong mark [" << mark->label << "] data - pointed mark name [" << label2 << "] not exists - DELETING MARK";
7490 				QString markLabel(mark->label);
7491 				if (!m_Doc->eraseMark(mark, true))
7492 					qWarning() << "Erase mark [" << markLabel << "] failed - was it defined?";
7493 
7494 			}
7495 		}
7496 		markeredMarksMap.clear();
7497 	}
7498 
7499 	//update endnotes frames pointers
7500 	if (!notesFramesData.isEmpty())
7501 	{
7502 		for (int i = 0; i < notesFramesData.count(); ++i)
7503 		{
7504 			NoteFrameData eF = notesFramesData.at(i);
7505 			NotesStyle* ns = m_Doc->getNotesStyle(eF.NSname);
7506 			if (ns == nullptr)
7507 				continue;
7508 
7509 			PageItem* item = LinkID.value(eF.myID);
7510 			if (item == nullptr || !item->isNoteFrame())
7511 			{
7512 				qDebug() << "Scribus150Format::updateNames2Ptr() : update end frames pointers - item is not note frame or name is wrong";
7513 				continue;
7514 			}
7515 
7516 			PageItem_NoteFrame* noteFrame = item->asNoteFrame();
7517 			noteFrame->setNoteStyle(ns);
7518 			if (ns->isEndNotes())
7519 			{
7520 				if (eF.NSrange == NSRdocument)
7521 					m_Doc->setEndNoteFrame(noteFrame, (void*) nullptr);
7522 				else if (eF.NSrange == NSRstory)
7523 					m_Doc->setEndNoteFrame(noteFrame, (void*) LinkID.value(eF.itemID));
7524 			}
7525 			else
7526 			{
7527 				PageItem* master = LinkID.value(eF.itemID);
7528 				if (master == nullptr)
7529 					continue;
7530 				noteFrame->setMaster(master);
7531 				master->asTextFrame()->setNoteFrame(noteFrame);
7532 				//FIX welding with note frame
7533 				PageItem::WeldingInfo wInf;
7534 				for (int i = 0 ; i < master->weldList.count(); i++)
7535 				{
7536 					wInf = master->weldList.at(i);
7537 					if (wInf.weldID == eF.myID)
7538 					{
7539 						master->weldList[i].weldItem = item;
7540 						break;
7541 					}
7542 				}
7543 			}
7544 		}
7545 	}
7546 	//update pointers to notes in master notes marks
7547 	if (!notesMasterMarks.isEmpty())
7548 	{
7549 		assert(!m_Doc->marksList().isEmpty() && !m_Doc->notesList().isEmpty());
7550 		QMap<QString, TextNote*>::Iterator it;
7551 		QMap<QString, TextNote*>::Iterator end = notesMasterMarks.end();
7552 		for (it = notesMasterMarks.begin(); it != end; ++it)
7553 		{
7554 			TextNote* note = it.value();
7555 			assert(note != nullptr);
7556 			const QString& mrkLabel = it.key();
7557 			Mark* mrk = m_Doc->getMark(mrkLabel, MARKNoteMasterType);
7558 			if (mrk == nullptr)
7559 			{
7560 				qWarning() << "Scribus150Format::updateNames2Ptr() : cannot find master mark ("<<mrkLabel <<") for note - note will be deleted";
7561 				m_Doc->deleteNote(note);
7562 				continue;
7563 			}
7564 			note->setMasterMark(mrk);
7565 			mrk->setNotePtr(note);
7566 		}
7567 		notesMasterMarks.clear();
7568 	}
7569 	if (!notesNSets.isEmpty())
7570 	{
7571 		assert(!m_Doc->notesList().isEmpty());
7572 		auto end = notesNSets.end();
7573 		for (auto it = notesNSets.begin(); it != end; ++it)
7574 		{
7575 			TextNote* note = it.key();
7576 			assert(note != nullptr);
7577 			QString nsLabel = it.value();
7578 			NotesStyle* ns = m_Doc->getNotesStyle(nsLabel);
7579 			if (ns != nullptr)
7580 				note->setNotesStyle(ns);
7581 			if (note->notesStyle() == nullptr)
7582 			{
7583 				qWarning() << "Scribus150Format::updateNames2Ptr()  : cannot find notes style ("<<nsLabel <<") for note - note will be deleted";
7584 				m_Doc->deleteNote(note);
7585 				continue;
7586 			}
7587 		}
7588 		notesNSets.clear();
7589 	}
7590 }
7591