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 "scribus134format.h"
8 #include "scribus134formatimpl.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 <QIODevice>
19 #include <QList>
20 #include <QScopedPointer>
21 
22 #include "../../formatidlist.h"
23 #include "commonstrings.h"
24 #include "langmgr.h"
25 #include "ui/missing.h"
26 #include "hyphenator.h"
27 #include "pageitem_latexframe.h"
28 #include "pageitem_line.h"
29 #include "pageitem_table.h"
30 #include "prefsmanager.h"
31 #include "qtiocompressor.h"
32 #include "scclocale.h"
33 #include "scconfig.h"
34 #include "sccolorengine.h"
35 #include "scpattern.h"
36 #include "scribuscore.h"
37 #include "scribusdoc.h"
38 #include "sctextstream.h"
39 #include "scxmlstreamreader.h"
40 #include "undomanager.h"
41 #include "units.h"
42 #include "util.h"
43 #include "util_color.h"
44 #include "util_layer.h"
45 #include "util_math.h"
46 #include "util_printer.h"
47 
48 // See scplugin.h and pluginmanager.{cpp,h} for detail on what these methods
49 // do. That documentatation is not duplicated here.
50 // Please don't implement the functionality of your plugin here; do that
51 // in scribus134formatimpl.h and scribus134formatimpl.cpp .
52 
Scribus134Format()53 Scribus134Format::Scribus134Format()
54 {
55 	itemCount = itemCountM = 0;
56 	legacyStyleCount = 0;
57 
58 	// Set action info in languageChange, so we only have to do
59 	// it in one place. This includes registering file formats.
60 	registerFormats();
61 	languageChange();
62 }
63 
~Scribus134Format()64 Scribus134Format::~Scribus134Format()
65 {
66 	unregisterAll();
67 }
68 
languageChange()69 void Scribus134Format::languageChange()
70 {
71 	FileFormat* fmt = getFormatByID(FORMATID_SLA134IMPORT);
72 	fmt->trName = tr("Scribus 1.3.4+ Document");
73 	fmt->filter = fmt->trName + " (*.sla *.SLA *.sla.gz *.SLA.GZ *.scd *.SCD *.scd.gz *.SCD.GZ)";
74 }
75 
fullTrName() const76 QString Scribus134Format::fullTrName() const
77 {
78 	return QObject::tr("Scribus 1.3.4+ Support");
79 }
80 
getAboutData() const81 const ScActionPlugin::AboutData* Scribus134Format::getAboutData() const
82 {
83 	AboutData* about = new AboutData;
84 	Q_CHECK_PTR(about);
85 	about->authors = QString::fromUtf8(
86 			"Franz Schmid <franz@scribus.info>, "
87 			"The Scribus Team");
88 	about->shortDescription = tr("Scribus 1.3.4+ File Format Support");
89 	about->description = tr("Allows Scribus to read Scribus 1.3.4 and higher formatted files.");
90 	// about->version
91 	// about->releaseDate
92 	// about->copyright
93 	about->license = "GPL";
94 	return about;
95 }
96 
deleteAboutData(const AboutData * about) const97 void Scribus134Format::deleteAboutData(const AboutData* about) const
98 {
99 	Q_ASSERT(about);
100 	delete about;
101 }
102 
registerFormats()103 void Scribus134Format::registerFormats()
104 {
105 	FileFormat fmt(this);
106 	fmt.trName = tr("Scribus 1.3.4+ Document");
107 	fmt.formatId = FORMATID_SLA134IMPORT;
108 	fmt.load = true;
109 	fmt.save = false;
110 	fmt.colorReading = true;
111 	fmt.filter = fmt.trName + " (*.sla *.SLA *.sla.gz *.SLA.GZ *.scd *.SCD *.scd.gz *.SCD.GZ)";
112 	fmt.mimeTypes = QStringList();
113 	fmt.mimeTypes.append("application/x-scribus");
114 	fmt.fileExtensions = QStringList() << "sla" << "sla.gz" << "scd" << "scd.gz";
115 	fmt.priority = 64;
116 	fmt.nativeScribus = true;
117 	registerFormat(fmt);
118 }
119 
fileSupported(QIODevice *,const QString & fileName) const120 bool Scribus134Format::fileSupported(QIODevice* /* file */, const QString & fileName) const
121 {
122 	QByteArray docBytes("");
123 	if (fileName.right(2) == "gz")
124 	{
125 		QFile file(fileName);
126 		QtIOCompressor compressor(&file);
127 		compressor.setStreamFormat(QtIOCompressor::GzipFormat);
128 		compressor.open(QIODevice::ReadOnly);
129 		docBytes = compressor.read(1024);
130 		compressor.close();
131 		if (docBytes.isEmpty())
132 			return false;
133 	}
134 	else
135 	{
136 		// Not gzip encoded, just load it
137 		loadRawBytes(fileName, docBytes, 1024);
138 	}
139 
140 	QRegExp regExp134("Version=\"1.3.[4-9]");
141 	QRegExp regExp140("Version=\"1.4.[0-9]");
142 	int startElemPos = docBytes.left(512).indexOf("<SCRIBUSUTF8NEW ");
143 	if (startElemPos >= 0)
144 	{
145 		bool is134 = (regExp134.indexIn(docBytes.mid(startElemPos, 64)) >= 0);
146 		bool is140 = (regExp140.indexIn(docBytes.mid(startElemPos, 64)) >= 0);
147 		return (is134 || is140);
148 	}
149 	return false;
150 }
151 
slaReader(const QString & fileName)152 QIODevice* Scribus134Format::slaReader(const QString & fileName)
153 {
154 	if (!fileSupported(nullptr, fileName))
155 		return nullptr;
156 
157 	QIODevice* ioDevice = nullptr;
158 	if (fileName.right(2) == "gz")
159 	{
160 		aFile.setFileName(fileName);
161 		QtIOCompressor *compressor = new QtIOCompressor(&aFile);
162 		compressor->setStreamFormat(QtIOCompressor::GzipFormat);
163 		if (!compressor->open(QIODevice::ReadOnly))
164 		{
165 			delete compressor;
166 			return nullptr;
167 		}
168 		ioDevice = compressor;
169 	}
170 	else
171 	{
172 		ioDevice = new QFile(fileName);
173 		if (!ioDevice->open(QIODevice::ReadOnly))
174 		{
175 			delete ioDevice;
176 			return nullptr;
177 		}
178 	}
179 	return ioDevice;
180 }
181 
getReplacedFontData(bool & getNewReplacement,QMap<QString,QString> & getReplacedFonts,QList<ScFace> & getDummyScFaces)182 void Scribus134Format::getReplacedFontData(bool & getNewReplacement, QMap<QString,QString> &getReplacedFonts, QList<ScFace> &getDummyScFaces)
183 {
184 	getNewReplacement=false;
185 	getReplacedFonts.clear();
186 }
187 
loadFile(const QString & fileName,const FileFormat &,int,int)188 bool Scribus134Format::loadFile(const QString & fileName, const FileFormat & /* fmt */, int /* flags */, int /* index */)
189 {
190 	if (m_Doc==nullptr || m_AvailableFonts==nullptr)
191 	{
192 		Q_ASSERT(m_Doc==nullptr || m_AvailableFonts==nullptr);
193 		return false;
194 	}
195 
196 	struct ScribusDoc::BookMa bok;
197 	QMap<int, ScribusDoc::BookMa> bookmarks;
198 
199 	QMap<int, PageItem*> TableID;
200 	QMap<int, PageItem*> TableIDM;
201 	QMap<int, PageItem*> TableIDF;
202 	QList<PageItem*> TableItems;
203 	QList<PageItem*> TableItemsM;
204 	QList<PageItem*> TableItemsF;
205 	QStack< QList<PageItem*> > groupStackFI;
206 	QStack< QList<PageItem*> > groupStackMI;
207 	QStack< QList<PageItem*> > groupStackPI;
208 	QStack< QList<PageItem*> > groupStackF;
209 	QStack< QList<PageItem*> > groupStackM;
210 	QStack< QList<PageItem*> > groupStackP;
211 	QStack<int> groupStackFI2;
212 	QStack<int> groupStackMI2;
213 	QStack<int> groupStackPI2;
214 
215 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
216 	if (ioDevice.isNull())
217 	{
218 		setFileReadError();
219 		return false;
220 	}
221 	QString fileDir = QFileInfo(fileName).absolutePath();
222 	int firstPage = 0;
223 	int layerToSetActive = 0;
224 
225 	if (m_mwProgressBar!=nullptr)
226 	{
227 		m_mwProgressBar->setMaximum(ioDevice->size());
228 		m_mwProgressBar->setValue(0);
229 	}
230 	// Stop autosave timer,it will be restarted only if doc has autosave feature is enabled
231 	if (m_Doc->autoSaveTimer->isActive())
232 		m_Doc->autoSaveTimer->stop();
233 
234 	parStyleMap.clear();
235 	charStyleMap.clear();
236 	groupRemap.clear();
237 	itemRemap.clear();
238 	itemNext.clear();
239 	itemCount = 0;
240 	itemRemapM.clear();
241 	itemNextM.clear();
242 	itemCountM = 0;
243 
244 	FrameItems.clear();
245 	TableItems.clear();
246 	TableID.clear();
247 	TableItemsM.clear();
248 	TableIDM.clear();
249 	TableItemsF.clear();
250 	TableIDF.clear();
251 
252 	m_Doc->GroupCounter = 1;
253 	m_Doc->LastAuto = nullptr;
254 	m_Doc->PageColors.clear();
255 	m_Doc->Layers.clear();
256 
257 	bool firstElement = true;
258 	bool success = true;
259 	bool hasPageSets = false;
260 	int  progress = 0;
261 
262 	ScXmlStreamReader reader(ioDevice.data());
263 	ScXmlStreamAttributes attrs;
264 	while (!reader.atEnd() && !reader.hasError())
265 	{
266 		QXmlStreamReader::TokenType tType = reader.readNext();
267 		if (tType != QXmlStreamReader::StartElement)
268 			continue;
269 		QStringRef tagName = reader.name();
270 		attrs = reader.scAttributes();
271 
272 		if (m_mwProgressBar != nullptr)
273 		{
274 			int newProgress = qRound(ioDevice->pos() / (double) ioDevice->size() * 100);
275 			if (newProgress != progress)
276 			{
277 				m_mwProgressBar->setValue(reader.characterOffset());
278 				progress = newProgress;
279 			}
280 		}
281 
282 		if (firstElement)
283 		{
284 			if (tagName != "SCRIBUSUTF8NEW")
285 			{
286 				success = false;
287 				break;
288 			}
289 			firstElement = false;
290 		}
291 		if (tagName == "DOCUMENT")
292 		{
293 			readDocAttributes(m_Doc, attrs);
294 			layerToSetActive = attrs.valueAsInt("ALAYER", 0);
295 			if (m_Doc->pagePositioning() == 0)
296 				firstPage = 0;
297 			else
298 			{
299 				if (attrs.valueAsInt("FIRSTLEFT", 0) == 1)
300 					firstPage = 0;
301 				else
302 					firstPage = 1;
303 			}
304 			if (attrs.hasAttribute("currentProfile"))
305 			{
306 				m_Doc->clearCheckerProfiles();
307 				m_Doc->setCurCheckProfile(attrs.valueAsString("currentProfile"));
308 			}
309 		}
310 		if (tagName == "CheckProfile")
311 		{
312 			success = readCheckProfile(m_Doc, attrs);
313 			if (!success) break;
314 		}
315 		if (tagName == "PageSets")
316 		{
317 			success = readPageSets(m_Doc, reader);
318 			if (!success) break;
319 			hasPageSets = true;
320 		}
321 		// 10/25/2004 pv - None is "reserved" color. cannot be defined in any file...
322 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
323 		{
324 			success = readColor(m_Doc->PageColors, attrs);
325 			if (!success) break;
326 		}
327 		if (tagName == "STYLE")
328 		{
329 			ParagraphStyle pstyle;
330 			readParagraphStyle(m_Doc, reader, pstyle);
331 			StyleSet<ParagraphStyle>tmp;
332 			tmp.create(pstyle);
333 			m_Doc->redefineStyles(tmp, false);
334 		}
335 		if (tagName == "CHARSTYLE")
336 		{
337 			CharStyle cstyle;
338 			ScXmlStreamAttributes attrs = reader.scAttributes();
339 			readNamedCharacterStyleAttrs(m_Doc, attrs, cstyle);
340 			StyleSet<CharStyle> temp;
341 			temp.create(cstyle);
342 			m_Doc->redefineCharStyles(temp, false);
343 		}
344 		if (tagName == "JAVA")
345 		{
346 			QString name = attrs.valueAsString("NAME");
347 			if (!name.isEmpty())
348 				m_Doc->JavaScripts[name] = attrs.valueAsString("SCRIPT");
349 		}
350 		if (tagName == "LAYERS")
351 		{
352 			ScLayer newLayer;
353 			readLayers(newLayer, attrs);
354 			m_Doc->Layers.append(newLayer);
355 		}
356 		if (tagName == "Arrows")
357 		{
358 			success = readArrows(m_Doc, attrs);
359 			if (!success) break;
360 		}
361 		if (tagName == "MultiLine")
362 		{
363 			multiLine ml;
364 			QString mlName = attrs.valueAsString("Name");
365 			success = readMultiline(ml, reader);
366 			if (!success) break;
367 			if (!mlName.isEmpty())
368 			{
369 				m_Doc->docLineStyles.insert(mlName, ml);
370 			}
371 		}
372 		if (tagName == "Bookmark")
373 		{
374 			int bmElem = 0;
375 			struct ScribusDoc::BookMa bookmark;
376 			success = readBookMark(bookmark, bmElem, attrs);
377 			if (!success) break;
378 			bookmarks.insert(bmElem, bookmark);
379 		}
380 		if (tagName == "PDF")
381 		{
382 			success = readPDFOptions(m_Doc, reader);
383 			if (!success) break;
384 		}
385 		if (tagName == "Printer")
386 		{
387 			success = readPrinterOptions(m_Doc, reader);
388 			if (!success) break;
389 		}
390 		if (tagName == "DocItemAttributes")
391 		{
392 			success = readDocItemAttributes(m_Doc, reader);
393 			if (!success) break;
394 		}
395 		if (tagName == "TablesOfContents")
396 		{
397 			success = readTableOfContents(m_Doc, reader);
398 			if (!success) break;
399 		}
400 		if (tagName == "Sections")
401 		{
402 			success = readSections(m_Doc, reader);
403 			if (!success) break;
404 		}
405 		if (tagName == "HYPHEN")
406 		{
407 			success = readHyphen(m_Doc, reader);
408 			if (!success) break;
409 		}
410 		if (tagName == "PAGE" || tagName == "MASTERPAGE")
411 		{
412 			success = readPage(m_Doc, reader);
413 			if (!success) break;
414 		}
415 		if (tagName == "PAGEOBJECT" || tagName == "MASTEROBJECT" || tagName == "FRAMEOBJECT")
416 		{
417 			ItemInfo itemInfo;
418 			success = readObject(m_Doc, reader, itemInfo, fileDir, false);
419 			if (!success) break;
420 
421 			// first of linked chain?
422 			if (tagName == "PAGEOBJECT")
423 			{
424 				if (itemInfo.nextItem != -1)
425 					itemNext[itemInfo.ownNr] = itemInfo.nextItem;
426 			}
427 			else if (tagName == "MASTEROBJECT")
428 			{
429 				if (itemInfo.nextItem != -1)
430 					itemNextM[itemInfo.ownNr] = itemInfo.nextItem;
431 			}
432 			/* not sure if we want that...
433 			else if (tagName == "FRAMEOBJECT")
434 			{
435 				if (itemInfo.nextItem != -1)
436 					itemNextF[itemInfo.item->ItemNr] = itemInfo.nextItem;
437 			}*/
438 
439 			if (itemInfo.item->isTableItem)
440 			{
441 				if (tagName == "PAGEOBJECT")
442 				{
443 					TableItems.append(itemInfo.item);
444 					TableID.insert(itemInfo.ownLink, itemInfo.item);
445 				}
446 				else if (tagName == "FRAMEOBJECT")
447 				{
448 					TableItemsF.append(itemInfo.item);
449 					TableIDF.insert(itemInfo.ownLink, itemInfo.item);
450 				}
451 				else
452 				{
453 					TableItemsM.append(itemInfo.item);
454 					TableIDM.insert(itemInfo.ownLink, itemInfo.item);
455 				}
456 			}
457 
458 			if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
459 			{
460 				groupStackPI.top().append(itemInfo.item);
461 				while (itemInfo.ownNr == groupStackPI2.top())
462 				{
463 					groupStackP.push(groupStackPI.pop());
464 					groupStackPI2.pop();
465 					if (groupStackPI2.count() == 0)
466 						break;
467 				}
468 			}
469 			else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
470 			{
471 				groupStackFI.top().append(itemInfo.item);
472 				while (itemInfo.ownNr == groupStackFI2.top())
473 				{
474 					groupStackF.push(groupStackFI.pop());
475 					groupStackFI2.pop();
476 					if (groupStackFI2.count() == 0)
477 						break;
478 				}
479 			}
480 			else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
481 			{
482 				groupStackMI.top().append(itemInfo.item);
483 				while (itemInfo.ownNr == groupStackMI2.top())
484 				{
485 					groupStackM.push(groupStackMI.pop());
486 					groupStackMI2.pop();
487 					if (groupStackMI2.count() == 0)
488 						break;
489 				}
490 			}
491 
492 			if (itemInfo.isGroupFlag)
493 			{
494 				QList<PageItem*> groupItems;
495 				groupItems.append(itemInfo.item);
496 				if (tagName == "PAGEOBJECT")
497 				{
498 					groupStackPI.push(groupItems);
499 					groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
500 				}
501 				else if (tagName == "FRAMEOBJECT")
502 				{
503 					groupStackFI.push(groupItems);
504 					groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
505 				}
506 				else
507 				{
508 					groupStackMI.push(groupItems);
509 					groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
510 				}
511 			}
512 		}
513 		if (tagName == "Pattern")
514 		{
515 			success = readPattern(m_Doc, reader, fileDir);
516 			if (!success) break;
517 		}
518 	}
519 
520 	if (reader.hasError())
521 	{
522 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
523 		return false;
524 	}
525 
526 	QMap<int, ScribusDoc::BookMa>::Iterator it;
527 	for (it = bookmarks.begin(); it != bookmarks.end(); ++it)
528 	{
529 		int elem = it.key();
530 		if (elem < m_Doc->Items->count())
531 		{
532 			ScribusDoc::BookMa bookmark = it.value();
533 			bookmark.PageObject = m_Doc->Items->at(elem);
534 			m_Doc->BookMarks.append( bookmark );
535 		}
536 	}
537 	std::stable_sort(m_Doc->BookMarks.begin(), m_Doc->BookMarks.end());
538 
539 	if (TableItemsF.count() != 0)
540 	{
541 		for (int ttc = 0; ttc < TableItemsF.count(); ++ttc)
542 		{
543 			PageItem* ta = TableItemsF.at(ttc);
544 			if (ta->TopLinkID != -1)
545 				ta->m_topLink = TableIDF[ta->TopLinkID];
546 			else
547 				ta->m_topLink = nullptr;
548 			if (ta->LeftLinkID != -1)
549 				ta->m_leftLink = TableIDF[ta->LeftLinkID];
550 			else
551 				ta->m_leftLink = nullptr;
552 			if (ta->RightLinkID != -1)
553 				ta->m_rightLink = TableIDF[ta->RightLinkID];
554 			else
555 				ta->m_rightLink = nullptr;
556 			if (ta->BottomLinkID != -1)
557 				ta->m_bottomLink = TableIDF[ta->BottomLinkID];
558 			else
559 				ta->m_bottomLink = nullptr;
560 		}
561 	}
562 	if (TableItemsM.count() != 0)
563 	{
564 		for (int ttc = 0; ttc < TableItemsM.count(); ++ttc)
565 		{
566 			PageItem* ta = TableItemsM.at(ttc);
567 			if (ta->TopLinkID != -1)
568 				ta->m_topLink = TableIDM[ta->TopLinkID];
569 			else
570 				ta->m_topLink = nullptr;
571 			if (ta->LeftLinkID != -1)
572 				ta->m_leftLink = TableIDM[ta->LeftLinkID];
573 			else
574 				ta->m_leftLink = nullptr;
575 			if (ta->RightLinkID != -1)
576 				ta->m_rightLink = TableIDM[ta->RightLinkID];
577 			else
578 				ta->m_rightLink = nullptr;
579 			if (ta->BottomLinkID != -1)
580 				ta->m_bottomLink = TableIDM[ta->BottomLinkID];
581 			else
582 				ta->m_bottomLink = nullptr;
583 		}
584 	}
585 	if (TableItems.count() != 0)
586 	{
587 		for (int ttc = 0; ttc < TableItems.count(); ++ttc)
588 		{
589 			PageItem* ta = TableItems.at(ttc);
590 			if (ta->TopLinkID != -1)
591 				ta->m_topLink = TableID[ta->TopLinkID];
592 			else
593 				ta->m_topLink = nullptr;
594 			if (ta->LeftLinkID != -1)
595 				ta->m_leftLink = TableID[ta->LeftLinkID];
596 			else
597 				ta->m_leftLink = nullptr;
598 			if (ta->RightLinkID != -1)
599 				ta->m_rightLink = TableID[ta->RightLinkID];
600 			else
601 				ta->m_rightLink = nullptr;
602 			if (ta->BottomLinkID != -1)
603 				ta->m_bottomLink = TableID[ta->BottomLinkID];
604 			else
605 				ta->m_bottomLink = nullptr;
606 		}
607 	}
608 	//CB Add this in to set this in the file in memory. Its saved, why not load it.
609 	//Will of course be replaced by per page settings although we still probably need a document default
610 	if (!hasPageSets)
611 	{
612 		m_Doc->setPageSetFirstPage(m_Doc->pagePositioning(), firstPage);
613 	}
614 
615 	m_Doc->setMasterPageMode(false);
616 	m_Doc->reformPages();
617 	m_Doc->refreshGuides();
618 
619 	// #12282 : some docs have language dependent style names specified in style properties
620 	// #14129 : some others reference deleted character styles
621 	m_Doc->fixCharacterStyles();
622 	m_Doc->fixParagraphStyles();
623 
624 	// #9969 : Some old long doc may have page owner somewhat broken
625 	m_Doc->fixItemPageOwner();
626 
627 	handleOldLayerBehavior(m_Doc);
628 	if (m_Doc->Layers.count() == 0)
629 	{
630 		ScLayer* nl = m_Doc->Layers.newLayer( QObject::tr("Background") );
631 		nl->flowControl  = false;
632 		layerToSetActive = nl->ID;
633 	}
634 	m_Doc->setActiveLayer(layerToSetActive);
635 	if (!EffVal.isEmpty())
636 	{
637 		for (int pdoE = 0; pdoE < EffVal.count(); ++pdoE)
638 		{
639 			if (pdoE < m_Doc->Pages->count())
640 				m_Doc->Pages->at(pdoE)->PresentVals = EffVal[pdoE];
641 		}
642 	}
643 
644 	// reestablish textframe links
645 	if (itemNext.count() != 0)
646 	{
647 		QMap<int,int>::Iterator lc;
648 		for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
649 		{
650 			if (lc.value() >= 0)
651 			{
652 				PageItem *Its(nullptr), *Itn(nullptr);
653 				if (lc.key() < m_Doc->DocItems.count())
654 					Its = m_Doc->DocItems.at(lc.key());
655 				if (lc.value() < m_Doc->DocItems.count())
656 					Itn = m_Doc->DocItems.at(lc.value());
657 				if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
658 				{
659 					qDebug() << "scribus134format: corruption in linked textframes detected";
660 					continue;
661 				}
662 				Its->link(Itn);
663 			}
664 		}
665 	}
666 
667 	if (itemNextM.count() != 0)
668 	{
669 		QMap<int,int>::Iterator lc;
670 		for (lc = itemNextM.begin(); lc != itemNextM.end(); ++lc)
671 		{
672 			if (lc.value() >= 0)
673 			{
674 				PageItem *Its(nullptr), *Itn(nullptr);
675 				if (lc.key() < m_Doc->MasterItems.count())
676 					Its = m_Doc->MasterItems.at(lc.key());
677 				if (lc.value() < m_Doc->MasterItems.count())
678 					Itn = m_Doc->MasterItems.at(lc.value());
679 				if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
680 				{
681 					qDebug() << "scribus134format: corruption in linked textframes detected";
682 					continue;
683 				}
684 				Its->link(Itn);
685 			}
686 		}
687 	}
688 
689 	while (groupStackP.count() > 0)
690 	{
691 		bool isTableIt = false;
692 		QList<PageItem*> gpL = groupStackP.pop();
693 		PageItem* gItem = gpL.takeFirst();
694 		for (int id = 0; id < gpL.count(); id++)
695 		{
696 			PageItem* cItem = gpL.at(id);
697 			isTableIt = cItem->isTableItem;
698 			cItem->gXpos = cItem->xPos() - gItem->xPos();
699 			cItem->gYpos = cItem->yPos() - gItem->yPos();
700 			cItem->Parent = gItem;
701 			if (gItem->rotation() != 0)
702 			{
703 				QTransform ma;
704 				ma.rotate(-gItem->rotation());
705 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
706 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
707 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
708 				cItem->setRotation(cItem->rotation() - gItem->rotation());
709 				cItem->oldRot = cItem->rotation();
710 			}
711 			m_Doc->DocItems.removeOne(cItem);
712 		}
713 		bool converted = false;
714 		if (isTableIt)
715 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
716 		if (!converted)
717 			gItem->groupItemList = gpL;
718 	}
719 
720 	while (groupStackF.count() > 0)
721 	{
722 		bool isTableIt = false;
723 		QList<PageItem*> gpL = groupStackF.pop();
724 		PageItem* gItem = gpL.takeFirst();
725 		for (int id = 0; id < gpL.count(); id++)
726 		{
727 			PageItem* cItem = gpL.at(id);
728 			isTableIt = cItem->isTableItem;
729 			cItem->gXpos = cItem->xPos() - gItem->xPos();
730 			cItem->gYpos = cItem->yPos() - gItem->yPos();
731 			cItem->Parent = gItem;
732 			if (gItem->rotation() != 0)
733 			{
734 				QTransform ma;
735 				ma.rotate(-gItem->rotation());
736 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
737 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
738 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
739 				cItem->setRotation(cItem->rotation() - gItem->rotation());
740 				cItem->oldRot = cItem->rotation();
741 			}
742 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
743 		}
744 		bool converted = false;
745 		if (isTableIt)
746 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
747 		if (!converted)
748 			gItem->groupItemList = gpL;
749 	}
750 
751 	while (groupStackM.count() > 0)
752 	{
753 		bool isTableIt = false;
754 		QList<PageItem*> gpL = groupStackM.pop();
755 		PageItem* gItem = gpL.takeFirst();
756 		for (int id = 0; id < gpL.count(); id++)
757 		{
758 			PageItem* cItem = gpL.at(id);
759 			isTableIt = cItem->isTableItem;
760 			cItem->gXpos = cItem->xPos() - gItem->xPos();
761 			cItem->gYpos = cItem->yPos() - gItem->yPos();
762 			cItem->Parent = gItem;
763 			if (gItem->rotation() != 0)
764 			{
765 				QTransform ma;
766 				ma.rotate(-gItem->rotation());
767 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
768 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
769 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
770 				cItem->setRotation(cItem->rotation() - gItem->rotation());
771 				cItem->oldRot = cItem->rotation();
772 			}
773 			m_Doc->MasterItems.removeOne(cItem);
774 		}
775 		bool converted = false;
776 		if (isTableIt)
777 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
778 		if (!converted)
779 			gItem->groupItemList = gpL;
780 	}
781 
782 	// reestablish first/lastAuto
783 	m_Doc->FirstAuto = m_Doc->LastAuto;
784 	if (m_Doc->LastAuto)
785 	{
786 		while (m_Doc->LastAuto->nextInChain())
787 			m_Doc->LastAuto = m_Doc->LastAuto->nextInChain();
788 		while (m_Doc->FirstAuto->prevInChain())
789 			m_Doc->FirstAuto = m_Doc->FirstAuto->prevInChain();
790 	}
791 
792 	// start auto save timer if needed
793 	if (m_Doc->autoSave()  && ScCore->usingGUI())
794 		m_Doc->restartAutoSaveTimer();
795 //		m_Doc->autoSaveTimer->start(m_Doc->autoSaveTime());
796 
797 	if (m_mwProgressBar!=nullptr)
798 		m_mwProgressBar->setValue(reader.characterOffset());
799 	return true;
800 //	return false;
801 }
802 
803 // Low level plugin API
scribus134format_getPluginAPIVersion()804 int scribus134format_getPluginAPIVersion()
805 {
806 	return PLUGIN_API_VERSION;
807 }
808 
scribus134format_getPlugin()809 ScPlugin* scribus134format_getPlugin()
810 {
811 	Scribus134Format* plug = new Scribus134Format();
812 	Q_CHECK_PTR(plug);
813 	return plug;
814 }
815 
scribus134format_freePlugin(ScPlugin * plugin)816 void scribus134format_freePlugin(ScPlugin* plugin)
817 {
818 	Scribus134Format* plug = qobject_cast<Scribus134Format*>(plugin);
819 	Q_ASSERT(plug);
820 	delete plug;
821 }
822 
823 
824 namespace {
825 	const int NOVALUE = -16000;
826 
fixLegacyCharStyle(CharStyle & cstyle)827 	void fixLegacyCharStyle(CharStyle& cstyle)
828 	{
829 		if (! cstyle.font().usable())
830 			cstyle.resetFont();
831 		if (cstyle.fontSize() <= NOVALUE / 10)
832 			cstyle.resetFontSize();
833 //		if (cstyle.effects() == 65535)
834 //			cstyle.resetEffects();
835 		if (cstyle.fillColor().isEmpty())
836 			cstyle.resetFillColor();
837 		if (cstyle.fillShade() <= NOVALUE)
838 			cstyle.resetFillShade();
839 		if (cstyle.strokeColor().isEmpty())
840 			cstyle.resetStrokeColor();
841 		if (cstyle.strokeShade() <= NOVALUE)
842 			cstyle.resetStrokeShade();
843 		if (cstyle.shadowXOffset() <= NOVALUE / 10)
844 			cstyle.resetShadowXOffset();
845 		if (cstyle.shadowYOffset() <= NOVALUE / 10)
846 			cstyle.resetShadowYOffset();
847 		if (cstyle.outlineWidth() <= NOVALUE / 10)
848 			cstyle.resetOutlineWidth();
849 		if (cstyle.underlineOffset() <= NOVALUE / 10)
850 			cstyle.resetUnderlineOffset();
851 		if (cstyle.underlineWidth() <= NOVALUE / 10)
852 			cstyle.resetUnderlineWidth();
853 		if (cstyle.strikethruOffset() <= NOVALUE / 10)
854 			cstyle.resetStrikethruOffset();
855 		if (cstyle.strikethruWidth() <= NOVALUE / 10)
856 			cstyle.resetStrikethruWidth();
857 		if (cstyle.scaleH() <= NOVALUE / 10)
858 			cstyle.resetScaleH();
859 		if (cstyle.scaleV() <= NOVALUE / 10)
860 			cstyle.resetScaleV();
861 		if (cstyle.baselineOffset() <= NOVALUE / 10)
862 			cstyle.resetBaselineOffset();
863 		if (cstyle.tracking() <= NOVALUE / 10)
864 			cstyle.resetTracking();
865 	}
866 
fixLegacyParStyle(ParagraphStyle & pstyle)867 	void fixLegacyParStyle(ParagraphStyle& pstyle)
868 	{
869 		if (pstyle.lineSpacing() <= NOVALUE)
870 			pstyle.resetLineSpacing();
871 		if (pstyle.leftMargin() <= NOVALUE)
872 			pstyle.resetLeftMargin();
873 		if (pstyle.rightMargin() <= NOVALUE)
874 			pstyle.resetRightMargin();
875 		if (pstyle.firstIndent() <= NOVALUE)
876 			pstyle.resetFirstIndent();
877 		if (pstyle.alignment() < 0)
878 			pstyle.resetAlignment();
879 		if (pstyle.gapBefore() <= NOVALUE)
880 			pstyle.resetGapBefore();
881 		if (pstyle.gapAfter() <= NOVALUE)
882 			pstyle.resetGapAfter();
883 		if (pstyle.dropCapLines() < 0)
884 			pstyle.resetDropCapLines();
885 		if (pstyle.parEffectOffset() <= NOVALUE)
886 			pstyle.resetParEffectOffset();
887 		fixLegacyCharStyle(pstyle.charStyle());
888 	}
889 
890 }// namespace
891 
readDocAttributes(ScribusDoc * doc,ScXmlStreamAttributes & attrs)892 void Scribus134Format::readDocAttributes(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
893 {
894 	m_Doc->setPageSize(attrs.valueAsString("PAGESIZE"));
895 	m_Doc->setPageOrientation(attrs.valueAsInt("ORIENTATION", 0));
896 	m_Doc->FirstPnum  = attrs.valueAsInt("FIRSTNUM", 1);
897 	m_Doc->setPagePositioning(attrs.valueAsInt("BOOK", 0));
898 
899 	m_Doc->setUsesAutomaticTextFrames( attrs.valueAsInt("AUTOTEXT") );
900 	m_Doc->PageSp  = attrs.valueAsInt("AUTOSPALTEN");
901 	m_Doc->PageSpa = attrs.valueAsDouble("ABSTSPALTEN");
902 	m_Doc->setUnitIndex( attrs.valueAsInt("UNITS", 0) );
903 
904 	static const QString LANGUAGE("LANGUAGE");
905 	if (attrs.hasAttribute(LANGUAGE))
906 	{
907 		QString l(attrs.valueAsString(LANGUAGE));
908 		if (LanguageManager::instance()->langTableIndex(l) != -1)
909 			m_Doc->setLanguage(l); //new style storage
910 		else
911 		{ //old style storage
912 			QString lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
913 			if (lnew.isEmpty())
914 				lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
915 			m_Doc->setLanguage(lnew);
916 		}
917 	}
918 
919 	if (attrs.hasAttribute("PAGEWIDTH"))
920 		m_Doc->setPageWidth(attrs.valueAsDouble("PAGEWIDTH"));
921 	else
922 		m_Doc->setPageWidth(attrs.valueAsDouble("PAGEWITH"));
923 	m_Doc->setPageHeight(attrs.valueAsDouble("PAGEHEIGHT"));
924 	m_Doc->margins()->setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
925 	m_Doc->margins()->setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
926 	m_Doc->margins()->setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
927 	m_Doc->margins()->setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
928 	m_Doc->setMarginPreset(attrs.valueAsInt("PRESET", 0));
929 	m_Doc->bleeds()->setTop(attrs.valueAsDouble("BleedTop", 0.0));
930 	m_Doc->bleeds()->setLeft(attrs.valueAsDouble("BleedLeft", 0.0));
931 	m_Doc->bleeds()->setRight(attrs.valueAsDouble("BleedRight", 0.0));
932 	m_Doc->bleeds()->setBottom(attrs.valueAsDouble("BleedBottom", 0.0));
933 	m_Doc->setHyphAutomatic(attrs.valueAsBool("AUTOMATIC", true));
934 	m_Doc->setHyphAutoCheck(attrs.valueAsBool("AUTOCHECK", false));
935 	m_Doc->GuideLock = attrs.valueAsBool("GUIDELOCK", false);
936 
937 	m_Doc->rulerXoffset = attrs.valueAsDouble("rulerXoffset", 0.0);
938 	m_Doc->rulerYoffset = attrs.valueAsDouble("rulerYoffset", 0.0);
939 	m_Doc->SnapGuides   = attrs.valueAsBool("SnapToGuides", false);
940 	m_Doc->SnapGrid     = attrs.valueAsBool("SnapToGrid", false);
941 
942 	m_Doc->setAutoSave(attrs.valueAsBool("AutoSave", false));
943 	m_Doc->setAutoSaveTime(attrs.valueAsInt("AutoSaveTime", 600000));
944 
945 	double leftScratch;
946 	// FIXME A typo in early 1.3cvs (MAR 05) means we must support loading of
947 	// FIXME 'ScatchLeft' for a while too. This can be removed in a few months.
948 	if (attrs.hasAttribute("ScatchLeft"))
949 		leftScratch = attrs.valueAsDouble("ScatchLeft", 100.0);
950 	else
951 		leftScratch = attrs.valueAsDouble("ScratchLeft", 100.0);
952 	m_Doc->scratch()->set(attrs.valueAsDouble("ScratchTop", 20.0), leftScratch,
953 						  attrs.valueAsDouble("ScratchBottom", 20.0),attrs.valueAsDouble("ScratchRight", 100.0));
954 	m_Doc->setPageGapHorizontal(attrs.valueAsDouble("GapHorizontal", -1.0));
955 	m_Doc->setPageGapVertical(attrs.valueAsDouble("GapVertical", -1.0));
956 
957 	if (attrs.hasAttribute("PAGEC"))
958 		m_Doc->setPaperColor(QColor(attrs.valueAsString("PAGEC")));
959 
960 	m_Doc->setMarginColored(attrs.valueAsBool("RANDF", false));
961 
962 	readCMSSettings(doc, attrs);
963 	readDocumentInfo(doc, attrs);
964 	readGuideSettings(doc, attrs);
965 	readToolSettings(doc, attrs);
966 	readTypographicSettings(doc, attrs);
967 }
968 
readCMSSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)969 void Scribus134Format::readCMSSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
970 {
971 	doc->cmsSettings().SoftProofOn     = attrs.valueAsBool("DPSo", false);
972 	doc->cmsSettings().SoftProofFullOn = attrs.valueAsBool("DPSFo", false);
973 	doc->cmsSettings().CMSinUse   = attrs.valueAsBool("DPuse", false);
974 	doc->cmsSettings().GamutCheck = attrs.valueAsBool("DPgam", false);
975 	doc->cmsSettings().BlackPoint = attrs.valueAsBool("DPbla", true);
976 	doc->cmsSettings().DefaultMonitorProfile   = PrefsManager::instance().appPrefs.colorPrefs.DCMSset.DefaultMonitorProfile;
977 	doc->cmsSettings().DefaultPrinterProfile   = attrs.valueAsString("DPPr","");
978 	doc->cmsSettings().DefaultImageRGBProfile  = attrs.valueAsString("DPIn","");
979 	doc->cmsSettings().DefaultImageCMYKProfile = attrs.valueAsString("DPInCMYK","");
980 	doc->cmsSettings().DefaultSolidColorRGBProfile = attrs.valueAsString("DPIn2","");
981 	if (attrs.hasAttribute("DPIn3"))
982 		doc->cmsSettings().DefaultSolidColorCMYKProfile = attrs.valueAsString("DPIn3","");
983 	else
984 		doc->cmsSettings().DefaultSolidColorCMYKProfile = attrs.valueAsString("DPPr","");
985 	doc->cmsSettings().DefaultIntentColors = (eRenderIntent) attrs.valueAsInt("DISc", 1);
986 	doc->cmsSettings().DefaultIntentImages = (eRenderIntent) attrs.valueAsInt("DIIm", 0);
987 }
988 
readDocumentInfo(ScribusDoc * doc,ScXmlStreamAttributes & attrs)989 void Scribus134Format::readDocumentInfo(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
990 {
991 	DocumentInformation di;
992 	di.setAuthor(attrs.valueAsString("AUTHOR"));
993 	di.setComments(attrs.valueAsString("COMMENTS"));
994 	di.setKeywords(attrs.valueAsString("KEYWORDS",""));
995 	di.setTitle(attrs.valueAsString("TITLE"));
996 	di.setSubject(attrs.valueAsString("SUBJECT"));
997 	di.setPublisher(attrs.valueAsString("PUBLISHER", ""));
998 	di.setDate(attrs.valueAsString("DOCDATE", ""));
999 	di.setType(attrs.valueAsString("DOCTYPE", ""));
1000 	di.setFormat(attrs.valueAsString("DOCFORMAT", ""));
1001 	di.setIdent(attrs.valueAsString("DOCIDENT", ""));
1002 	di.setSource(attrs.valueAsString("DOCSOURCE", ""));
1003 	di.setLangInfo(attrs.valueAsString("DOCLANGINFO", ""));
1004 	di.setRelation(attrs.valueAsString("DOCRELATION", ""));
1005 	di.setCover(attrs.valueAsString("DOCCOVER", ""));
1006 	di.setRights(attrs.valueAsString("DOCRIGHTS", ""));
1007 	di.setContrib(attrs.valueAsString("DOCCONTRIB", ""));
1008 	doc->setDocumentInfo(di);
1009 }
1010 
readGuideSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)1011 void Scribus134Format::readGuideSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
1012 {
1013 	PrefsManager& prefsManager = PrefsManager::instance();
1014 	doc->guidesPrefs().minorGridSpacing = attrs.valueAsDouble("MINGRID", prefsManager.appPrefs.guidesPrefs.minorGridSpacing);
1015 	doc->guidesPrefs().majorGridSpacing = attrs.valueAsDouble("MAJGRID", prefsManager.appPrefs.guidesPrefs.majorGridSpacing);
1016 	doc->guidesPrefs().gridShown    = attrs.valueAsBool("SHOWGRID", false);
1017 	doc->guidesPrefs().guidesShown  =attrs.valueAsBool("SHOWGUIDES", true);
1018 	doc->guidesPrefs().colBordersShown  = attrs.valueAsBool("showcolborders", false);
1019 	doc->guidesPrefs().framesShown  = attrs.valueAsBool("SHOWFRAME", true);
1020 	doc->guidesPrefs().layerMarkersShown = attrs.valueAsBool("SHOWLAYERM", false);
1021 	doc->guidesPrefs().marginsShown = attrs.valueAsBool("SHOWMARGIN", true);
1022 	doc->guidesPrefs().baselineGridShown    = attrs.valueAsBool("SHOWBASE", false);
1023 	doc->guidesPrefs().showPic      = attrs.valueAsBool("SHOWPICT", true);
1024 	doc->guidesPrefs().linkShown    = attrs.valueAsBool("SHOWLINK", false);
1025 	doc->guidesPrefs().showControls = attrs.valueAsBool("SHOWControl", false);
1026 	doc->guidesPrefs().rulerMode    = attrs.valueAsBool("rulerMode", true);
1027 	doc->guidesPrefs().rulersShown  = attrs.valueAsBool("showrulers", true);
1028 	doc->guidesPrefs().showBleed    = attrs.valueAsBool("showBleed", true);
1029 	if (attrs.hasAttribute("MARGC"))
1030 		doc->guidesPrefs().marginColor  = QColor(attrs.valueAsString("MARGC"));
1031 	if (attrs.hasAttribute("MINORC"))
1032 		doc->guidesPrefs().minorGridColor = QColor(attrs.valueAsString("MINORC"));
1033 	if (attrs.hasAttribute("MAJORC"))
1034 		doc->guidesPrefs().majorGridColor = QColor(attrs.valueAsString("MAJORC"));
1035 	if (attrs.hasAttribute("GuideC"))
1036 		doc->guidesPrefs().guideColor = QColor(attrs.valueAsString("GuideC"));
1037 	if (attrs.hasAttribute("BaseC"))
1038 		doc->guidesPrefs().baselineGridColor  = QColor(attrs.valueAsString("BaseC"));
1039 	doc->guidesPrefs().renderStackOrder.clear();
1040 	if (attrs.valueAsBool("BACKG", true))
1041 		doc->guidesPrefs().renderStackOrder << 0 << 1 << 2 << 3 << 4;
1042 	else
1043 		doc->guidesPrefs().renderStackOrder << 4 << 0 << 1 << 2 << 3;
1044 	doc->guidesPrefs().gridType = 0;
1045 	doc->guidesPrefs().guideRad = attrs.valueAsDouble("GuideRad", 10.0);
1046 	doc->guidesPrefs().grabRadius  = attrs.valueAsInt("GRAB", 4);
1047 }
1048 
readToolSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)1049 void Scribus134Format::readToolSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
1050 {
1051 	QString textFont = attrs.valueAsString("DFONT");
1052 	m_AvailableFonts->findFont(textFont, doc);
1053 
1054 	doc->itemToolPrefs().textFont = textFont;
1055 	doc->itemToolPrefs().textSize = qRound(attrs.valueAsDouble("DSIZE", 12.0) * 10);
1056 	doc->itemToolPrefs().textColumns   = attrs.valueAsInt("DCOL", 1);
1057 	doc->itemToolPrefs().textColumnGap    = attrs.valueAsDouble("DGAP", 0.0);
1058 
1059 	doc->itemToolPrefs().polyCorners   = attrs.valueAsInt("POLYC", 4);
1060 	doc->itemToolPrefs().polyFactor   = attrs.valueAsDouble("POLYF", 0.5);
1061 	doc->itemToolPrefs().polyRotation   = attrs.valueAsDouble("POLYR", 0.0);
1062 	doc->itemToolPrefs().polyCurvature = attrs.valueAsDouble("POLYCUR", 0.0);
1063 	doc->itemToolPrefs().polyUseFactor   = attrs.valueAsBool("POLYS", false);
1064 
1065 	doc->itemToolPrefs().lineStartArrow = attrs.valueAsInt("StartArrow", 0);
1066 	doc->itemToolPrefs().lineEndArrow   = attrs.valueAsInt("EndArrow", 0);
1067 	doc->itemToolPrefs().imageScaleX      = attrs.valueAsDouble("PICTSCX", 1.0);
1068 	doc->itemToolPrefs().imageScaleY      = attrs.valueAsDouble("PICTSCY", 1.0);
1069 	doc->itemToolPrefs().imageScaleType   = attrs.valueAsBool("PSCALE", true);
1070 	doc->itemToolPrefs().imageAspectRatio = attrs.valueAsBool("PASPECT", false);
1071 	doc->itemToolPrefs().imageLowResType  = attrs.valueAsInt("HalfRes", 1);
1072 	doc->itemToolPrefs().imageUseEmbeddedPath = attrs.valueAsBool("EmbeddedPath", false);
1073 	if (attrs.hasAttribute("PEN"))
1074 		doc->itemToolPrefs().shapeLineColor = attrs.valueAsString("PEN");
1075 	if (attrs.hasAttribute("BRUSH"))
1076 		doc->itemToolPrefs().shapeFillColor = attrs.valueAsString("BRUSH");
1077 	if (attrs.hasAttribute("PENLINE"))
1078 		doc->itemToolPrefs().lineColor = attrs.valueAsString("PENLINE");
1079 	if (attrs.hasAttribute("PENTEXT"))
1080 		doc->itemToolPrefs().textColor = attrs.valueAsString("PENTEXT");
1081 	if (attrs.hasAttribute("StrokeText"))
1082 		doc->itemToolPrefs().textStrokeColor = attrs.valueAsString("StrokeText");
1083 	doc->itemToolPrefs().textFillColor  = attrs.valueAsString("TextBackGround", CommonStrings::None);
1084 	doc->itemToolPrefs().textLineColor   = attrs.valueAsString("TextLineColor", CommonStrings::None);
1085 	doc->itemToolPrefs().textFillColorShade =attrs.valueAsInt("TextBackGroundShade", 100);
1086 	doc->itemToolPrefs().textLineColorShade   = attrs.valueAsInt("TextLineShade", 100);
1087 	doc->itemToolPrefs().textShade    = attrs.valueAsInt("TextPenShade", 100);
1088 	doc->itemToolPrefs().textStrokeShade = attrs.valueAsInt("TextStrokeShade", 100);
1089 	doc->itemToolPrefs().shapeLineStyle    = static_cast<Qt::PenStyle>(attrs.valueAsInt("STIL"));
1090 	doc->itemToolPrefs().lineStyle = static_cast<Qt::PenStyle>(attrs.valueAsInt("STILLINE"));
1091 	doc->itemToolPrefs().shapeLineWidth      = attrs.valueAsDouble("WIDTH", 0.0);
1092 	doc->itemToolPrefs().lineWidth  = attrs.valueAsDouble("WIDTHLINE", 1.0);
1093 	doc->itemToolPrefs().shapeLineColorShade     = attrs.valueAsInt("PENSHADE", 100);
1094 	doc->itemToolPrefs().lineColor  = attrs.valueAsInt("LINESHADE", 100);
1095 	doc->itemToolPrefs().shapeFillColorShade      = attrs.valueAsInt("BRUSHSHADE", 100);
1096 	doc->opToolPrefs().dispX       = attrs.valueAsDouble("dispX", 10.0);
1097 	doc->opToolPrefs().dispY       = attrs.valueAsDouble("dispY", 10.0);
1098 	doc->opToolPrefs().constrain   = attrs.valueAsDouble("constrain", 15.0);
1099 	doc->itemToolPrefs().textTabFillChar = attrs.valueAsString("TabFill","");
1100 	doc->itemToolPrefs().textTabWidth   = attrs.valueAsDouble("TabWidth", 36.0);
1101 	doc->itemToolPrefs().firstLineOffset = FLOPRealGlyphHeight;
1102 	if (attrs.hasAttribute("CPICT"))
1103 		doc->itemToolPrefs().imageFillColor = attrs.valueAsString("CPICT");
1104 	doc->itemToolPrefs().imageFillColorShade = attrs.valueAsInt("PICTSHADE", 100);
1105 }
1106 
readTypographicSettings(ScribusDoc * doc,ScXmlStreamAttributes & attrs)1107 void Scribus134Format::readTypographicSettings(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
1108 {
1109 	doc->typographicPrefs().valueSuperScript   = attrs.valueAsInt("VHOCH");
1110 	doc->typographicPrefs().scalingSuperScript = attrs.valueAsInt("VHOCHSC");
1111 	doc->typographicPrefs().valueSubScript     = attrs.valueAsInt("VTIEF");
1112 	doc->typographicPrefs().scalingSubScript   = attrs.valueAsInt("VTIEFSC");
1113 	doc->typographicPrefs().valueSmallCaps     = attrs.valueAsInt("VKAPIT");
1114 	doc->guidesPrefs().valueBaselineGrid      = attrs.valueAsDouble("BASEGRID", 12.0);
1115 	doc->guidesPrefs().offsetBaselineGrid     = attrs.valueAsDouble("BASEO", 0.0);
1116 	// #9621 : autolinespacing is now express as a percentage of the font height
1117 	// It was not working in regualer text frame in 1.3.4+, so set it to the default value
1118 	doc->typographicPrefs().autoLineSpacing    = 100 /*attrs.valueAsInt("AUTOL", 20)*/;
1119 	doc->typographicPrefs().valueUnderlinePos  = attrs.valueAsInt("UnderlinePos", -1);
1120 	doc->typographicPrefs().valueUnderlineWidth  = attrs.valueAsInt("UnderlineWidth", -1);
1121 	doc->typographicPrefs().valueStrikeThruPos   = attrs.valueAsInt("StrikeThruPos", -1);
1122 	doc->typographicPrefs().valueStrikeThruWidth = attrs.valueAsInt("StrikeThruWidth", -1);
1123 }
1124 
readPageSets(ScribusDoc * doc,ScXmlStreamReader & reader)1125 bool Scribus134Format::readPageSets(ScribusDoc* doc, ScXmlStreamReader& reader)
1126 {
1127 	struct PageSet pageS;
1128 	ScXmlStreamAttributes attrs;
1129 
1130 	doc->clearPageSets();
1131 	while (!reader.atEnd() && !reader.hasError())
1132 	{
1133 		reader.readNext();
1134 		QStringRef tagName = reader.name();
1135 		if (reader.isStartElement())
1136 			attrs = reader.attributes();
1137 		if (reader.isEndElement() && tagName == "PageSets")
1138 			break;
1139 		if (reader.isStartElement() && tagName == "Set")
1140 		{
1141 			ScXmlStreamAttributes attrs = reader.scAttributes();
1142 			pageS.Name      = CommonStrings::untranslatePageSetString(attrs.valueAsString("Name"));
1143 			pageS.FirstPage = attrs.valueAsInt("FirstPage", 0);
1144 			pageS.Rows      = attrs.valueAsInt("Rows", 1);
1145 			pageS.Columns   = attrs.valueAsInt("Columns", 1);
1146 //			pageS.GapHorizontal = attrs.valueAsDouble("GapHorizontal", 0);
1147 //			pageS.GapVertical   = attrs.valueAsDouble("GapVertical", 0);
1148 //			pageS.GapBelow      = attrs.valueAsDouble("GapBelow", 0);
1149 			pageS.pageNames.clear();
1150 		}
1151 		if (reader.isEndElement() && tagName == "Set")
1152 		{
1153 			//->Prefs doc->pageSets.append(pageS);
1154 			doc->appendToPageSets(pageS);
1155 			if ((doc->pageSets().count()-1 == doc->pagePositioning()) && ((doc->pageGapHorizontal() < 0) && (doc->pageGapVertical() < 0)))
1156 			{
1157 				doc->setPageGapHorizontal(attrs.valueAsDouble("GapHorizontal", 0.0));
1158 				doc->setPageGapVertical(attrs.valueAsDouble("GapBelow", 0.0));
1159 			}
1160 		}
1161 		if (reader.isStartElement() && tagName == "PageNames")
1162 			pageS.pageNames.append(CommonStrings::untranslatePageSetLocString(attrs.valueAsString("Name")));
1163 	}
1164 	return !reader.hasError();
1165 }
1166 
readCheckProfile(ScribusDoc * doc,ScXmlStreamAttributes & attrs)1167 bool Scribus134Format::readCheckProfile(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
1168 {
1169 	struct CheckerPrefs checkerSettings;
1170 	QString profileName = attrs.valueAsString("Name");
1171 	if (profileName.isEmpty())
1172 		return true;
1173 	checkerSettings.ignoreErrors      = attrs.valueAsBool("ignoreErrors", false);
1174 	checkerSettings.autoCheck         = attrs.valueAsBool("autoCheck", true);
1175 	checkerSettings.checkGlyphs       = attrs.valueAsBool("checkGlyphs", true);
1176 	checkerSettings.checkOrphans      = attrs.valueAsBool("checkOrphans", true);
1177 	checkerSettings.checkOverflow     = attrs.valueAsBool("checkOverflow", true);
1178 	checkerSettings.checkPictures     = attrs.valueAsBool("checkPictures", true);
1179 	checkerSettings.checkPartFilledImageFrames = attrs.valueAsBool("checkPartFilledImageFrames", false);
1180 	checkerSettings.checkResolution   = attrs.valueAsBool("checkResolution", true);
1181 	checkerSettings.checkTransparency = attrs.valueAsBool("checkTransparency", true);
1182 	checkerSettings.minResolution     = attrs.valueAsDouble("minResolution", 72.0);
1183 	checkerSettings.maxResolution     = attrs.valueAsDouble("maxResolution", 4800.0);
1184 	checkerSettings.checkAnnotations  = attrs.valueAsBool("checkAnnotations", false);
1185 	checkerSettings.checkRasterPDF    = attrs.valueAsBool("checkRasterPDF", true);
1186 	checkerSettings.checkForGIF       = attrs.valueAsBool("checkForGIF", true);
1187 	checkerSettings.ignoreOffLayers   = attrs.valueAsBool("ignoreOffLayers", false);
1188 	checkerSettings.checkOffConflictLayers = attrs.valueAsBool("checkOffConflictLayers", false);
1189 	checkerSettings.checkNotCMYKOrSpot     = attrs.valueAsBool("checkNotCMYKOrSpot", false);
1190 	checkerSettings.checkDeviceColorsAndOutputIntent = attrs.valueAsBool("checkDeviceColorsAndOutputIntent", false);
1191 	checkerSettings.checkFontNotEmbedded = attrs.valueAsBool("checkFontNotEmbedded", false);
1192 	checkerSettings.checkFontIsOpenType  = attrs.valueAsBool("checkFontIsOpenType", false);
1193 	checkerSettings.checkAppliedMasterDifferentSide = attrs.valueAsBool("checkAppliedMasterDifferentSide", true);
1194 	checkerSettings.checkEmptyTextFrames     = attrs.valueAsBool("checkEmptyTextFrames", true);
1195 	doc->set1CheckerProfile(profileName, checkerSettings);
1196 	return true;
1197 }
1198 
readColor(ColorList & colors,ScXmlStreamAttributes & attrs)1199 bool Scribus134Format::readColor(ColorList& colors, ScXmlStreamAttributes& attrs)
1200 {
1201 	ScColor color;
1202 	if (attrs.hasAttribute("CMYK"))
1203 		color.setNamedColor(attrs.valueAsString("CMYK"));
1204 	else
1205 		color.fromQColor(QColor(attrs.valueAsString("RGB")));
1206 	color.setSpotColor( attrs.valueAsBool("Spot", false) );
1207 	color.setRegistrationColor( attrs.valueAsBool("Register", false) );
1208 	QString name = attrs.valueAsString("NAME");
1209 	if (name == "All")
1210 	{
1211 		color.setSpotColor(true);
1212 		color.setRegistrationColor(true);
1213 		color.setColor(255, 255, 255, 255);
1214 	}
1215 	colors.insert((name.isEmpty()) ? color.name() : name, color);
1216 	return true;
1217 }
1218 
readCharacterStyleAttrs(ScribusDoc * doc,ScXmlStreamAttributes & attrs,CharStyle & newStyle)1219 void Scribus134Format::readCharacterStyleAttrs(ScribusDoc *doc, ScXmlStreamAttributes& attrs, CharStyle & newStyle)
1220 {
1221 	static const QString CPARENT("CPARENT");
1222 	if (attrs.hasAttribute(CPARENT))
1223 	{
1224 		QString parentStyle = attrs.valueAsString(CPARENT);
1225 		if (!parentStyle.isEmpty())
1226 			parentStyle = charStyleMap.value(parentStyle, parentStyle);
1227 		newStyle.setParent(parentStyle);
1228 	}
1229 
1230 	static const QString FONT("FONT");
1231 	if (attrs.hasAttribute(FONT))
1232 	{
1233 		const ScFace& face = m_AvailableFonts->findFont(attrs.valueAsString(FONT), doc);
1234 		if (!face.isNone())
1235 			newStyle.setFont(face);
1236 	}
1237 
1238 	static const QString FONTSIZE("FONTSIZE");
1239 	if (attrs.hasAttribute(FONTSIZE))
1240 		newStyle.setFontSize(qRound(attrs.valueAsDouble(FONTSIZE) * 10));
1241 
1242 	static const QString FCOLOR("FCOLOR");
1243 	if (attrs.hasAttribute(FCOLOR))
1244 		newStyle.setFillColor(attrs.valueAsString(FCOLOR));
1245 
1246 	static const QString KERN("KERN");
1247 	if (attrs.hasAttribute(KERN))
1248 		newStyle.setTracking(qRound(attrs.valueAsDouble(KERN) * 10));
1249 
1250 	static const QString FSHADE("FSHADE");
1251 	if (attrs.hasAttribute(FSHADE))
1252 		newStyle.setFillShade(attrs.valueAsInt(FSHADE));
1253 
1254 	static const QString EFFECTS("EFFECTS");
1255 	if (attrs.hasAttribute(EFFECTS))
1256 		newStyle.setFeatures(static_cast<StyleFlag>(attrs.valueAsInt(EFFECTS)).featureList());
1257 
1258 	static const QString EFFECT("EFFECT");
1259 	if (attrs.hasAttribute(EFFECT))
1260 		newStyle.setFeatures(static_cast<StyleFlag>(attrs.valueAsInt(EFFECT)).featureList());
1261 
1262 	static const QString FEATURES("FEATURES");
1263 	if (attrs.hasAttribute(FEATURES))
1264 		newStyle.setFeatures(attrs.valueAsString(FEATURES).split( " ", Qt::SkipEmptyParts));
1265 
1266 	static const QString SCOLOR("SCOLOR");
1267 	if (attrs.hasAttribute(SCOLOR))
1268 		newStyle.setStrokeColor(attrs.valueAsString(SCOLOR, CommonStrings::None));
1269 
1270 	static const QString SSHADE("SSHADE");
1271 	if (attrs.hasAttribute(SSHADE))
1272 		newStyle.setStrokeShade(attrs.valueAsInt(SSHADE));
1273 
1274 	static const QString SCALEH("SCALEH");
1275 	if (attrs.hasAttribute(SCALEH))
1276 		newStyle.setScaleH(qRound(attrs.valueAsDouble(SCALEH) * 10));
1277 
1278 	static const QString SCALEV("SCALEV");
1279 	if (attrs.hasAttribute(SCALEV))
1280 		newStyle.setScaleV(qRound(attrs.valueAsDouble(SCALEV) * 10));
1281 
1282 	static const QString BASEO("BASEO");
1283 	if (attrs.hasAttribute(BASEO))
1284 		newStyle.setBaselineOffset(qRound(attrs.valueAsDouble(BASEO) * 10));
1285 
1286 	static const QString TXTSHX("TXTSHX");
1287 	if (attrs.hasAttribute(TXTSHX))
1288 		newStyle.setShadowXOffset(qRound(attrs.valueAsDouble(TXTSHX) * 10));
1289 
1290 	static const QString TXTSHY("TXTSHY");
1291 	if (attrs.hasAttribute(TXTSHY))
1292 		newStyle.setShadowYOffset(qRound(attrs.valueAsDouble(TXTSHY) * 10));
1293 
1294 	static const QString TXTOUT("TXTOUT");
1295 	if (attrs.hasAttribute(TXTOUT))
1296 		newStyle.setOutlineWidth(qRound(attrs.valueAsDouble(TXTOUT) * 10));
1297 
1298 	static const QString TXTULP("TXTULP");
1299 	if (attrs.hasAttribute(TXTULP))
1300 		newStyle.setUnderlineOffset(qRound(attrs.valueAsDouble(TXTULP) * 10));
1301 
1302 	static const QString TXTULW("TXTULW");
1303 	if (attrs.hasAttribute(TXTULW))
1304 		newStyle.setUnderlineWidth(qRound(attrs.valueAsDouble(TXTULW) * 10));
1305 
1306 	static const QString TXTSTP("TXTSTP");
1307 	if (attrs.hasAttribute(TXTSTP))
1308 		newStyle.setStrikethruOffset(qRound(attrs.valueAsDouble(TXTSTP) * 10));
1309 
1310 	static const QString TXTSTW("TXTSTW");
1311 	if (attrs.hasAttribute(TXTSTW))
1312 		newStyle.setStrikethruWidth(qRound(attrs.valueAsDouble(TXTSTW) * 10));
1313 
1314 	static const QString LANGUAGE("LANGUAGE");
1315 	if (attrs.hasAttribute(LANGUAGE))
1316 	{
1317 		QString l(attrs.valueAsString(LANGUAGE));
1318 		if (LanguageManager::instance()->langTableIndex(l) != -1)
1319 			newStyle.setLanguage(l); //new style storage
1320 		else
1321 		{ //old style storage
1322 			QString lnew = LanguageManager::instance()->getAbbrevFromLang(l, true);
1323 			if (lnew.isEmpty())
1324 				lnew = LanguageManager::instance()->getAbbrevFromLang(l, false);
1325 			newStyle.setLanguage(lnew);
1326 		}
1327 	}
1328 
1329 	static const QString SHORTCUT("SHORTCUT");
1330 	if (attrs.hasAttribute(SHORTCUT))
1331 		newStyle.setShortcut(attrs.valueAsString(SHORTCUT));
1332 
1333 	static const QString WORDTRACK("wordTrack");
1334 	if (attrs.hasAttribute(WORDTRACK))
1335 		newStyle.setWordTracking(attrs.valueAsDouble(WORDTRACK));
1336 }
1337 
readNamedCharacterStyleAttrs(ScribusDoc * doc,ScXmlStreamAttributes & attrs,CharStyle & newStyle)1338 void Scribus134Format::readNamedCharacterStyleAttrs(ScribusDoc *doc, ScXmlStreamAttributes& attrs, CharStyle & newStyle)
1339 {
1340 	static const QString CNAME("CNAME");
1341 	if (attrs.hasAttribute(CNAME))
1342 		newStyle.setName(attrs.valueAsString(CNAME));
1343 
1344 	// The default style attribute must be correctly set before trying to assign a parent
1345 	static const QString DEFAULTSTYLE("DefaultStyle");
1346 	if (newStyle.hasName() && attrs.hasAttribute(DEFAULTSTYLE))
1347 		newStyle.setDefaultStyle(attrs.valueAsInt(DEFAULTSTYLE));
1348 	else if (newStyle.name() == CommonStrings::DefaultCharacterStyle || newStyle.name() == CommonStrings::trDefaultCharacterStyle)
1349 		newStyle.setDefaultStyle(true);
1350 	else
1351 		newStyle.setDefaultStyle(false);
1352 
1353 	readCharacterStyleAttrs(doc, attrs, newStyle);
1354 
1355 	// Check that a style is not its own parent
1356 	QString parentStyle = newStyle.parent();
1357 	if (parentStyle == newStyle.name())
1358 		newStyle.setParent(QString());
1359 }
1360 
readParagraphStyle(ScribusDoc * doc,ScXmlStreamReader & reader,ParagraphStyle & newStyle)1361 void Scribus134Format::readParagraphStyle(ScribusDoc *doc, ScXmlStreamReader& reader, ParagraphStyle& newStyle)
1362 {
1363 	ScXmlStreamAttributes attrs = reader.scAttributes();
1364 
1365 	newStyle.erase();
1366 	newStyle.setName(attrs.valueAsString("NAME", ""));
1367 	// The default style attribute must be correctly set before trying to assign a parent
1368 	static const QString DEFAULTSTYLE("DefaultStyle");
1369 	if (attrs.hasAttribute(DEFAULTSTYLE))
1370 		newStyle.setDefaultStyle(attrs.valueAsInt(DEFAULTSTYLE));
1371 	else if (newStyle.name() == CommonStrings::DefaultParagraphStyle || newStyle.name() == CommonStrings::trDefaultParagraphStyle)
1372 		newStyle.setDefaultStyle(true);
1373 	else
1374 		newStyle.setDefaultStyle(false);
1375 
1376 	QString parentStyle = attrs.valueAsString("PARENT", QString());
1377 	if (!parentStyle.isEmpty() && (parentStyle != newStyle.name()))
1378 	{
1379 		parentStyle = parStyleMap.value(parentStyle, parentStyle);
1380 		if (m_Doc->styleExists(parentStyle))
1381 			newStyle.setParent(parentStyle);
1382 		else
1383 			newStyle.setParent(CommonStrings::DefaultParagraphStyle);
1384 	}
1385 
1386 	static const QString LINESPMode("LINESPMode");
1387 	if (attrs.hasAttribute(LINESPMode))
1388 		newStyle.setLineSpacingMode(static_cast<ParagraphStyle::LineSpacingMode>(attrs.valueAsInt(LINESPMode)));
1389 
1390 	static const QString LINESP("LINESP");
1391 	if (attrs.hasAttribute(LINESP))
1392 		newStyle.setLineSpacing(attrs.valueAsDouble(LINESP));
1393 
1394 	static const QString INDENT("INDENT");
1395 	if (attrs.hasAttribute(INDENT))
1396 		newStyle.setLeftMargin(attrs.valueAsDouble(INDENT));
1397 
1398 	static const QString RMARGIN("RMARGIN");
1399 	if (attrs.hasAttribute(RMARGIN))
1400 		newStyle.setRightMargin(attrs.valueAsDouble(RMARGIN));
1401 
1402 	static const QString FIRST("FIRST");
1403 	if (attrs.hasAttribute(FIRST))
1404 		newStyle.setFirstIndent(attrs.valueAsDouble(FIRST));
1405 
1406 	static const QString ALIGN("ALIGN");
1407 	if (attrs.hasAttribute(ALIGN))
1408 		newStyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(attrs.valueAsInt(ALIGN)));
1409 
1410 	static const QString VOR("VOR");
1411 	if (attrs.hasAttribute(VOR))
1412 		newStyle.setGapBefore(attrs.valueAsDouble(VOR));
1413 
1414 	static const QString NACH("NACH");
1415 	if (attrs.hasAttribute(NACH))
1416 		newStyle.setGapAfter(attrs.valueAsDouble(NACH));
1417 
1418 	static const QString DROP("DROP");
1419 	if (attrs.hasAttribute(DROP))
1420 		newStyle.setHasDropCap(static_cast<bool>(attrs.valueAsInt(DROP)));
1421 
1422 	static const QString DROPLIN("DROPLIN");
1423 	if (attrs.hasAttribute(DROPLIN))
1424 		newStyle.setDropCapLines(attrs.valueAsInt(DROPLIN));
1425 
1426 	static const QString DROPDIST("DROPDIST");
1427 	if (attrs.hasAttribute(DROPDIST))
1428 		newStyle.setParEffectOffset(attrs.valueAsDouble(DROPDIST));
1429 
1430 	static const QString PSHORTCUT("PSHORTCUT");
1431 	if (attrs.hasAttribute(PSHORTCUT))
1432 		newStyle.setShortcut(attrs.valueAsString(PSHORTCUT));
1433 
1434 	static const QString OpticalMargins("OpticalMargins");
1435 	if (attrs.hasAttribute(OpticalMargins))
1436 		newStyle.setOpticalMargins(attrs.valueAsInt(OpticalMargins));
1437 
1438 	static const QString HyphenationMode("HyphenationMode");
1439 	if (attrs.hasAttribute(HyphenationMode))
1440 		newStyle.setHyphenationMode(attrs.valueAsInt(HyphenationMode));
1441 
1442 	static const QString MinWordTrack("MinWordTrack");
1443 	if (attrs.hasAttribute(MinWordTrack))
1444 		newStyle.setMinWordTracking(attrs.valueAsDouble(MinWordTrack));
1445 
1446 	static const QString NormWordTrack("NormWordTrack");
1447 	if (attrs.hasAttribute(NormWordTrack))
1448 		newStyle.charStyle().setWordTracking(attrs.valueAsDouble(NormWordTrack));
1449 
1450 	static const QString MinGlyphShrink("MinGlyphShrink");
1451 	if (attrs.hasAttribute(MinGlyphShrink))
1452 		newStyle.setMinGlyphExtension(attrs.valueAsDouble(MinGlyphShrink));
1453 
1454 	static const QString MaxGlyphExtend("MaxGlyphExtend");
1455 	if (attrs.hasAttribute(MaxGlyphExtend))
1456 		newStyle.setMaxGlyphExtension(attrs.valueAsDouble(MaxGlyphExtend));
1457 
1458 	readCharacterStyleAttrs(doc, attrs, newStyle.charStyle());
1459 
1460 	//	newStyle.tabValues().clear();
1461 	int numTabs = attrs.valueAsInt("NUMTAB", 0);
1462 	if (numTabs > 0)
1463 	{
1464 		QList<ParagraphStyle::TabRecord> tbs;
1465 		ParagraphStyle::TabRecord tb;
1466 		QString tmp = attrs.valueAsString("TABS");
1467 		ScTextStream tgv(&tmp, QIODevice::ReadOnly);
1468 		double xf, xf2;
1469 		for (int cxv = 0; cxv < numTabs; cxv += 2)
1470 		{
1471 			tgv >> xf;
1472 			tgv >> xf2;
1473 			tb.tabPosition = xf2;
1474 			tb.tabType = static_cast<int>(xf);
1475 			tb.tabFillChar =  QChar();
1476 			tbs.append(tb);
1477 		}
1478 		newStyle.setTabValues(tbs);
1479 		tmp = "";
1480 	}
1481 	else
1482 	{
1483 		QList<ParagraphStyle::TabRecord> tbs;
1484 		newStyle.resetTabValues();
1485 		QStringRef thisTagName = reader.name();
1486 		while (!reader.atEnd() && !reader.hasError())
1487 		{
1488 			reader.readNext();
1489 			if (reader.isEndElement() && reader.name() == thisTagName)
1490 				break;
1491 			if (reader.isStartElement() && reader.name() == "Tabs")
1492 			{
1493 				ParagraphStyle::TabRecord tb;
1494 				ScXmlStreamAttributes attrs2 = reader.scAttributes();
1495 				tb.tabPosition = attrs2.valueAsDouble("Pos");
1496 				tb.tabType     = attrs2.valueAsInt("Type");
1497 				QString tbCh   = attrs2.valueAsString("Fill","");
1498 				tb.tabFillChar = tbCh.isEmpty() ? QChar() : tbCh[0];
1499 				tbs.append(tb);
1500 			}
1501 		}
1502 		if (tbs.count() > 0)
1503 			newStyle.setTabValues(tbs);
1504 	}
1505 
1506 	fixLegacyParStyle(newStyle);
1507 }
1508 
readLayers(ScLayer & layer,ScXmlStreamAttributes & attrs)1509 void Scribus134Format::readLayers(ScLayer& layer, ScXmlStreamAttributes& attrs)
1510 {
1511 	int lId   = attrs.valueAsInt("NUMMER");
1512 	int level = attrs.valueAsInt("LEVEL");
1513 	layer = ScLayer( attrs.valueAsString("NAME"), level, lId);
1514 	layer.isViewable   = attrs.valueAsInt("SICHTBAR");
1515 	layer.isPrintable  = attrs.valueAsInt("DRUCKEN");
1516 	layer.isEditable   = attrs.valueAsInt("EDIT", 1);
1517 	layer.flowControl  = attrs.valueAsInt("FLOW", 1);
1518 	layer.transparency = attrs.valueAsDouble("TRANS", 1.0);
1519 	layer.blendMode    = attrs.valueAsInt("BLEND", 0);
1520 	layer.outlineMode  = attrs.valueAsInt("OUTL", 0);
1521 	if (attrs.hasAttribute("LAYERC"))
1522 		layer.markerColor =  QColor(attrs.valueAsString("LAYERC","#000000"));
1523 }
1524 
readArrows(ScribusDoc * doc,ScXmlStreamAttributes & attrs)1525 bool Scribus134Format::readArrows(ScribusDoc* doc, ScXmlStreamAttributes& attrs)
1526 {
1527 	double xa, ya;
1528 	struct ArrowDesc arrow;
1529 	arrow.name = attrs.valueAsString("Name");
1530 	arrow.userArrow = true;
1531 	QString tmp = attrs.valueAsString("Points");
1532 	ScTextStream fp(&tmp, QIODevice::ReadOnly);
1533 	unsigned int numPoints = attrs.valueAsUInt("NumPoints");
1534 	for (uint cx = 0; cx < numPoints; ++cx)
1535 	{
1536 		fp >> xa;
1537 		fp >> ya;
1538 		arrow.points.addPoint(xa, ya);
1539 	}
1540 	doc->appendToArrowStyles(arrow);
1541 	return true;
1542 }
1543 
readMultiline(multiLine & ml,ScXmlStreamReader & reader)1544 bool Scribus134Format::readMultiline(multiLine& ml, ScXmlStreamReader& reader)
1545 {
1546 	ml = multiLine();
1547 	ScXmlStreamAttributes rattrs = reader.scAttributes();
1548 	QStringRef tagName = reader.name();
1549 	while (!reader.atEnd() && !reader.hasError())
1550 	{
1551 		ScXmlStreamReader::TokenType tType = reader.readNext();
1552 		if (tType == ScXmlStreamReader::EndElement && reader.name() == tagName)
1553 			break;
1554 		if (tType == ScXmlStreamReader::StartElement && reader.name() == "SubLine")
1555 		{
1556 			struct SingleLine sl;
1557 			ScXmlStreamAttributes attrs = reader.scAttributes();
1558 			sl.Color    = attrs.valueAsString("Color");
1559 			sl.Dash     = attrs.valueAsInt("Dash");
1560 			sl.LineEnd  = attrs.valueAsInt("LineEnd");
1561 			sl.LineJoin = attrs.valueAsInt("LineJoin");
1562 			sl.Shade    = attrs.valueAsInt("Shade");
1563 			sl.Width    = attrs.valueAsDouble("Width");
1564 			ml.shortcut = attrs.valueAsString("Shortcut");
1565 			ml.push_back(sl);
1566 		}
1567 	}
1568 	return !reader.hasError();
1569 }
1570 
readBookMark(ScribusDoc::BookMa & bookmark,int & elem,ScXmlStreamAttributes & attrs)1571 bool Scribus134Format::readBookMark(ScribusDoc::BookMa& bookmark, int& elem, ScXmlStreamAttributes& attrs)
1572 {
1573 	elem = attrs.valueAsInt("Element");
1574 	bookmark.PageObject = nullptr;
1575 	bookmark.Title  = attrs.valueAsString("Title");
1576 	bookmark.Text   = attrs.valueAsString("Text");
1577 	bookmark.Aktion = attrs.valueAsString("Aktion");
1578 	bookmark.ItemNr = attrs.valueAsInt("ItemNr");
1579 	bookmark.First  = attrs.valueAsInt("First");
1580 	bookmark.Last   = attrs.valueAsInt("Last");
1581 	bookmark.Prev   = attrs.valueAsInt("Prev");
1582 	bookmark.Next   = attrs.valueAsInt("Next");
1583 	bookmark.Parent = attrs.valueAsInt("Parent");
1584 	return true;
1585 }
1586 
readPDFOptions(ScribusDoc * doc,ScXmlStreamReader & reader)1587 bool Scribus134Format::readPDFOptions(ScribusDoc* doc, ScXmlStreamReader& reader)
1588 {
1589 	ScXmlStreamAttributes attrs = reader.scAttributes();
1590 
1591 	doc->pdfOptions().firstUse   = attrs.valueAsBool("firstUse", true);
1592 	doc->pdfOptions().Articles   = attrs.valueAsBool("Articles");
1593 	doc->pdfOptions().Thumbnails = attrs.valueAsBool("Thumbnails");
1594 	doc->pdfOptions().Compress   = attrs.valueAsBool("Compress");
1595 	doc->pdfOptions().CompressMethod = (PDFOptions::PDFCompression)attrs.valueAsInt("CMethod", 0);
1596 	doc->pdfOptions().Quality    = attrs.valueAsInt("Quality", 0);
1597 	doc->pdfOptions().RecalcPic  = attrs.valueAsBool("RecalcPic");
1598 	doc->pdfOptions().embedPDF   = attrs.valueAsBool("EmbedPDF", false);
1599 	doc->pdfOptions().Bookmarks  = attrs.valueAsBool("Bookmarks");
1600 	doc->pdfOptions().MirrorH    = attrs.valueAsBool("MirrorH", false);
1601 	doc->pdfOptions().MirrorV    = attrs.valueAsBool("MirrorV", false);
1602 	doc->pdfOptions().RotateDeg  = attrs.valueAsInt("RotateDeg", 0);
1603 	doc->pdfOptions().doClip     = attrs.valueAsBool("Clip", false);
1604 	doc->pdfOptions().PresentMode = attrs.valueAsBool("PresentMode");
1605 	doc->pdfOptions().PicRes     = attrs.valueAsInt("PicRes");
1606 	// Fixme: check input pdf version
1607 	doc->pdfOptions().Version    = (PDFVersion::Version) attrs.valueAsInt("Version");
1608 	doc->pdfOptions().Resolution = attrs.valueAsInt("Resolution");
1609 	doc->pdfOptions().Binding    = attrs.valueAsInt("Binding");
1610 	doc->pdfOptions().fileName   = "";
1611 	doc->pdfOptions().FontEmbedding = (PDFOptions::PDFFontEmbedding) attrs.valueAsInt("FontEmbedding", 0);
1612 	doc->pdfOptions().isGrayscale   = attrs.valueAsBool("Grayscale", false);
1613 	doc->pdfOptions().UseRGB        = attrs.valueAsBool("RGBMode", false);
1614 	doc->pdfOptions().UseProfiles   = attrs.valueAsBool("UseProfiles", false);
1615 	doc->pdfOptions().UseProfiles2  = attrs.valueAsBool("UseProfiles2", false);
1616 	doc->pdfOptions().Intent        = attrs.valueAsInt("Intent", 1);
1617 	doc->pdfOptions().Intent2       = attrs.valueAsInt("Intent2", 1);
1618 	doc->pdfOptions().SolidProf     = attrs.valueAsString("SolidP", "");
1619 	doc->pdfOptions().ImageProf     = attrs.valueAsString("ImageP", "");
1620 	doc->pdfOptions().PrintProf     = attrs.valueAsString("PrintP", "");
1621 	doc->pdfOptions().Info          = attrs.valueAsString("InfoString", "");
1622 	doc->pdfOptions().bleeds.setTop(attrs.valueAsDouble("BTop", 0.0));
1623 	doc->pdfOptions().bleeds.setLeft(attrs.valueAsDouble("BLeft", 0.0));
1624 	doc->pdfOptions().bleeds.setRight(attrs.valueAsDouble("BRight", 0.0));
1625 	doc->pdfOptions().bleeds.setBottom(attrs.valueAsDouble("BBottom", 0.0));
1626 	doc->pdfOptions().useDocBleeds  = attrs.valueAsBool("useDocBleeds", true);
1627 	doc->pdfOptions().cropMarks     = attrs.valueAsBool("cropMarks", false);
1628 	doc->pdfOptions().bleedMarks    = attrs.valueAsBool("bleedMarks", false);
1629 	doc->pdfOptions().registrationMarks = attrs.valueAsBool("registrationMarks", false);
1630 	doc->pdfOptions().colorMarks    = attrs.valueAsBool("colorMarks", false);
1631 	doc->pdfOptions().docInfoMarks  = attrs.valueAsBool("docInfoMarks", false);
1632 	doc->pdfOptions().markLength    = attrs.valueAsDouble("markLength", 0.0);
1633 	doc->pdfOptions().markOffset    = attrs.valueAsDouble("markOffset", 0.0);
1634 	doc->pdfOptions().EmbeddedI     = attrs.valueAsBool("ImagePr", false);
1635 	doc->pdfOptions().PassOwner     = attrs.valueAsString("PassOwner", "");
1636 	doc->pdfOptions().PassUser      = attrs.valueAsString("PassUser", "");
1637 	doc->pdfOptions().Permissions   = attrs.valueAsInt("Permissions", -4);
1638 	doc->pdfOptions().Encrypt       = attrs.valueAsBool("Encrypt", false);
1639 	doc->pdfOptions().useLayers     = attrs.valueAsBool("UseLayers", false);
1640 	doc->pdfOptions().UseLPI        = attrs.valueAsBool("UseLpi", false);
1641 	doc->pdfOptions().UseSpotColors = attrs.valueAsBool("UseSpotColors", true);
1642 	doc->pdfOptions().doMultiFile   = attrs.valueAsBool("doMultiFile", false);
1643 	doc->pdfOptions().displayBookmarks =  attrs.valueAsBool("displayBookmarks", false);
1644 	doc->pdfOptions().displayFullscreen = attrs.valueAsBool("displayFullscreen", false);
1645 	doc->pdfOptions().displayLayers = attrs.valueAsBool("displayLayers", false);
1646 	doc->pdfOptions().displayThumbs = attrs.valueAsBool("displayThumbs", false);
1647 	doc->pdfOptions().hideMenuBar   = attrs.valueAsBool("hideMenuBar", false);
1648 	doc->pdfOptions().hideToolBar   = attrs.valueAsBool("hideToolBar", false);
1649 	doc->pdfOptions().fitWindow     = attrs.valueAsBool("fitWindow", false);
1650 	doc->pdfOptions().PageLayout    = attrs.valueAsInt("PageLayout", 0);
1651 	doc->pdfOptions().openAction    = attrs.valueAsString("openAction", "");
1652 
1653 	QStringRef tagName = reader.name();
1654 	while (!reader.atEnd() && !reader.hasError())
1655 	{
1656 		reader.readNext();
1657 		if (reader.isEndElement() && (reader.name() == tagName))
1658 			break;
1659 		if (!reader.isStartElement())
1660 			continue;
1661 		QStringRef tName = reader.name();
1662 		attrs = reader.scAttributes();
1663 		if (tName == "LPI")
1664 		{
1665 			struct LPIData lpo;
1666 			lpo.Angle     = attrs.valueAsInt("Angle");
1667 			lpo.Frequency = attrs.valueAsInt("Frequency");
1668 			lpo.SpotFunc  = attrs.valueAsInt("SpotFunction");
1669 			doc->pdfOptions().LPISettings[attrs.valueAsString("Color")] = lpo;
1670 		}
1671 		if (tName == "Fonts")
1672 		{
1673 			QString fname = attrs.valueAsString("Name");
1674 			if (!doc->pdfOptions().EmbedList.contains(fname))
1675 				doc->pdfOptions().EmbedList.append(fname);
1676 		}
1677 		if (tName == "Subset")
1678 		{
1679 			QString sname = attrs.valueAsString("Name");
1680 			if (!doc->pdfOptions().SubsetList.contains(sname))
1681 				doc->pdfOptions().SubsetList.append(sname);
1682 		}
1683 		if (tName == "Effekte")
1684 		{
1685 			struct PDFPresentationData ef;
1686 			ef.pageEffectDuration =  attrs.valueAsInt("pageEffectDuration");
1687 			ef.pageViewDuration =  attrs.valueAsInt("pageViewDuration");
1688 			ef.effectType = attrs.valueAsInt("effectType");
1689 			ef.Dm = attrs.valueAsInt("Dm");
1690 			ef.M  = attrs.valueAsInt("M");
1691 			ef.Di = attrs.valueAsInt("Di");
1692 			EffVal.append(ef);
1693 		}
1694 	}
1695 	return !reader.hasError();
1696 }
1697 
readPrinterOptions(ScribusDoc * doc,ScXmlStreamReader & reader)1698 bool Scribus134Format::readPrinterOptions(ScribusDoc* doc, ScXmlStreamReader& reader)
1699 {
1700 	ScXmlStreamAttributes attrs = reader.scAttributes();
1701 	doc->Print_Options.firstUse = attrs.valueAsBool("firstUse");
1702 	if (doc->Print_Options.firstUse)
1703 	{
1704 		// Formerly we were writing uninitialized structure values in documents
1705 		// so set these uninitialized values to something more meaningful
1706 		PrinterUtil::getDefaultPrintOptions(doc->Print_Options, doc->bleedsVal());
1707 		reader.readToElementEnd();
1708 		return !reader.hasError();
1709 	}
1710 
1711 	doc->Print_Options.toFile   = attrs.valueAsBool("toFile");
1712 	doc->Print_Options.useAltPrintCommand = attrs.valueAsBool("useAltPrintCommand");
1713 	doc->Print_Options.outputSeparations  = attrs.valueAsBool("outputSeparations");
1714 	doc->Print_Options.useSpotColors      = attrs.valueAsBool("useSpotColors");
1715 	doc->Print_Options.useColor = attrs.valueAsBool("useColor");
1716 	doc->Print_Options.mirrorH  = attrs.valueAsBool("mirrorH");
1717 	doc->Print_Options.mirrorV  = attrs.valueAsBool("mirrorV");
1718 	doc->Print_Options.doGCR    = attrs.valueAsBool("doGCR");
1719 	doc->Print_Options.doClip   = attrs.valueAsBool("doClip");
1720 	doc->Print_Options.setDevParam  = attrs.valueAsBool("setDevParam");
1721 	doc->Print_Options.useDocBleeds = attrs.valueAsBool("useDocBleeds");
1722 	doc->Print_Options.cropMarks    = attrs.valueAsBool("cropMarks");
1723 	doc->Print_Options.bleedMarks   = attrs.valueAsBool("bleedMarks");
1724 	doc->Print_Options.registrationMarks = attrs.valueAsBool("registrationMarks");
1725 	doc->Print_Options.colorMarks   = attrs.valueAsBool("colorMarks");
1726 	doc->Print_Options.includePDFMarks = attrs.valueAsBool("includePDFMarks", true);
1727 	if (attrs.hasAttribute("PrintEngine"))
1728 		doc->Print_Options.prnLanguage = (PrintLanguage) attrs.valueAsInt("PrintEngine", 3);
1729 	else
1730 		doc->Print_Options.prnLanguage = (PrintLanguage) attrs.valueAsInt("PSLevel", 3);
1731 	doc->Print_Options.markLength    = attrs.valueAsDouble("markLength");
1732 	doc->Print_Options.markOffset    = attrs.valueAsDouble("markOffset");
1733 	doc->Print_Options.bleeds.setTop(attrs.valueAsDouble("BleedTop"));
1734 	doc->Print_Options.bleeds.setLeft(attrs.valueAsDouble("BleedLeft"));
1735 	doc->Print_Options.bleeds.setRight(attrs.valueAsDouble("BleedRight"));
1736 	doc->Print_Options.bleeds.setBottom(attrs.valueAsDouble("BleedBottom"));
1737 	doc->Print_Options.printer  = attrs.valueAsString("printer");
1738 	doc->Print_Options.filename = attrs.valueAsString("filename");
1739 	doc->Print_Options.separationName = attrs.valueAsString("separationName");
1740 	doc->Print_Options.printerCommand = attrs.valueAsString("printerCommand");
1741 	doc->Print_Options.copies = 1;
1742 
1743 	QStringRef tagName = reader.name();
1744 	while (!reader.atEnd() && !reader.hasError())
1745 	{
1746 		ScXmlStreamReader::TokenType tType = reader.readNext();
1747 		QStringRef tName = reader.name();
1748 		if (tType == ScXmlStreamReader::StartElement && tName == "Separation")
1749 			doc->Print_Options.allSeparations.append(reader.attributes().value("Name").toString());
1750 		if (tType == ScXmlStreamReader::EndElement && tName == tagName)
1751 			break;
1752 	}
1753 	return !reader.hasError();
1754 }
1755 
readDocItemAttributes(ScribusDoc * doc,ScXmlStreamReader & reader)1756 bool Scribus134Format::readDocItemAttributes(ScribusDoc *doc, ScXmlStreamReader& reader)
1757 {
1758 	QStringRef tagName = reader.name();
1759 	doc->clearItemAttributes();
1760 	while (!reader.atEnd() && !reader.hasError())
1761 	{
1762 		reader.readNext();
1763 		if (reader.isEndElement() && reader.name() == tagName)
1764 			break;
1765 		if (reader.isStartElement() && reader.name() == "ItemAttribute")
1766 		{
1767 			ScXmlStreamAttributes attrs = reader.scAttributes();
1768 			ObjectAttribute objattr;
1769 			objattr.name  = attrs.valueAsString("Name");
1770 			objattr.type  = attrs.valueAsString("Type");
1771 			objattr.value = attrs.valueAsString("Value");
1772 			objattr.parameter      = attrs.valueAsString("Parameter");
1773 			objattr.relationship   = attrs.valueAsString("Relationship");
1774 			objattr.relationshipto = attrs.valueAsString("RelationshipTo");
1775 			objattr.autoaddto = attrs.valueAsString("AutoAddTo");
1776 			doc->appendToItemAttributes(objattr);
1777 		}
1778 	}
1779 	return !reader.hasError();
1780 }
1781 
readTableOfContents(ScribusDoc * doc,ScXmlStreamReader & reader)1782 bool Scribus134Format::readTableOfContents(ScribusDoc* doc, ScXmlStreamReader& reader)
1783 {
1784 	QStringRef tagName = reader.name();
1785 	m_Doc->clearTocSetups();
1786 	while (!reader.atEnd() && !reader.hasError())
1787 	{
1788 		reader.readNext();
1789 		if (reader.isEndElement() && reader.name() == tagName)
1790 			break;
1791 		if (reader.isStartElement() && reader.name() == "TableOfContents")
1792 		{
1793 			ScXmlStreamAttributes attrs = reader.scAttributes();
1794 			ToCSetup tocsetup;
1795 			tocsetup.name = attrs.valueAsString("Name");
1796 			tocsetup.itemAttrName = attrs.valueAsString("ItemAttributeName");
1797 			tocsetup.frameName    = attrs.valueAsString("FrameName");
1798 			tocsetup.textStyle    = attrs.valueAsString("Style");
1799 			tocsetup.listNonPrintingFrames = QVariant(attrs.valueAsString("ListNonPrinting")).toBool();
1800 			QString numberPlacement = attrs.valueAsString("NumberPlacement");
1801 			if (numberPlacement == "Beginning")
1802 				tocsetup.pageLocation = Beginning;
1803 			if (numberPlacement == "End")
1804 				tocsetup.pageLocation = End;
1805 			if (numberPlacement == "NotShown")
1806 				tocsetup.pageLocation = NotShown;
1807 			doc->appendToTocSetups(tocsetup);
1808 		}
1809 	}
1810 	return !reader.hasError();
1811 }
1812 
readSections(ScribusDoc * doc,ScXmlStreamReader & reader)1813 bool Scribus134Format::readSections(ScribusDoc* doc, ScXmlStreamReader& reader)
1814 {
1815 	QStringRef tagName = reader.name();
1816 	while (!reader.atEnd() && !reader.hasError())
1817 	{
1818 		reader.readNext();
1819 		if (reader.isEndElement() && reader.name() == tagName)
1820 			break;
1821 		if (reader.isStartElement() && reader.name() == "Section")
1822 		{
1823 			ScXmlStreamAttributes attrs = reader.scAttributes();
1824 			struct DocumentSection newSection;
1825 			newSection.number = attrs.valueAsInt("Number");
1826 			newSection.name   = attrs.valueAsString("Name");
1827 			newSection.fromindex = attrs.valueAsInt("From");
1828 			newSection.toindex   = attrs.valueAsInt("To");
1829 			QString type = attrs.valueAsString("Type");
1830 			if (type == "Type_1_2_3")
1831 				newSection.type=Type_1_2_3;
1832 			if (type == "Type_i_ii_iii")
1833 				newSection.type=Type_i_ii_iii;
1834 			if (type == "Type_I_II_III")
1835 				newSection.type=Type_I_II_III;
1836 			if (type == "Type_a_b_c")
1837 				newSection.type=Type_a_b_c;
1838 			if (type == "Type_A_B_C")
1839 				newSection.type=Type_A_B_C;
1840 			if (type == "Type_None")
1841 				newSection.type=Type_None;
1842 			newSection.sectionstartindex = attrs.valueAsInt("Start");
1843 			newSection.reversed = attrs.valueAsBool("Reversed");
1844 			newSection.active   = attrs.valueAsBool("Active");
1845 			newSection.pageNumberWidth = 0;
1846 			doc->sections().insert(newSection.number, newSection);
1847 		}
1848 	}
1849 	return !reader.hasError();
1850 }
1851 
readHyphen(ScribusDoc * doc,ScXmlStreamReader & reader)1852 bool Scribus134Format::readHyphen(ScribusDoc *doc, ScXmlStreamReader& reader)
1853 {
1854 	if (!doc->docHyphenator)
1855 		doc->createHyphenator();
1856 
1857 	QStringRef tagName = reader.name();
1858 	while (!reader.atEnd() && !reader.hasError())
1859 	{
1860 		reader.readNext();
1861 		if (reader.isEndElement() && reader.name() == tagName)
1862 			break;
1863 		if (reader.isStartElement() && reader.name() == "EXCEPTION")
1864 		{
1865 			ScXmlStreamAttributes attrs = reader.scAttributes();
1866 			QString word = attrs.valueAsString("WORD");
1867 			QString hyph = attrs.valueAsString("HYPHENATED");
1868 			doc->docHyphenator->specialWords.insert(word, hyph);
1869 		}
1870 		else if (reader.isStartElement() && reader.name() == "IGNORE")
1871 		{
1872 			ScXmlStreamAttributes attrs = reader.scAttributes();
1873 			QString word = attrs.valueAsString("WORD");
1874 			doc->docHyphenator->ignoredWords.insert(word);
1875 		}
1876 	}
1877 	return !reader.hasError();
1878 }
1879 
readPage(ScribusDoc * doc,ScXmlStreamReader & reader)1880 bool Scribus134Format::readPage(ScribusDoc* doc, ScXmlStreamReader& reader)
1881 {
1882 	QStringRef tagName = reader.name();
1883 
1884 	ScXmlStreamAttributes attrs = reader.scAttributes();
1885 	int     pageNum  = attrs.valueAsInt("NUM");
1886 	QString pageName = attrs.valueAsString("NAM", "");
1887 	if (tagName == "MASTERPAGE" && pageName.isEmpty())
1888 	{
1889 		qDebug() << "scribus134format: corrupted masterpage with empty name detected";
1890 		return true;
1891 	}
1892 	m_Doc->setMasterPageMode(!pageName.isEmpty());
1893 	ScPage* newPage = pageName.isEmpty() ? doc->addPage(pageNum) : doc->addMasterPage(pageNum, pageName);
1894 
1895 	newPage->LeftPg   = attrs.valueAsInt("LEFT", 0);
1896 	QString mpName    = attrs.valueAsString("MNAM", "Normal");
1897 	newPage->setMasterPageName(m_Doc->masterPageMode() ? QString() : mpName);
1898 	if (attrs.hasAttribute("Size"))
1899 		newPage->setSize(attrs.valueAsString("Size"));
1900 	if (attrs.hasAttribute("Orientation"))
1901 		newPage->setOrientation(attrs.valueAsInt("Orientation"));
1902 	newPage->setXOffset(attrs.valueAsDouble("PAGEXPOS"));
1903 	newPage->setYOffset(attrs.valueAsDouble("PAGEYPOS"));
1904 	if (attrs.hasAttribute("PAGEWIDTH"))
1905 		newPage->setWidth(attrs.valueAsDouble("PAGEWIDTH"));
1906 	else
1907 		newPage->setWidth(attrs.valueAsDouble("PAGEWITH"));
1908 	newPage->setHeight(attrs.valueAsDouble("PAGEHEIGHT"));
1909 	newPage->setInitialHeight(newPage->height());
1910 	newPage->setInitialWidth(newPage->width());
1911 	newPage->initialMargins.setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
1912 	newPage->initialMargins.setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
1913 	newPage->initialMargins.setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
1914 	newPage->initialMargins.setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
1915 	newPage->marginPreset   = attrs.valueAsInt("PRESET", 0);
1916 	newPage->Margins.setTop(newPage->initialMargins.top());
1917 	newPage->Margins.setBottom(newPage->initialMargins.bottom());
1918 	m_Doc->setMasterPageMode(false);
1919 	//m_Doc->Pages=&m_Doc->DocPages;
1920 	// guides reading
1921 	newPage->guides.setHorizontalAutoGap( attrs.valueAsDouble("AGhorizontalAutoGap", 0.0));
1922 	newPage->guides.setVerticalAutoGap  ( attrs.valueAsDouble("AGverticalAutoGap", 0.0));
1923 	newPage->guides.setHorizontalAutoCount( attrs.valueAsInt("AGhorizontalAutoCount", 0) );
1924 	newPage->guides.setVerticalAutoCount  ( attrs.valueAsInt("AGverticalAutoCount", 0) );
1925 	newPage->guides.setHorizontalAutoRefer( attrs.valueAsInt("AGhorizontalAutoRefer", 0) );
1926 	newPage->guides.setVerticalAutoRefer  ( attrs.valueAsInt("AGverticalAutoRefer", 0) );
1927 	GuideManagerIO::readVerticalGuides(attrs.valueAsString("VerticalGuides"),
1928 			newPage,
1929 			GuideManagerCore::Standard,
1930 			attrs.hasAttribute("NumVGuides"));
1931 	GuideManagerIO::readHorizontalGuides(attrs.valueAsString("HorizontalGuides"),
1932 			newPage,
1933 			GuideManagerCore::Standard,
1934 			attrs.hasAttribute("NumHGuides"));
1935 	GuideManagerIO::readSelection(attrs.valueAsString("AGSelection"), newPage);
1936 
1937 	newPage->guides.addHorizontals(newPage->guides.getAutoHorizontals(newPage), GuideManagerCore::Auto);
1938 	newPage->guides.addVerticals(newPage->guides.getAutoVerticals(newPage), GuideManagerCore::Auto);
1939 	return true;
1940 }
1941 
readObject(ScribusDoc * doc,ScXmlStreamReader & reader,ItemInfo & info,const QString & baseDir,bool loadPage,const QString & renamedPageName)1942 bool Scribus134Format::readObject(ScribusDoc* doc, ScXmlStreamReader& reader, ItemInfo& info, const QString& baseDir, bool loadPage, const QString& renamedPageName)
1943 {
1944 	QStringRef tagName = reader.name();
1945 	ScXmlStreamAttributes attrs = reader.scAttributes();
1946 
1947 	if (!loadPage)
1948 	{
1949 		if (tagName == "PAGEOBJECT" || tagName =="FRAMEOBJECT" || tagName =="PatternItem")
1950 			doc->setMasterPageMode(false);
1951 		else
1952 			doc->setMasterPageMode(true);
1953 	}
1954 
1955 	PageItem::ItemKind itemKind = PageItem::StandardItem;
1956 	if (tagName == "FRAMEOBJECT")
1957 		itemKind = PageItem::InlineItem;
1958 	else if (tagName == "PatternItem")
1959 		itemKind = PageItem::PatternItem;
1960 
1961 	int pagenr = -1;
1962 	QString masterPageName = attrs.valueAsString("OnMasterPage");
1963 	if ((!masterPageName.isEmpty()) && (tagName == "MASTEROBJECT"))
1964 	{
1965 		if (!renamedPageName.isEmpty())
1966 			masterPageName = renamedPageName;
1967 		doc->setCurrentPage(doc->MasterPages.at(doc->MasterNames[masterPageName]));
1968 		pagenr = -2;
1969 	}
1970 
1971 	PageItem* newItem = pasteItem(doc, attrs, baseDir, itemKind, pagenr);
1972 	newItem->setRedrawBounding();
1973 	if (tagName == "MASTEROBJECT")
1974 		newItem->setOwnerPage(doc->OnPage(newItem));
1975 	else
1976 		newItem->setOwnerPage(attrs.valueAsInt("OwnPage"));
1977 	if (tagName == "PAGEOBJECT")
1978 		newItem->setMasterPageName(QString());
1979 	QString tmpf = attrs.valueAsString("IFONT", doc->itemToolPrefs().textFont);
1980 	m_AvailableFonts->findFont(tmpf, doc);
1981 
1982 //	newItem->Language = ScMW->GetLang(pg.attribute("LANGUAGE", doc->Language));
1983 	newItem->isAutoText = attrs.valueAsBool("AUTOTEXT", false);
1984 	newItem->isEmbedded = attrs.valueAsBool("isInline", false);
1985 	newItem->gXpos   = attrs.valueAsDouble("gXpos", 0.0);
1986 	newItem->gYpos   = attrs.valueAsDouble("gYpos", 0.0);
1987 	newItem->gWidth  = attrs.valueAsDouble("gWidth", newItem->width());
1988 	newItem->gHeight = attrs.valueAsDouble("gHeight", newItem->height());
1989 	if (newItem->isAutoText)
1990 		doc->LastAuto = newItem;
1991 
1992 	if (tagName == "FRAMEOBJECT")
1993 	{
1994 		FrameItems.append(doc->Items->takeAt(doc->Items->indexOf(newItem)));
1995 		newItem->setLayer(doc->firstLayerID());
1996 	}
1997 
1998 	info.item     = newItem;
1999 	info.nextItem = attrs.valueAsInt("NEXTITEM", -1);
2000 	info.ownLink  = newItem->isTableItem ? attrs.valueAsInt("OwnLINK", 0) : 0;
2001 	info.groupLastItem = 0;
2002 	info.ownNr = doc->Items->indexOf(newItem);
2003 
2004 	info.isGroupFlag = attrs.valueAsBool("isGroupControl", false);
2005 	if (info.isGroupFlag)
2006 		info.groupLastItem = attrs.valueAsInt("groupsLastItem", 0);
2007 
2008 	bool layerFound = false;
2009 	struct ImageLoadRequest loadingInfo;
2010 	QList<ParagraphStyle::TabRecord> tabValues;
2011 
2012 	LastStyles * lastStyle = new LastStyles();
2013 	while (!reader.atEnd() && !reader.hasError())
2014 	{
2015 		ScXmlStreamReader::TokenType tType = reader.readNext();
2016 		if (reader.isEndElement() && tagName == reader.name())
2017 			break;
2018 		if (tType != ScXmlStreamReader::StartElement)
2019 			continue;
2020 		QStringRef tName = reader.name();
2021 		ScXmlStreamAttributes tAtt = reader.scAttributes();
2022 		if (tName == "CSTOP")
2023 		{
2024 			QString name = tAtt.valueAsString("NAME");
2025 			double ramp  = tAtt.valueAsDouble("RAMP", 0.0);
2026 			int shade    = tAtt.valueAsInt("SHADE", 100);
2027 			double opa   = tAtt.valueAsDouble("TRANS", 1.0);
2028 			newItem->fill_gradient.addStop(SetColor(doc, name, shade), ramp, 0.5, opa, name, shade);
2029 		}
2030 
2031 		if (tName == "ITEXT")
2032 			readItemText(newItem, tAtt, lastStyle);
2033 		else if (tName == "para")
2034 		{
2035 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PARSEP);
2036 			ParagraphStyle newStyle;
2037 //			PrefsManager& prefsManager = PrefsManager::instance();
2038 			readParagraphStyle(doc, reader, newStyle);
2039 			newItem->itemText.setStyle(newItem->itemText.length()-1, newStyle);
2040 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, lastStyle->Style);
2041 		}
2042 		else if (tName == "trail")
2043 		{
2044 			ParagraphStyle newStyle;
2045 //			PrefsManager& prefsManager = PrefsManager::instance();
2046 			readParagraphStyle(doc, reader, newStyle);
2047 			newItem->itemText.setStyle(newItem->itemText.length(), newStyle);
2048 		}
2049 		else if (tName == "tab")
2050 		{
2051 			CharStyle newStyle;
2052 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::TAB);
2053 			readCharacterStyleAttrs(doc, tAtt, newStyle);
2054 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
2055 			lastStyle->StyleStart = newItem->itemText.length()-1;
2056 			lastStyle->Style = newStyle;
2057 		}
2058 		else if (tName == "breakline")
2059 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::LINEBREAK);
2060 		else if (tName == "breakcol")
2061 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::COLBREAK);
2062 		else if (tName == "breakframe")
2063 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::FRAMEBREAK);
2064 		else if (tName == "nbhyphen")
2065 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::NBHYPHEN);
2066 		else if (tName == "nbspace")
2067 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::NBSPACE);
2068 		else if (tName == "zwnbspace")
2069 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::ZWNBSPACE);
2070 		else if (tName == "zwspace")
2071 			newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::ZWSPACE);
2072 		else if (tName == "var")
2073 		{
2074 			CharStyle newStyle;
2075 			if (tAtt.value("name") == "pgno")
2076 				newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PAGENUMBER);
2077 			else
2078 				newItem->itemText.insertChars(newItem->itemText.length(), SpecialChars::PAGECOUNT);
2079 			readCharacterStyleAttrs(doc, tAtt, newStyle);
2080 			newItem->itemText.setCharStyle(newItem->itemText.length()-1, 1, newStyle);
2081 			lastStyle->StyleStart = newItem->itemText.length()-1;
2082 			lastStyle->Style = newStyle;
2083 		}
2084 		if (tName == "PageItemAttributes")
2085 		{
2086 			readPageItemAttributes(newItem, reader);
2087 		}
2088 		if (tName == "PSDLayer")
2089 		{
2090 			layerFound = true;
2091 			loadingInfo.blend   = tAtt.valueAsString("Blend");
2092 			loadingInfo.opacity = tAtt.valueAsInt("Opacity");
2093 			loadingInfo.visible = tAtt.valueAsBool("Visible");
2094 			loadingInfo.useMask = tAtt.valueAsBool("useMask", true);
2095 			newItem->pixm.imgInfo.RequestProps.insert(tAtt.valueAsInt("Layer"), loadingInfo);
2096 		}
2097 		if (tName == "ImageEffect")
2098 		{
2099 			struct ImageEffect ef;
2100 			ef.effectParameters = tAtt.valueAsString("Param");
2101 			ef.effectCode = tAtt.valueAsInt("Code");
2102 			newItem->effectsInUse.append(ef);
2103 		}
2104 		if (tName == "Tabs")
2105 		{
2106 			ParagraphStyle::TabRecord tb;
2107 			tb.tabPosition = tAtt.valueAsDouble("Pos");
2108 			tb.tabType     = tAtt.valueAsInt("Type");
2109 			QString tbCh   = tAtt.valueAsString("Fill", "");
2110 			tb.tabFillChar = tbCh.isEmpty() ? QChar() : tbCh[0];
2111 			tabValues.append(tb);
2112 		}
2113 		if (tName == "LATEX")
2114 		{
2115 			if (newItem->isLatexFrame())
2116 			{
2117 				readLatexInfo(newItem->asLatexFrame(), reader);
2118 			}
2119 			else
2120 			{
2121 				while (!reader.atEnd() && !reader.hasError())
2122 				{
2123 					reader.readNext();
2124 					if (reader.isEndElement() && reader.name() == tName)
2125 						break;
2126 				}
2127 			}
2128 		}
2129 	}
2130 	delete lastStyle;
2131 
2132 	if (tabValues.count() > 0)
2133 	{
2134 		ParagraphStyle newDefault(newItem->itemText.defaultStyle());
2135 		newDefault.setTabValues(tabValues);
2136 		newItem->itemText.setDefaultStyle(newDefault);
2137 	}
2138 
2139 	if (newItem->fill_gradient.stops() == 0)
2140 	{
2141 		const ScColor& col1 = doc->PageColors[doc->itemToolPrefs().shapeFillColor];
2142 		const ScColor& col2 = doc->PageColors[doc->itemToolPrefs().shapeLineColor];
2143 		newItem->fill_gradient.addStop(ScColorEngine::getRGBColor(col1, doc), 0.0, 0.5, 1.0, doc->itemToolPrefs().shapeFillColor, 100);
2144 		newItem->fill_gradient.addStop(ScColorEngine::getRGBColor(col2, doc), 1.0, 0.5, 1.0, doc->itemToolPrefs().shapeLineColor, 100);
2145 	}
2146 
2147 	if (newItem->asPathText())
2148 		newItem->updatePolyClip();
2149 	if (newItem->isImageFrame() || newItem->isLatexFrame())
2150 	{
2151 		if (!newItem->Pfile.isEmpty())
2152 		{
2153 			doc->loadPict(newItem->Pfile, newItem, false);
2154 			if (layerFound)
2155 			{
2156 				newItem->pixm.imgInfo.isRequest = true;
2157 				doc->loadPict(newItem->Pfile, newItem, true);
2158 			}
2159 		}
2160 	}
2161 
2162 	if (!loadPage)
2163 		doc->setMasterPageMode(false);
2164 	return !reader.hasError();
2165 }
2166 
readPattern(ScribusDoc * doc,ScXmlStreamReader & reader,const QString & baseDir)2167 bool Scribus134Format::readPattern(ScribusDoc* doc, ScXmlStreamReader& reader, const QString& baseDir)
2168 {
2169 	ScPattern pat;
2170 	ScXmlStreamAttributes attrs = reader.scAttributes();
2171 	QString patternName = attrs.valueAsString("Name");
2172 	bool success = true;
2173 
2174 	if (patternName.isEmpty())
2175 	{
2176 		reader.readToElementEnd();
2177 		return true;
2178 	}
2179 
2180 	QStack< QList<PageItem*> > groupStack;
2181 	QStack< QList<PageItem*> > groupStackP;
2182 	QStack<int> groupStack2;
2183 	QMap<int, PageItem*> TableID2;
2184 	QList<PageItem*> TableItems2;
2185 
2186 	pat.setDoc(doc);
2187 	pat.width   = attrs.valueAsDouble("width", 0.0);
2188 	pat.height  = attrs.valueAsDouble("height", 0.0);
2189 	pat.scaleX  = attrs.valueAsDouble("scaleX", 0.0);
2190 	pat.scaleY  = attrs.valueAsDouble("scaleY", 0.0);
2191 	pat.xoffset = attrs.valueAsDouble("xoffset", 0.0);
2192 	pat.yoffset = attrs.valueAsDouble("yoffset", 0.0);
2193 
2194 	uint itemCount1 = m_Doc->Items->count();
2195 	bool savedAlignGrid = m_Doc->SnapGrid;
2196 	bool savedAlignGuides = m_Doc->SnapGuides;
2197 	bool savedMasterPageMode = m_Doc->masterPageMode();
2198 	m_Doc->SnapGrid  = false;
2199 	m_Doc->SnapGuides = false;
2200 
2201 	QStringRef tagName = reader.name();
2202 	while (!reader.atEnd() && !reader.hasError())
2203 	{
2204 		reader.readNext();
2205 		if (reader.isEndElement() && reader.name() == tagName)
2206 			break;
2207 		if (!reader.isStartElement() || reader.name() != "PatternItem")
2208 			continue;
2209 
2210 		ScXmlStreamAttributes tAtt = reader.attributes();
2211 
2212 		ItemInfo itemInfo;
2213 		m_Doc->setMasterPageMode(false);
2214 
2215 		//int ownPage = tAtt.valueAsInt("OwnPage");
2216 		success = readObject(doc, reader, itemInfo, baseDir, false);
2217 		if (!success) break;
2218 
2219 		// #11274 : OwnPage is not meaningful for pattern items
2220 		itemInfo.item->OwnPage = -1 /*ownPage*/;
2221 		itemInfo.item->OnMasterPage.clear();
2222 
2223 		if (itemInfo.item->isTableItem)
2224 		{
2225 			TableItems2.append(itemInfo.item);
2226 			TableID2.insert(itemInfo.ownLink, itemInfo.item);
2227 		}
2228 		if (groupStack.count() > 0)
2229 		{
2230 			groupStack.top().append(itemInfo.item);
2231 			while (itemInfo.ownNr == groupStack2.top())
2232 			{
2233 				groupStackP.push(groupStack.pop());
2234 				groupStack2.pop();
2235 				if (groupStack2.count() == 0)
2236 					break;
2237 			}
2238 		}
2239 		if (itemInfo.isGroupFlag)
2240 		{
2241 			QList<PageItem*> GroupItems;
2242 			GroupItems.append(itemInfo.item);
2243 			groupStack.push(GroupItems);
2244 			groupStack2.push(itemInfo.groupLastItem + itemInfo.ownNr);
2245 		}
2246 	}
2247 
2248 	doc->SnapGrid   = savedAlignGrid;
2249 	doc->SnapGuides = savedAlignGuides;
2250 	if (!success)
2251 	{
2252 		doc->setMasterPageMode(savedMasterPageMode);
2253 		return false;
2254 	}
2255 
2256 	if (TableItems2.count() != 0)
2257 	{
2258 		for (int ttc = 0; ttc < TableItems2.count(); ++ttc)
2259 		{
2260 			PageItem* ta = TableItems2.at(ttc);
2261 			if (ta->TopLinkID != -1)
2262 				ta->m_topLink = TableID2[ta->TopLinkID];
2263 			else
2264 				ta->m_topLink = nullptr;
2265 			if (ta->LeftLinkID != -1)
2266 				ta->m_leftLink = TableID2[ta->LeftLinkID];
2267 			else
2268 				ta->m_leftLink = nullptr;
2269 			if (ta->RightLinkID != -1)
2270 				ta->m_rightLink = TableID2[ta->RightLinkID];
2271 			else
2272 				ta->m_rightLink = nullptr;
2273 			if (ta->BottomLinkID != -1)
2274 				ta->m_bottomLink = TableID2[ta->BottomLinkID];
2275 			else
2276 				ta->m_bottomLink = nullptr;
2277 		}
2278 	}
2279 
2280 	while (groupStackP.count() > 0)
2281 	{
2282 		bool isTableIt = false;
2283 		QList<PageItem*> gpL = groupStackP.pop();
2284 		PageItem* gItem = gpL.takeFirst();
2285 		for (int id = 0; id < gpL.count(); id++)
2286 		{
2287 			PageItem* cItem = gpL.at(id);
2288 			isTableIt = cItem->isTableItem;
2289 			cItem->gXpos = cItem->xPos() - gItem->xPos();
2290 			cItem->gYpos = cItem->yPos() - gItem->yPos();
2291 			cItem->Parent = gItem;
2292 			if (gItem->rotation() != 0)
2293 			{
2294 				QTransform ma;
2295 				ma.rotate(-gItem->rotation());
2296 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
2297 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
2298 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
2299 				cItem->setRotation(cItem->rotation() - gItem->rotation());
2300 				cItem->oldRot = cItem->rotation();
2301 			}
2302 			m_Doc->DocItems.removeOne(cItem);
2303 		}
2304 		bool converted = false;
2305 		if (isTableIt)
2306 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
2307 		if (!converted)
2308 			gItem->groupItemList = gpL;
2309 	}
2310 
2311 	uint itemCount2 = m_Doc->Items->count();
2312 	if (itemCount2 > itemCount1)
2313 	{
2314 		PageItem* newItem;
2315 		for (uint as = itemCount1; as < itemCount2; ++as)
2316 		{
2317 			newItem = doc->Items->takeAt(itemCount1);
2318 			newItem->moveBy(pat.xoffset, pat.yoffset, true);
2319 			newItem->gXpos += pat.xoffset;
2320 			newItem->gYpos += pat.yoffset;
2321 			pat.items.append(newItem);
2322 		}
2323 		pat.createPreview();
2324 	}
2325 	doc->docPatterns.insert(patternName, pat);
2326 
2327 	doc->setMasterPageMode(savedMasterPageMode);
2328 	return success;
2329 }
2330 
readItemText(PageItem * obj,ScXmlStreamAttributes & attrs,LastStyles * last)2331 bool Scribus134Format::readItemText(PageItem *obj, ScXmlStreamAttributes& attrs, LastStyles* last)
2332 {
2333 	QString tmp2;
2334 	CharStyle newStyle;
2335 	ScribusDoc* doc = obj->doc();
2336 
2337 	readCharacterStyleAttrs(doc, attrs, newStyle);
2338 
2339 	if (attrs.hasAttribute(QLatin1String("Unicode")))
2340 	{
2341 		tmp2 = QChar(attrs.valueAsInt("Unicode"));
2342 	}
2343 	else
2344 	{
2345 		tmp2 = attrs.valueAsString("CH");
2346 
2347 		// legacy stuff:
2348 		tmp2.replace(QRegExp("\r"), QChar(13));
2349 		tmp2.replace(QRegExp("\n"), QChar(13));
2350 		tmp2.replace(QRegExp("\t"), QChar(9));
2351 	}
2352 
2353 	// more legacy stuff:
2354 	static const QString CFONT("CFONT");
2355 	if (attrs.hasAttribute(CFONT))
2356 		newStyle.setFont(m_AvailableFonts->findFont(attrs.valueAsString(CFONT), doc));
2357 
2358 	static const QString CSIZE("CSIZE");
2359 	if (attrs.hasAttribute(CSIZE))
2360 		newStyle.setFontSize(qRound(attrs.valueAsDouble(CSIZE) * 10));
2361 
2362 	static const QString CCOLOR("CCOLOR");
2363 	if (attrs.hasAttribute(CCOLOR))
2364 		newStyle.setFillColor(attrs.valueAsString(CCOLOR));
2365 
2366 	static const QString CEXTRA("CEXTRA");
2367 	if (attrs.hasAttribute(CEXTRA))
2368 		newStyle.setTracking(qRound(attrs.valueAsDouble(CEXTRA) / attrs.valueAsDouble(CSIZE) * 1000.0));
2369 	else if (attrs.hasAttribute(QLatin1String("CKERN")))
2370 		newStyle.setTracking(attrs.valueAsInt("CKERN"));
2371 
2372 	static const QString CSHADE("CSHADE");
2373 	if (attrs.hasAttribute(CSHADE))
2374 		newStyle.setFillShade(attrs.valueAsInt(CSHADE));
2375 
2376 	static const QString CSTYLE("CSTYLE");
2377 	if (attrs.hasAttribute(CSTYLE))
2378 		newStyle.setFeatures(static_cast<StyleFlag>(attrs.valueAsInt(CSTYLE)).featureList());
2379 
2380 	QString pstylename = attrs.valueAsString("PSTYLE", "");
2381 	int calign = attrs.valueAsInt("CALIGN", -1);
2382 
2383 	int ab = attrs.valueAsInt("CAB", -1);
2384 	if (ab >= 5) {
2385 		pstylename = doc->paragraphStyles()[ab-5].name();
2386 		calign = -1;
2387 	}
2388 	else if (ab >= 0) {
2389 		pstylename = "";
2390 		calign = ab;
2391 	}
2392 
2393 	static const QString CSTROKE("CSTROKE");
2394 	if (attrs.hasAttribute(CSTROKE))
2395 		newStyle.setStrokeColor(attrs.valueAsString(CSTROKE, CommonStrings::None));
2396 
2397 	static const QString CSHADE2("CSHADE2");
2398 	if (attrs.hasAttribute(CSHADE2))
2399 		newStyle.setStrokeShade(attrs.valueAsInt(CSHADE2, 100));
2400 
2401 	static const QString CSCALE("CSCALE");
2402 	if (attrs.hasAttribute(CSCALE))
2403 		newStyle.setScaleH(qMin(qMax(qRound(attrs.valueAsDouble(CSCALE, 100.0) * 10), 100), 4000));
2404 
2405 	static const QString CSCALEV("CSCALEV");
2406 	if (attrs.hasAttribute(CSCALEV))
2407 		newStyle.setScaleV(qMin(qMax(qRound(attrs.valueAsDouble(CSCALEV, 100.0) * 10), 100), 4000));
2408 
2409 	static const QString CBASE("CBASE");
2410 	if (attrs.hasAttribute(CBASE))
2411 		newStyle.setBaselineOffset(qRound(attrs.valueAsDouble(CBASE) * 10));
2412 
2413 	static const QString CSHX("CSHX");
2414 	if (attrs.hasAttribute(CSHX))
2415 		newStyle.setShadowXOffset(qRound(attrs.valueAsDouble(CSHX, 5.0) * 10));
2416 
2417 	static const QString CSHY("CSHY");
2418 	if (attrs.hasAttribute(CSHY))
2419 		newStyle.setShadowYOffset(qRound(attrs.valueAsDouble(CSHY, -5.0) * 10));
2420 
2421 	static const QString COUT("CSHY");
2422 	if (attrs.hasAttribute(COUT))
2423 		newStyle.setOutlineWidth(qRound(attrs.valueAsDouble(COUT, 1.0) * 10));
2424 
2425 	static const QString CULP("CULP");
2426 	if (attrs.hasAttribute(CULP))
2427 		newStyle.setUnderlineOffset(qRound(attrs.valueAsDouble(CULP, -0.1) * 10));
2428 
2429 	static const QString CULW("CULW");
2430 	if (attrs.hasAttribute(CULW))
2431 		newStyle.setUnderlineWidth(qRound(attrs.valueAsDouble(CULW, -0.1) * 10));
2432 
2433 	static const QString CSTP("CSTP");
2434 	if (attrs.hasAttribute(CSTP))
2435 		newStyle.setStrikethruOffset(qRound(attrs.valueAsDouble(CSTP, -0.1) * 10));
2436 
2437 	static const QString CSTW("CSTW");
2438 	if (attrs.hasAttribute(CSTW))
2439 		newStyle.setStrikethruWidth(qRound(attrs.valueAsDouble(CSTW, -0.1) * 10));
2440 
2441 	fixLegacyCharStyle(newStyle);
2442 
2443 	if (ab >= 0)
2444 		last->ParaStyle = legacyStyleMap[ab];
2445 	else
2446 		last->ParaStyle = pstylename;
2447 	// end of legacy stuff
2448 
2449 	int iobj = attrs.valueAsInt("COBJ", -1);
2450 
2451 	for (int cxx=0; cxx<tmp2.length(); ++cxx)
2452 	{
2453 		QChar ch = tmp2.at(cxx);
2454 		{ // Legacy mode
2455 			if (ch == QChar(5))
2456 				ch = SpecialChars::PARSEP;
2457 			if (ch == QChar(4))
2458 				ch = SpecialChars::TAB;
2459 		}
2460 
2461 		int pos = obj->itemText.length();
2462 		if (ch == SpecialChars::OBJECT)
2463 		{
2464 			if (iobj >= 0)
2465 			{
2466 				if (iobj < FrameItems.count())
2467 				{
2468 					int fIndex = doc->addToInlineFrames(FrameItems.at(iobj));
2469 					obj->itemText.insertObject(pos, fIndex);
2470 				}
2471 				else
2472 					qDebug() << QString("scribus134format: invalid inline frame used in text object : %1").arg(iobj);
2473 			}
2474 		}
2475 		else if (ch == SpecialChars::SHYPHEN && pos > 0)
2476 		{
2477 //			qDebug() << QString("scribus134format: SHYPHEN at %1").arg(pos);
2478 			// double SHY means user provided SHY, single SHY is automatic one
2479 			if (obj->itemText.hasFlag(pos-1, ScLayout_HyphenationPossible))
2480 			{
2481 				obj->itemText.clearFlag(pos-1, ScLayout_HyphenationPossible);
2482 				obj->itemText.insertChars(pos, QString(ch));
2483 			}
2484 			else
2485 			{
2486 				obj->itemText.setFlag(pos-1, ScLayout_HyphenationPossible);
2487 			}
2488 		}
2489 		else {
2490 			obj->itemText.insertChars(pos, QString(ch));
2491 		}
2492 //		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);
2493 		if (newStyle != last->Style) // || (newStyle.effects() ^ last->Style.effects()) == ScStyle_HyphenationPossible)
2494 		{  // FIXME StyleFlag operator== ignores hyphen flag
2495 //			qDebug() << QString("new style at %1: %2 -> %3").arg(pos).arg(last->Style.asString()).arg(newStyle.asString());
2496 			obj->itemText.setCharStyle(last->StyleStart, pos-last->StyleStart, last->Style);
2497 			last->Style = newStyle;
2498 			last->StyleStart = pos;
2499 		}
2500 		if (ch == SpecialChars::PARSEP) {
2501 			ParagraphStyle pstyle;
2502 			// Qt4 if (last->ParaStyle >= 0) {
2503 			if (!last->ParaStyle.isEmpty()) {
2504 				pstyle.setParent( last->ParaStyle );
2505 			}
2506 			if (calign >= 0)
2507 				pstyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(calign));
2508 //			qDebug() << QString("par style at %1: %2/%3 (%4) calign %5").arg(pos).arg(pstyle.name()).arg(pstyle.parent()).arg(last->ParaStyle).arg(calign);
2509 			obj->itemText.applyStyle(pos, pstyle);
2510 		}
2511 	}
2512 
2513 	obj->itemText.setCharStyle(last->StyleStart, obj->itemText.length()-last->StyleStart, last->Style);
2514 	last->StyleStart = obj->itemText.length();
2515 /*
2516 	QString dbg("");
2517 	for (int i=0; i < obj->itemText.length(); ++i)
2518 	{
2519 		dbg += obj->itemText.text(i,1);
2520 		if (obj->itemText.item(i)->effects() & ScStyle_HyphenationPossible)
2521 			dbg += "~";
2522 	}
2523 	qDebug("scribus134format: read itemtext %d '%s'", obj->itemText.length(), dbg.latin1());
2524 	*/
2525 	ParagraphStyle pstyle;
2526 
2527 	if (!last->ParaStyle.isEmpty()) { // Qt4 >= 0) {
2528 		pstyle.setParent( last->ParaStyle );
2529 		obj->itemText.applyStyle(obj->itemText.length()-1, pstyle);
2530 	}
2531 	if (calign >= 0) {
2532 		pstyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(calign));
2533 		obj->itemText.applyStyle(obj->itemText.length()-1, pstyle);
2534 	}
2535 
2536 	return true;
2537 }
2538 
readPageItemAttributes(PageItem * item,ScXmlStreamReader & reader)2539 bool Scribus134Format::readPageItemAttributes(PageItem* item, ScXmlStreamReader& reader)
2540 {
2541 	QStringRef tagName = reader.name();
2542 	ObjAttrVector pageItemAttributes;
2543 	while (!reader.atEnd() && !reader.hasError())
2544 	{
2545 		reader.readNext();
2546 		if (reader.isEndElement() && reader.name() == tagName)
2547 			break;
2548 		if (reader.isStartElement() && reader.name() == "ItemAttribute")
2549 		{
2550 			ScXmlStreamAttributes tAtt = reader.scAttributes();
2551 			ObjectAttribute objattr;
2552 			objattr.name  = tAtt.valueAsString("Name");
2553 			objattr.type  = tAtt.valueAsString("Type");
2554 			objattr.value = tAtt.valueAsString("Value");
2555 			objattr.parameter = tAtt.valueAsString("Parameter");
2556 			objattr.relationship   = tAtt.valueAsString("Relationship");
2557 			objattr.relationshipto = tAtt.valueAsString("RelationshipTo");
2558 			objattr.autoaddto = tAtt.valueAsString("AutoAddTo");
2559 			pageItemAttributes.append(objattr);
2560 		}
2561 	}
2562 	item->setObjectAttributes(&pageItemAttributes);
2563 	return !reader.hasError();
2564 }
2565 
pasteItem(ScribusDoc * doc,ScXmlStreamAttributes & attrs,const QString & baseDir,PageItem::ItemKind itemKind,int pagenr)2566 PageItem* Scribus134Format::pasteItem(ScribusDoc *doc, ScXmlStreamAttributes& attrs, const QString& baseDir, PageItem::ItemKind itemKind, int pagenr)
2567 {
2568 	int z = 0;
2569 	struct ImageLoadRequest loadingInfo;
2570 	PageItem::ItemType pt = static_cast<PageItem::ItemType>(attrs.valueAsInt("PTYPE"));
2571 	bool isGroupFlag = attrs.valueAsBool("isGroupControl", false);
2572 	if (isGroupFlag)
2573 		pt = PageItem::Group;
2574 	double x   = attrs.valueAsDouble("XPOS");
2575 	double y   = attrs.valueAsDouble("YPOS");
2576 	double w   = attrs.valueAsDouble("WIDTH");
2577 	double h   = attrs.valueAsDouble("HEIGHT");
2578 	double pw  = attrs.valueAsDouble("PWIDTH");
2579 	double scx = attrs.valueAsDouble("LOCALSCX");
2580 	double scy = attrs.valueAsDouble("LOCALSCY");
2581 	QString Pcolor = attrs.valueAsString("PCOLOR");
2582 	if (Pcolor.isEmpty())
2583 		Pcolor = CommonStrings::None;
2584 	QString Pcolor2 = attrs.valueAsString("PCOLOR2");
2585 	if (Pcolor2.isEmpty())
2586 		Pcolor2 = CommonStrings::None;
2587 	QColor tmpc;
2588 	PageItem *currItem=nullptr;
2589 	QString tmp;
2590 	double xf, yf, xf2;
2591 	QString clPath;
2592 
2593 	switch (pt)
2594 	{
2595 	// OBSOLETE CR 2005-02-06
2596 	case PageItem::ItemType1:
2597 		z = doc->itemAdd(PageItem::Polygon, PageItem::Ellipse, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
2598 		currItem = doc->Items->at(z);
2599 		if (pagenr > -2)
2600 			currItem->OwnPage = pagenr;
2601 		break;
2602 	//
2603 	case PageItem::ImageFrame:
2604 	case PageItem::OSGFrame:
2605 	case PageItem::LatexFrame: /*Everything that is valid for image frames is also valid for latex frames*/
2606 		z = doc->itemAdd(pt, PageItem::Unspecified, x, y, w, h, 1, doc->itemToolPrefs().imageFillColor, CommonStrings::None, itemKind);
2607 		currItem = doc->Items->at(z);
2608 		if (pagenr > -2)
2609 			currItem->OwnPage = pagenr;
2610 		UndoManager::instance()->setUndoEnabled(false);
2611 		currItem->ScaleType   = attrs.valueAsInt("SCALETYPE", 1);
2612 		currItem->AspectRatio = attrs.valueAsInt("RATIO", 0);
2613 		currItem->setImageXYScale(scx, scy);
2614 		currItem->setImageXYOffset(attrs.valueAsDouble("LOCALX"), attrs.valueAsDouble("LOCALY"));
2615 		currItem->setImageRotation(attrs.valueAsDouble("LOCALROT", 0));
2616 		if (!currItem->isLatexFrame())
2617 		{
2618 			bool inlineF = attrs.valueAsBool("isInlineImage", false);
2619 			QString dat  = attrs.valueAsString("ImageData", "");
2620 			QByteArray inlineImageData;
2621 			inlineImageData.append(dat.toUtf8());
2622 			QString inlineImageExt = attrs.valueAsString("inlineImageExt", "");
2623 			if (inlineF)
2624 			{
2625 				if (inlineImageData.size() > 0)
2626 				{
2627 					QTemporaryFile *tempFile = new QTemporaryFile(QDir::tempPath() + "/scribus_temp_XXXXXX." + inlineImageExt);
2628 					tempFile->setAutoRemove(false);
2629 					tempFile->open();
2630 					QString fileName = getLongPathName(tempFile->fileName());
2631 					tempFile->close();
2632 					inlineImageData = qUncompress(QByteArray::fromBase64(inlineImageData));
2633 					QFile outFil(fileName);
2634 					if (outFil.open(QIODevice::WriteOnly))
2635 					{
2636 						outFil.write(inlineImageData);
2637 						outFil.close();
2638 						currItem->isInlineImage = true;
2639 						currItem->Pfile = QDir::fromNativeSeparators(fileName);
2640 						currItem->isTempFile = true;
2641 					}
2642 					delete tempFile;
2643 				}
2644 			}
2645 			else
2646 			{
2647 				currItem->Pfile = Relative2Path(attrs.valueAsString("PFILE"), baseDir);
2648 				currItem->Pfile = QDir::fromNativeSeparators(currItem->Pfile);
2649 			}
2650 		}
2651 		currItem->ImageProfile    = attrs.valueAsString("PRFILE", "");
2652 		currItem->ImageIntent     = (eRenderIntent) attrs.valueAsInt("IRENDER", 1);
2653 		currItem->EmbeddedProfile = attrs.valueAsString("EPROF" , "");
2654 		currItem->UseEmbedded = attrs.valueAsInt("EMBEDDED", 1);
2655 		currItem->pixm.imgInfo.lowResType = attrs.valueAsInt("ImageRes", 1);
2656 		currItem->pixm.imgInfo.actualPageNumber = attrs.valueAsInt("Pagenumber", 0);
2657 		if (currItem->isLatexFrame())
2658 		{
2659 			currItem->setImageXYOffset(attrs.valueAsDouble("LOCALX") * scx, attrs.valueAsDouble("LOCALY") * scy);
2660 	//		currItem->setImageXYScale(1.0, 1.0);
2661 		}
2662 		else
2663 			currItem->setImageXYScale(scx, scy);
2664 		currItem->setImageRotation(attrs.valueAsDouble("LOCALROT", 0));
2665 		clPath = attrs.valueAsString("ImageClip", "");
2666 		if (currItem->pixm.imgInfo.PDSpathData.contains(clPath))
2667 		{
2668 			currItem->imageClip = currItem->pixm.imgInfo.PDSpathData[clPath].copy();
2669 			currItem->pixm.imgInfo.usedPath = clPath;
2670 			QTransform cl;
2671 			cl.translate(currItem->imageXOffset()*currItem->imageXScale(), currItem->imageYOffset()*currItem->imageYScale());
2672 			cl.scale(currItem->imageXScale(), currItem->imageYScale());
2673 			currItem->imageClip.map(cl);
2674 		}
2675 		currItem->setImageVisible( attrs.valueAsInt("PICART"));
2676 /*		currItem->BBoxX = ScCLocale::toDoubleC( obj->attribute("BBOXX"));
2677 		currItem->BBoxH = ScCLocale::toDoubleC( obj->attribute("BBOXH")); */
2678 		currItem->setLineWidth(pw);
2679 		UndoManager::instance()->setUndoEnabled(true);
2680 		break;
2681 	// OBSOLETE CR 2005-02-06
2682 	case PageItem::ItemType3:
2683 		z = doc->itemAdd(PageItem::Polygon, PageItem::Rectangle, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
2684 		currItem = doc->Items->at(z);
2685 		if (pagenr > -2)
2686 			currItem->setOwnerPage(pagenr);
2687 		break;
2688 	//
2689 	case PageItem::PathText:
2690 		z = doc->itemAdd(PageItem::PathText, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, itemKind);
2691 		currItem = doc->Items->at(z);
2692 		if (pagenr > -2)
2693 			currItem->setOwnerPage(pagenr);
2694 		break;
2695 	case PageItem::TextFrame:
2696 		z = doc->itemAdd(PageItem::TextFrame, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor, itemKind);
2697 		currItem = doc->Items->at(z);
2698 		if (pagenr > -2)
2699 			currItem->setOwnerPage(pagenr);
2700 		break;
2701 	case PageItem::Line:
2702 		z = doc->itemAdd(PageItem::Line, PageItem::Unspecified, x, y, w, h, pw, CommonStrings::None, Pcolor2, itemKind);
2703 		currItem = doc->Items->at(z);
2704 		if (pagenr > -2)
2705 			currItem->setOwnerPage(pagenr);
2706 		break;
2707 	case PageItem::Polygon:
2708 		z = doc->itemAdd(PageItem::Polygon, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
2709 		currItem = doc->Items->at(z);
2710 		if (pagenr > -2)
2711 			currItem->setOwnerPage(pagenr);
2712 		break;
2713 	case PageItem::PolyLine:
2714 		z = doc->itemAdd(PageItem::PolyLine, PageItem::Unspecified, x, y, w, h, pw, Pcolor, Pcolor2, itemKind);
2715 		currItem = doc->Items->at(z);
2716 		if (pagenr > -2)
2717 			currItem->setOwnerPage(pagenr);
2718 		break;
2719 	case PageItem::Group:
2720 		z = doc->itemAdd(PageItem::Group, PageItem::Unspecified, x, y, w, h, 0, CommonStrings::None, CommonStrings::None, itemKind);
2721 		currItem = doc->Items->at(z);
2722 		if (pagenr > -2)
2723 			currItem->setOwnerPage(pagenr);
2724 		currItem->groupWidth = attrs.valueAsDouble("groupWidth", w);
2725 		currItem->groupHeight = attrs.valueAsDouble("groupHeight", h);
2726 		doc->GroupCounter++;
2727 		break;
2728 	case PageItem::Symbol:
2729 	case PageItem::RegularPolygon:
2730 	case PageItem::Arc:
2731 	case PageItem::Spiral:
2732 	case PageItem::Multiple:
2733 	case PageItem::Table:
2734 	case PageItem::NoteFrame:
2735 		Q_ASSERT(false);
2736 		break;
2737 	}
2738 
2739 	UndoManager::instance()->setUndoEnabled(false);
2740 	currItem->FrameType = attrs.valueAsInt("FRTYPE", 0);
2741 	int startArrowIndex = attrs.valueAsInt("startArrowIndex", 0);
2742 	if ((startArrowIndex < 0) || (startArrowIndex > static_cast<int>(doc->arrowStyles().size())))
2743 	{
2744 		qDebug() << QString("scribus134format: invalid arrow index: %").arg(startArrowIndex);
2745 		startArrowIndex = 0;
2746 	}
2747 	currItem->setStartArrowIndex(startArrowIndex);
2748 	int endArrowIndex = attrs.valueAsInt("endArrowIndex", 0);
2749 	if ((endArrowIndex < 0) || (endArrowIndex > static_cast<int>(doc->arrowStyles().size())))
2750 	{
2751 		qDebug() << QString("scribus134format: invalid arrow index: %").arg(endArrowIndex);
2752 		endArrowIndex = 0;
2753 	}
2754 	currItem->setEndArrowIndex(endArrowIndex);
2755 	currItem->setStartArrowScale(attrs.valueAsInt("startArrowScale", 100));
2756 	currItem->setEndArrowScale(attrs.valueAsInt("endArrowScale", 100));
2757 	currItem->NamedLStyle = attrs.valueAsString("NAMEDLST", "");
2758 	currItem->isBookmark  = attrs.valueAsInt("BOOKMARK");
2759 	currItem->setImageFlippedH( attrs.valueAsInt("FLIPPEDH"));
2760 	currItem->setImageFlippedV( attrs.valueAsInt("FLIPPEDV"));
2761 	currItem->setCornerRadius( attrs.valueAsDouble("RADRECT", 0.0));
2762 	currItem->ClipEdited = attrs.valueAsInt("CLIPEDIT", 0);
2763 	currItem->setFillColor(Pcolor);
2764 	currItem->setLineColor(Pcolor2);
2765 	currItem->setFillShade(attrs.valueAsInt("SHADE"));
2766 	currItem->setLineShade(attrs.valueAsInt("SHADE2"));
2767 
2768 	ParagraphStyle pstyle;
2769 	if (attrs.hasAttribute("LINESP"))
2770 		pstyle.setLineSpacing(attrs.valueAsDouble("LINESP"));
2771 	if (attrs.hasAttribute("LINESPMode"))
2772 		pstyle.setLineSpacingMode(static_cast<ParagraphStyle::LineSpacingMode>(attrs.valueAsInt("LINESPMode", 0)));
2773 	if (attrs.hasAttribute("ALIGN"))
2774 		pstyle.setAlignment(static_cast<ParagraphStyle::AlignmentType>(attrs.valueAsInt("ALIGN", 0)));
2775 	if (attrs.valueAsBool("REVERS"))
2776 		pstyle.setDirection(ParagraphStyle::RTL);
2777 	if (attrs.hasAttribute("IFONT"))
2778 		pstyle.charStyle().setFont(m_AvailableFonts->findFont(attrs.valueAsString("IFONT"), doc));
2779 	if (attrs.hasAttribute("ISIZE"))
2780 		pstyle.charStyle().setFontSize(qRound(attrs.valueAsDouble("ISIZE") * 10));
2781 	if (attrs.hasAttribute("TXTSTROKE"))
2782 		pstyle.charStyle().setStrokeColor(attrs.valueAsString("TXTSTROKE"));
2783 	if (attrs.hasAttribute("TXTFILL"))
2784 		pstyle.charStyle().setFillColor(attrs.valueAsString("TXTFILL"));
2785 	if (attrs.hasAttribute("TXTSTRSH"))
2786 		pstyle.charStyle().setStrokeShade(attrs.valueAsInt("TXTSTRSH"));
2787 	if (attrs.hasAttribute("TXTFILLSH"))
2788 		pstyle.charStyle().setFillShade(attrs.valueAsInt("TXTFILLSH"));
2789 	if (attrs.hasAttribute("TXTSCALE"))
2790 		pstyle.charStyle().setScaleH(qRound(attrs.valueAsDouble("TXTSCALE") * 10));
2791 	if (attrs.hasAttribute("TXTSCALEV"))
2792 		pstyle.charStyle().setScaleV(qRound(attrs.valueAsDouble("TXTSCALEV") * 10));
2793 	if (attrs.hasAttribute("TXTBASE"))
2794 		pstyle.charStyle().setBaselineOffset(qRound(attrs.valueAsDouble("TXTBASE") * 10));
2795 	if (attrs.hasAttribute("TXTSHX"))
2796 		pstyle.charStyle().setShadowXOffset(qRound(attrs.valueAsDouble("TXTSHX") * 10));
2797 	if (attrs.hasAttribute("TXTSHY"))
2798 		pstyle.charStyle().setShadowYOffset(qRound(attrs.valueAsDouble("TXTSHY") * 10));
2799 	if (attrs.hasAttribute("TXTOUT"))
2800 		pstyle.charStyle().setOutlineWidth(qRound(attrs.valueAsDouble("TXTOUT") * 10));
2801 	if (attrs.hasAttribute("TXTULP"))
2802 		pstyle.charStyle().setUnderlineOffset(qRound(attrs.valueAsDouble("TXTULP") * 10));
2803 	if (attrs.hasAttribute("TXTULW"))
2804 		pstyle.charStyle().setUnderlineWidth(qRound(attrs.valueAsDouble("TXTULW") * 10));
2805 	if (attrs.hasAttribute("TXTSTP"))
2806 		pstyle.charStyle().setStrikethruOffset(qRound(attrs.valueAsDouble("TXTSTP") * 10));
2807 	if (attrs.hasAttribute("TXTSTW"))
2808 		pstyle.charStyle().setStrikethruWidth(qRound(attrs.valueAsDouble("TXTSTW") * 10));
2809 	if (attrs.hasAttribute("TXTSTYLE")) // Pre 1.4.x attribute, not used in 1.4.x
2810 		pstyle.charStyle().setFeatures(static_cast<StyleFlag>(attrs.valueAsInt("TXTSTYLE")).featureList());
2811 	if (attrs.hasAttribute("TXTFEATURES")) // Added to fix issue #13355
2812 		pstyle.charStyle().setFeatures(attrs.valueAsString("TXTFEATURES").split(" ", Qt::SkipEmptyParts));
2813 	if (attrs.hasAttribute("TXTKERN"))
2814 		pstyle.charStyle().setTracking(qRound(attrs.valueAsDouble("TXTKERN", 0.0) * 10));
2815 	if (attrs.hasAttribute("wordTrack"))
2816 		pstyle.charStyle().setWordTracking(attrs.valueAsDouble("wordTrack"));
2817 	if (attrs.hasAttribute("MinWordTrack"))
2818 		pstyle.setMinWordTracking(attrs.valueAsDouble("MinWordTrack"));
2819 	if (attrs.hasAttribute("MinGlyphShrink"))
2820 		pstyle.setMinGlyphExtension(attrs.valueAsDouble("MinGlyphShrink"));
2821 	if (attrs.hasAttribute("MaxGlyphExtend"))
2822 		pstyle.setMaxGlyphExtension(attrs.valueAsDouble("MaxGlyphExtend"));
2823 	if (attrs.hasAttribute("OpticalMargins"))
2824 		pstyle.setOpticalMargins(attrs.valueAsInt("OpticalMargins"));
2825 	if (attrs.hasAttribute("HyphenationMode"))
2826 		pstyle.setHyphenationMode(attrs.valueAsInt("HyphenationMode"));
2827 	if (attrs.hasAttribute("leftMargin"))
2828 		pstyle.setLeftMargin(attrs.valueAsDouble("leftMargin"));
2829 	if (attrs.hasAttribute("rightMargin"))
2830 		pstyle.setRightMargin(attrs.valueAsDouble("rightMargin"));
2831 	if (attrs.hasAttribute("firstIndent"))
2832 		pstyle.setFirstIndent(attrs.valueAsDouble("firstIndent"));
2833 	currItem->itemText.setDefaultStyle(pstyle);
2834 
2835 	if (attrs.hasAttribute("PSTYLE"))
2836 	{
2837 		QString pstyleName = attrs.valueAsString("PSTYLE");
2838 		if (!pstyleName.isEmpty())
2839 		{
2840 			ParagraphStyle defStyle(currItem->itemText.defaultStyle());
2841 			defStyle.setParent(pstyleName);
2842 			currItem->itemText.setDefaultStyle(defStyle);
2843 		}
2844 	}
2845 
2846 	currItem->setRotation( attrs.valueAsDouble("ROT") );
2847 	currItem->oldRot = currItem->rotation();
2848 	currItem->setTextToFrameDist(attrs.valueAsDouble("EXTRA"),
2849 								attrs.valueAsDouble("REXTRA", 1.0),
2850 								attrs.valueAsDouble("TEXTRA", 1.0),
2851 								attrs.valueAsDouble("BEXTRA", 1.0));
2852 	currItem->setFirstLineOffset(static_cast<FirstLineOffsetPolicy>(attrs.valueAsInt("FLOP")));
2853 
2854 	currItem->PLineArt  = Qt::PenStyle(attrs.valueAsInt("PLINEART"));
2855 	currItem->PLineEnd  = Qt::PenCapStyle(attrs.valueAsInt("PLINEEND", 0));
2856 	currItem->PLineJoin = Qt::PenJoinStyle(attrs.valueAsInt("PLINEJOIN", 0));
2857 	currItem->setPrintEnabled( attrs.valueAsInt("PRINTABLE"));
2858 	currItem->setIsAnnotation( attrs.valueAsInt("ANNOTATION", 0));
2859 	currItem->annotation().setType( attrs.valueAsInt("ANTYPE", 0));
2860 	QString itemName = attrs.valueAsString("ANNAME","");
2861 	if (!itemName.isEmpty())
2862 	{
2863 		if (currItem->itemName() == itemName)
2864 			currItem->AutoName = true;
2865 		else
2866 			currItem->setItemName(itemName);
2867 	}
2868 	currItem->annotation().setAction( attrs.valueAsString("ANACTION","") );
2869 	currItem->annotation().setE_act ( attrs.valueAsString("ANEACT","") );
2870 	currItem->annotation().setX_act ( attrs.valueAsString("ANXACT","") );
2871 	currItem->annotation().setD_act ( attrs.valueAsString("ANDACT","") );
2872 	currItem->annotation().setFo_act( attrs.valueAsString("ANFOACT","") );
2873 	currItem->annotation().setBl_act( attrs.valueAsString("ANBLACT","") );
2874 	currItem->annotation().setK_act ( attrs.valueAsString("ANKACT","") );
2875 	currItem->annotation().setF_act ( attrs.valueAsString("ANFACT","") );
2876 	currItem->annotation().setV_act ( attrs.valueAsString("ANVACT","") );
2877 	currItem->annotation().setC_act ( attrs.valueAsString("ANCACT","") );
2878 	currItem->annotation().setActionType(attrs.valueAsInt("ANACTYP", 0));
2879 	currItem->annotation().setExtern( attrs.valueAsString("ANEXTERN",""));
2880 	if ((!currItem->annotation().Extern().isEmpty()) && (currItem->annotation().ActionType() != 8))
2881 		currItem->annotation().setExtern(Relative2Path(attrs.valueAsString("ANEXTERN", "") , baseDir));
2882 	currItem->annotation().setZiel( attrs.valueAsInt("ANZIEL", 0));
2883 	currItem->annotation().setToolTip ( attrs.valueAsString("ANTOOLTIP",""));
2884 	currItem->annotation().setRollOver( attrs.valueAsString("ANROLL",""));
2885 	currItem->annotation().setDown( attrs.valueAsString("ANDOWN",""));
2886 	currItem->annotation().setBorderWidth( attrs.valueAsInt("ANBWID", 1));
2887 	currItem->annotation().setBorderStyle( attrs.valueAsInt("ANBSTY", 0));
2888 	currItem->annotation().setFeed( attrs.valueAsInt("ANFEED", 1));
2889 	currItem->annotation().setFlag( attrs.valueAsInt("ANFLAG", 0));
2890 	currItem->annotation().setFont( attrs.valueAsInt("ANFONT", 4));
2891 	currItem->annotation().setFormat( attrs.valueAsInt("ANFORMAT", 0));
2892 	currItem->annotation().setVis( attrs.valueAsInt("ANVIS", 0));
2893 	currItem->annotation().setIsChk( attrs.valueAsBool("ANCHK", false) );
2894 	currItem->annotation().setCheckState(currItem->annotation().IsChk());
2895 	currItem->annotation().setAAact( attrs.valueAsBool("ANAA", false) );
2896 	currItem->annotation().setHTML ( attrs.valueAsInt("ANHTML", 0));
2897 	currItem->annotation().setUseIcons( attrs.valueAsBool("ANICON", false));
2898 	currItem->annotation().setChkStil ( attrs.valueAsInt("ANCHKS", 0));
2899 	currItem->annotation().setMaxChar ( attrs.valueAsInt("ANMC", -1));
2900 	currItem->annotation().setBorderColor( attrs.valueAsString("ANBCOL", CommonStrings::None));
2901 	currItem->annotation().setIPlace(attrs.valueAsInt("ANPLACE", 1));
2902 	currItem->annotation().setScaleW(attrs.valueAsInt("ANSCALE", 0));
2903 
2904 	if (currItem->isTextFrame() || currItem->isPathText())
2905 	{
2906 		UndoManager::instance()->setUndoEnabled(false);
2907 		if (currItem->isAnnotation() && currItem->annotation().UseIcons())
2908 		{
2909 			currItem->ScaleType   = attrs.valueAsInt("SCALETYPE", 1);
2910 			currItem->AspectRatio = attrs.valueAsInt("RATIO", 0);
2911 			currItem->setImageXYScale(scx, scy);
2912 			currItem->setImageXYOffset(attrs.valueAsDouble("LOCALX"), attrs.valueAsDouble("LOCALY"));
2913 			currItem->setImageRotation(attrs.valueAsDouble("LOCALROT", 0));
2914 			currItem->Pfile  = Relative2Path(attrs.valueAsString("PFILE" , ""), baseDir);
2915 			currItem->Pfile2 = Relative2Path(attrs.valueAsString("PFILE2", ""), baseDir);
2916 			currItem->Pfile3 = Relative2Path(attrs.valueAsString("PFILE3", ""), baseDir);
2917 			currItem->Pfile  = QDir::fromNativeSeparators(currItem->Pfile);
2918 			currItem->Pfile2 = QDir::fromNativeSeparators(currItem->Pfile2);
2919 			currItem->Pfile3 = QDir::fromNativeSeparators(currItem->Pfile3);
2920 			currItem->ImageProfile    = attrs.valueAsString("PRFILE", "");
2921 			currItem->ImageIntent     = (eRenderIntent) attrs.valueAsInt("IRENDER" , 1);
2922 			currItem->EmbeddedProfile = attrs.valueAsString("EPROF", "");
2923 			currItem->UseEmbedded = attrs.valueAsInt("EMBEDDED", 1);
2924 			doc->loadPict(currItem->Pfile, currItem);
2925 			currItem->setImageXYScale(scx, scy);
2926 			currItem->setImageVisible( attrs.valueAsInt("PICART"));
2927 /*			currItem->BBoxX = ScCLocale::toDoubleC( obj->attribute("BBOXX"));
2928 			currItem->BBoxH = ScCLocale::toDoubleC( obj->attribute("BBOXH")); */
2929 		}
2930 		UndoManager::instance()->setUndoEnabled(true);
2931 	}
2932 
2933 	currItem->TopLine      = attrs.valueAsBool("TopLine", false);
2934 	currItem->LeftLine     = attrs.valueAsBool("LeftLine", false);
2935 	currItem->RightLine    = attrs.valueAsBool("RightLine", false);
2936 	currItem->BottomLine   = attrs.valueAsBool("BottomLine", false);
2937 	currItem->isTableItem  = attrs.valueAsBool("isTableItem", false);
2938 	currItem->TopLinkID    = attrs.valueAsInt("TopLINK", -1);
2939 	currItem->LeftLinkID   = attrs.valueAsInt("LeftLINK", -1);
2940 	currItem->RightLinkID  = attrs.valueAsInt("RightLINK", -1);
2941 	currItem->BottomLinkID = attrs.valueAsInt("BottomLINK", -1);
2942 	currItem->PoShow       = attrs.valueAsInt("PLTSHOW", 0);
2943 	currItem->BaseOffs     = attrs.valueAsDouble("BASEOF", 0.0);
2944 	currItem->textPathType =  attrs.valueAsInt("textPathType", 0);
2945 	currItem->textPathFlipped = attrs.valueAsBool("textPathFlipped", false);
2946 	if ( attrs.hasAttribute("TEXTFLOWMODE") )
2947 		currItem->setTextFlowMode((PageItem::TextFlowMode) attrs.valueAsInt("TEXTFLOWMODE", 0));
2948 	else if ( attrs.valueAsInt("TEXTFLOW") )
2949 	{
2950 		if (attrs.valueAsInt("TEXTFLOW2", 0))
2951 			currItem->setTextFlowMode(PageItem::TextFlowUsesBoundingBox);
2952 		else if (attrs.valueAsInt("TEXTFLOW3", 0))
2953 			currItem->setTextFlowMode(PageItem::TextFlowUsesContourLine);
2954 		else
2955 			currItem->setTextFlowMode(PageItem::TextFlowUsesFrameShape);
2956 	}
2957 	else
2958 		currItem->setTextFlowMode(PageItem::TextFlowDisabled);
2959 	currItem->DashOffset = attrs.valueAsDouble("DASHOFF", 0.0);
2960 	currItem->setLocked (attrs.valueAsBool("LOCK", false));
2961 	currItem->setSizeLocked(attrs.valueAsBool("LOCKR", false));
2962 	currItem->setFillTransparency(attrs.valueAsDouble("TransValue", 0.0));
2963 	currItem->setLineTransparency(attrs.valueAsDouble("TransValueS", 0.0));
2964 	currItem->fillRule    = attrs.valueAsBool("fillRule", true);
2965 	currItem->doOverprint = attrs.valueAsBool("doOverprint", false);
2966 	currItem->setFillBlendmode(attrs.valueAsInt("TransBlend", 0));
2967 	currItem->setLineBlendmode(attrs.valueAsInt("TransBlendS", 0));
2968 	if (attrs.valueAsInt("TRANSPARENT", 0) == 1)
2969 		currItem->setFillColor(CommonStrings::None);
2970 	currItem->m_columns   = attrs.valueAsInt("COLUMNS", 1);
2971 	currItem->m_columnGap = attrs.valueAsDouble("COLGAP", 0.0);
2972 	if (attrs.valueAsInt("LAYER", 0) != -1)
2973 		currItem->setLayer(attrs.valueAsInt("LAYER", 0));
2974 	tmp = "";
2975 
2976 	QList<ParagraphStyle::TabRecord> tbs;
2977 	tmp = "";
2978 	if ((attrs.hasAttribute("NUMTAB")) && (attrs.valueAsInt("NUMTAB", 0) != 0))
2979 	{
2980 		ParagraphStyle::TabRecord tb;
2981 		tmp = attrs.valueAsString("TABS");
2982 		ScTextStream tgv(&tmp, QIODevice::ReadOnly);
2983 		int numTab = attrs.valueAsInt("NUMTAB", 0);
2984 		for (int cxv = 0; cxv < numTab; cxv += 2)
2985 		{
2986 			tgv >> xf;
2987 			tgv >> xf2;
2988 			tb.tabPosition = xf2;
2989 			tb.tabType = static_cast<int>(xf);
2990 			tb.tabFillChar = QChar();
2991 			tbs.append(tb);
2992 		}
2993 		tmp = "";
2994 	}
2995 	if (tbs.count() > 0) {
2996 		ParagraphStyle newDefault(currItem->itemText.defaultStyle());
2997 		newDefault.setTabValues(tbs);
2998 		currItem->itemText.setDefaultStyle(newDefault);
2999 	}
3000 
3001 	if ((attrs.hasAttribute("NUMDASH")) && (attrs.valueAsInt("NUMDASH", 0) != 0))
3002 	{
3003 		tmp = attrs.valueAsString("DASHS");
3004 		ScTextStream dgv(&tmp, QIODevice::ReadOnly);
3005 		currItem->DashValues.clear();
3006 		int numDash = attrs.valueAsInt("NUMDASH", 0);
3007 		for (int cxv = 0; cxv < numDash; ++cxv)
3008 		{
3009 			dgv >> xf;
3010 			currItem->DashValues.append(xf);
3011 		}
3012 		tmp = "";
3013 	}
3014 	else
3015 		currItem->DashValues.clear();
3016 
3017 	tmp = "";
3018 	if (attrs.hasAttribute("NUMPO"))
3019 	{
3020 		currItem->PoLine.resize(attrs.valueAsUInt("NUMPO"));
3021 		tmp = attrs.valueAsString("POCOOR");
3022 		ScTextStream fp(&tmp, QIODevice::ReadOnly);
3023 		uint numPo = attrs.valueAsUInt("NUMPO");
3024 		double maxVal = std::numeric_limits<double>::max() / 2.0;
3025 		for (uint cx=0; cx < numPo; ++cx)
3026 		{
3027 			fp >> xf;
3028 			fp >> yf;
3029 			if (xf >= 999999)
3030 				xf = maxVal;
3031 			if (yf >= 999999)
3032 				yf = maxVal;
3033 			currItem->PoLine.setPoint(cx, xf, yf);
3034 		}
3035 	}
3036 	else
3037 		currItem->PoLine.resize(0);
3038 
3039 	tmp = "";
3040 	if (attrs.hasAttribute("NUMCO"))
3041 	{
3042 		currItem->ContourLine.resize(attrs.valueAsUInt("NUMCO"));
3043 		tmp = attrs.valueAsString("COCOOR");
3044 		ScTextStream fp(&tmp, QIODevice::ReadOnly);
3045 		uint numCo = attrs.valueAsUInt("NUMCO");
3046 		double maxVal = std::numeric_limits<double>::max() / 2.0;
3047 		for (uint cx=0; cx < numCo; ++cx)
3048 		{
3049 			fp >> xf;
3050 			fp >> yf;
3051 			if (xf >= 999999)
3052 				xf = maxVal;
3053 			if (yf >= 999999)
3054 				yf = maxVal;
3055 			currItem->ContourLine.setPoint(cx, xf, yf);
3056 		}
3057 	}
3058 	else
3059 		currItem->ContourLine = currItem->PoLine.copy();
3060 
3061 	if (!currItem->asLine())
3062 		currItem->Clip = flattenPath(currItem->PoLine, currItem->Segments);
3063 	else
3064 	{
3065 		currItem->Segments.clear();
3066 		currItem->PoLine.resize(0);
3067 		currItem->setHeight(1.0);
3068 		currItem->asLine()->setLineClip();
3069 	}
3070 
3071 	if (currItem->isPathText())
3072 		currItem->updatePolyClip();
3073 	currItem->GrType = attrs.valueAsInt("GRTYP", 0);
3074 	QString GrColor;
3075 	QString GrColor2;
3076 	int GrShade = 0;
3077 	int GrShade2 = 0;
3078 	if (currItem->GrType != 0)
3079 	{
3080 		if (currItem->GrType == Gradient_Pattern)
3081 		{
3082 			currItem->setPattern( attrs.valueAsString("pattern", "") );
3083 			double patternScaleX   = attrs.valueAsDouble("pScaleX", 100.0);
3084 			double patternScaleY   = attrs.valueAsDouble("pScaleY", 100.0);
3085 			double patternOffsetX  = attrs.valueAsDouble("pOffsetX", 0.0);
3086 			double patternOffsetY  = attrs.valueAsDouble("pOffsetY", 0.0);
3087 			double patternRotation = attrs.valueAsDouble("pRotation", 0.0);
3088 			currItem->setPatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, 0, 0);
3089 		}
3090 		else
3091 		{
3092 			currItem->GrStartX = attrs.valueAsDouble("GRSTARTX", 0.0);
3093 			currItem->GrStartY = attrs.valueAsDouble("GRSTARTY", 0.0);
3094 			currItem->GrEndX   = attrs.valueAsDouble("GRENDX", currItem->width());
3095 			currItem->GrEndY   = attrs.valueAsDouble("GRENDY", 0.0);
3096 			currItem->GrFocalX = currItem->GrStartX;
3097 			currItem->GrFocalY = currItem->GrStartY;
3098 			currItem->GrScale  = 1.0;
3099 			currItem->GrSkew  = 0.0;
3100 			GrColor = attrs.valueAsString("GRCOLOR","");
3101 			if (!GrColor.isEmpty())
3102 			{
3103 				GrColor2 = attrs.valueAsString("GRCOLOR2","");
3104 				GrShade  = attrs.valueAsInt("GRSHADE", 100);
3105 				GrShade2 = attrs.valueAsInt("GRSHADE2", 100);
3106 			}
3107 		}
3108 	}
3109 	if ((currItem->GrType != 0) && (currItem->GrType != Gradient_Pattern))
3110 	{
3111 		currItem->fill_gradient.clearStops();
3112 		if ((!GrColor.isEmpty()) && (!GrColor2.isEmpty()))
3113 		{
3114 			if (currItem->GrType == Gradient_RadialLegacy5)
3115 			{
3116 				if ((GrColor != CommonStrings::None) && (!GrColor.isEmpty()))
3117 					currItem->SetQColor(&tmpc, GrColor, GrShade);
3118 				currItem->fill_gradient.addStop(tmpc, 0.0, 0.5, 1.0, GrColor, GrShade);
3119 				if ((GrColor2 != CommonStrings::None) && (!GrColor2.isEmpty()))
3120 					currItem->SetQColor(&tmpc, GrColor2, GrShade2);
3121 				currItem->fill_gradient.addStop(tmpc, 1.0, 0.5, 1.0, GrColor2, GrShade2);
3122 			}
3123 			else
3124 			{
3125 				if ((GrColor2 != CommonStrings::None) && (!GrColor2.isEmpty()))
3126 					currItem->SetQColor(&tmpc, GrColor2, GrShade2);
3127 				currItem->fill_gradient.addStop(tmpc, 0.0, 0.5, 1.0, GrColor2, GrShade2);
3128 				if ((GrColor != CommonStrings::None) && (!GrColor.isEmpty()))
3129 					currItem->SetQColor(&tmpc, GrColor, GrShade);
3130 				currItem->fill_gradient.addStop(tmpc, 1.0, 0.5, 1.0, GrColor, GrShade);
3131 			}
3132 		}
3133 //		currItem->updateGradientVectors();
3134 	}
3135 	switch (currItem->GrType)
3136 	{
3137 		case Gradient_LinearLegacy1:
3138 		case Gradient_LinearLegacy2:
3139 		case Gradient_LinearLegacy3:
3140 		case Gradient_LinearLegacy4:
3141 			currItem->GrType = Gradient_Linear;
3142 			break;
3143 		case Gradient_RadialLegacy5:
3144 			currItem->GrType = Gradient_Radial;
3145 			break;
3146 		default:
3147 			break;
3148 	}
3149 	//currItem->setRedrawBounding();
3150 	//currItem->OwnPage = view->OnPage(currItem);
3151 	UndoManager::instance()->setUndoEnabled(true);
3152 	return currItem;
3153 }
3154 
readLatexInfo(PageItem_LatexFrame * latexitem,ScXmlStreamReader & reader)3155 bool Scribus134Format::readLatexInfo(PageItem_LatexFrame* latexitem, ScXmlStreamReader& reader)
3156 {
3157 	ScXmlStreamAttributes attrs = reader.scAttributes();
3158 	QStringRef tagName = reader.name();
3159 
3160 	latexitem->setConfigFile(attrs.valueAsString("ConfigFile"), true);
3161 	latexitem->setDpi(attrs.valueAsInt("DPI"));
3162 	latexitem->setUsePreamble(attrs.valueAsBool("USE_PREAMBLE"));
3163 
3164 	QString formula;
3165 	while (!reader.atEnd() && !reader.hasError())
3166 	{
3167 		reader.readNext();
3168 		if (reader.isEndElement() && reader.name() == tagName)
3169 			break;
3170 		if (reader.isCharacters())
3171 			formula += reader.text().toString();
3172 		if (reader.isStartElement() && reader.name() == "PROPERTY")
3173 		{
3174 			ScXmlStreamAttributes tAtt = reader.scAttributes();
3175 			QString name  = tAtt.valueAsString("name");
3176 			QString value = tAtt.valueAsString("value");
3177 			if (name.isEmpty()) continue;
3178 			latexitem->editorProperties[name] = value;
3179 		}
3180 	}
3181 	formula = formula.trimmed();
3182 	latexitem->setFormula(formula, false);
3183 
3184 	return !reader.hasError();
3185 }
3186 
loadPage(const QString & fileName,int pageNumber,bool Mpage,const QString & renamedPageName)3187 bool Scribus134Format::loadPage(const QString & fileName, int pageNumber, bool Mpage, const QString& renamedPageName)
3188 {
3189 // 	qDebug() << QString("loading page %2 from file '%1' from 1.3.x plugin").arg(fileName).arg(pageNumber);
3190 	if (m_Doc==nullptr || m_AvailableFonts==nullptr)
3191 	{
3192 		Q_ASSERT(m_Doc==nullptr || m_AvailableFonts==nullptr);
3193 		return false;
3194 	}
3195 
3196 	struct ScribusDoc::BookMa bok;
3197 	QMap<int, ScribusDoc::BookMa> bookmarks;
3198 
3199 	ScPage* newPage = nullptr;
3200 
3201 	QString tmp;
3202 	QMap<int, PageItem*> TableID;
3203 	QList<PageItem*> TableItems;
3204 	QStack< QList<PageItem*> > groupStackFI;
3205 	QStack< QList<PageItem*> > groupStackMI;
3206 	QStack< QList<PageItem*> > groupStackPI;
3207 	QStack< QList<PageItem*> > groupStackF;
3208 	QStack< QList<PageItem*> > groupStackM;
3209 	QStack< QList<PageItem*> > groupStackP;
3210 	QStack<int> groupStackFI2;
3211 	QStack<int> groupStackMI2;
3212 	QStack<int> groupStackPI2;
3213 	double pageX = 0, pageY = 0;
3214 	QMap<int, int> layerTrans;
3215 	int maxLayer = 0, maxLevel = 0, a = 0;
3216 
3217 	layerTrans.clear();
3218 	uint layerCount=m_Doc->layerCount();
3219 	for (uint la2 = 0; la2 < layerCount; ++la2)
3220 	{
3221 		maxLayer = qMax(m_Doc->Layers[la2].ID, maxLayer);
3222 		maxLevel = qMax(m_Doc->Layers[la2].Level, maxLevel);
3223 	}
3224 
3225 	FrameItems.clear();
3226 	groupRemap.clear();
3227 	itemRemap.clear();
3228 	itemNext.clear();
3229 	itemCount = 0;
3230 	itemRemapM.clear();
3231 	itemNextM.clear();
3232 	itemCountM = 0;
3233 
3234 	parStyleMap.clear();
3235 	charStyleMap.clear();
3236 	legacyStyleMap.clear();
3237 	legacyStyleMap[0] = "0";
3238 	legacyStyleMap[1] = "1";
3239 	legacyStyleMap[2] = "2";
3240 	legacyStyleMap[3] = "3";
3241 	legacyStyleMap[4] = "4";
3242 	legacyStyleCount = 5;
3243 
3244  	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3245 	if (ioDevice.isNull())
3246 	{
3247 		setFileReadError();
3248 		return false;
3249 	}
3250 
3251 	QString fileDir = QFileInfo(fileName).absolutePath();
3252 
3253 	bool firstElement = true;
3254 	bool success = true;
3255 
3256 	ScXmlStreamReader reader(ioDevice.data());
3257 	ScXmlStreamAttributes attrs;
3258 	while (!reader.atEnd() && !reader.hasError())
3259 	{
3260 		QXmlStreamReader::TokenType tType = reader.readNext();
3261 		if (tType != QXmlStreamReader::StartElement)
3262 			continue;
3263 		QStringRef tagName = reader.name();
3264 		attrs = reader.scAttributes();
3265 
3266 		if (firstElement)
3267 		{
3268 			if (tagName != "SCRIBUSUTF8NEW")
3269 			{
3270 				success = false;
3271 				break;
3272 			}
3273 			firstElement = false;
3274 		}
3275 
3276 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
3277 		{
3278 			success = readColor(m_Doc->PageColors, attrs);
3279 			if (!success) break;
3280 		}
3281 		if (tagName == "JAVA")
3282 		{
3283 			QString name = attrs.valueAsString("NAME");
3284 			if (!name.isEmpty())
3285 				m_Doc->JavaScripts[name] = attrs.valueAsString("SCRIPT");
3286 		}
3287 		if (tagName == "LAYERS")
3288 		{
3289 			ScLayer newLayer;
3290 			readLayers(newLayer, attrs);
3291 			const ScLayer* la2 = m_Doc->Layers.layerByName(newLayer.Name);
3292 			if (la2)
3293 				layerTrans.insert(newLayer.ID, la2->ID);
3294 			else
3295 			{
3296 				maxLayer++;
3297 				maxLevel++;
3298 				layerTrans.insert(newLayer.ID, maxLayer);
3299 				newLayer.ID = maxLayer;
3300 				newLayer.Level = maxLevel;
3301 				m_Doc->Layers.append(newLayer);
3302 			}
3303 		}
3304 		if (tagName == "Arrows")
3305 		{
3306 			success = readArrows(m_Doc, attrs);
3307 			if (!success) break;
3308 		}
3309 		if (tagName == "MultiLine")
3310 		{
3311 			multiLine ml;
3312 			QString mlName  = attrs.valueAsString("Name");
3313 			QString mlName2 = mlName;
3314 			readMultiline(ml, reader);
3315 			QHash<QString,multiLine>::ConstIterator mlit = m_Doc->docLineStyles.constFind(mlName2);
3316 			if (mlit != m_Doc->docLineStyles.constEnd() && ml != mlit.value())
3317 				mlName2 = getUniqueName(mlName2, m_Doc->docLineStyles);
3318 			m_Doc->docLineStyles.insert(mlName2, ml);
3319 		}
3320 		if (tagName == "Pattern")
3321 		{
3322 			success = readPattern(m_Doc, reader, fileDir);
3323 			if (!success) break;
3324 		}
3325 		if (tagName == "Bookmark")
3326 		{
3327 			int bmElem = 0;
3328 			struct ScribusDoc::BookMa bookmark;
3329 			success = readBookMark(bookmark, bmElem, attrs);
3330 			if (!success) break;
3331 			bookmarks.insert(bmElem, bookmark);
3332 		}
3333 		if (tagName == "STYLE")
3334 		{
3335 			ParagraphStyle pStyle;
3336 			getStyle(pStyle, reader, nullptr, m_Doc, true);
3337 		}
3338 		if (tagName == "CHARSTYLE")
3339 		{
3340 			CharStyle cstyle;
3341 			getStyle(cstyle, reader, nullptr, m_Doc, true);
3342 		}
3343 		if (((tagName == "PAGE") || (tagName == "MASTERPAGE")) && (attrs.valueAsInt("NUM") == pageNumber))
3344 		{
3345 			if (Mpage && (tagName != "MASTERPAGE"))
3346 				continue;
3347 			a = m_Doc->currentPage()->pageNr();
3348 			newPage = m_Doc->Pages->at(a);
3349 			if (Mpage)
3350 			{
3351 				newPage->LeftPg = attrs.valueAsInt("LEFT", 0);
3352 
3353 				if (!renamedPageName.isEmpty())
3354 					newPage->setPageName(renamedPageName);
3355 				else
3356 					newPage->setPageName(attrs.valueAsString("NAM",""));
3357 			}
3358 			if (attrs.hasAttribute("Size"))
3359 				newPage->setSize(attrs.valueAsString("Size"));
3360 			if (attrs.hasAttribute("Orientation"))
3361 				newPage->setOrientation(attrs.valueAsInt("Orientation"));
3362 			if (attrs.hasAttribute("PAGEWIDTH"))
3363 				newPage->setWidth( attrs.valueAsDouble("PAGEWIDTH") );
3364 			else
3365 				newPage->setWidth( attrs.valueAsDouble("PAGEWITH") );
3366 			newPage->setHeight( attrs.valueAsDouble("PAGEHEIGHT") );
3367 			newPage->setInitialHeight(newPage->height());
3368 			newPage->setInitialWidth(newPage->width());
3369 			newPage->initialMargins.setTop(qMax(0.0, attrs.valueAsDouble("BORDERTOP")));
3370 			newPage->initialMargins.setBottom(qMax(0.0, attrs.valueAsDouble("BORDERBOTTOM")));
3371 			newPage->initialMargins.setLeft(qMax(0.0, attrs.valueAsDouble("BORDERLEFT")));
3372 			newPage->initialMargins.setRight(qMax(0.0, attrs.valueAsDouble("BORDERRIGHT")));
3373 			newPage->marginPreset = attrs.valueAsInt("PRESET", 0);
3374 			newPage->Margins.setTop(newPage->initialMargins.top());
3375 			newPage->Margins.setBottom(newPage->initialMargins.bottom());
3376 			pageX = attrs.valueAsDouble("PAGEXPOS");
3377 			pageY = attrs.valueAsDouble("PAGEYPOS");
3378 			// guides reading
3379 			tmp = "";
3380 			newPage->guides.setHorizontalAutoGap(attrs.valueAsDouble("AGhorizontalAutoGap", 0.0));
3381 			newPage->guides.setVerticalAutoGap(attrs.valueAsDouble("AGverticalAutoGap", 0.0));
3382 			newPage->guides.setHorizontalAutoCount(attrs.valueAsInt("AGhorizontalAutoCount", 0));
3383 			newPage->guides.setVerticalAutoCount(attrs.valueAsInt("AGverticalAutoCount", 0));
3384 			newPage->guides.setHorizontalAutoRefer(attrs.valueAsInt("AGhorizontalAutoRefer", 0));
3385 			newPage->guides.setVerticalAutoRefer(attrs.valueAsInt("AGverticalAutoRefer", 0));
3386 			GuideManagerIO::readVerticalGuides(attrs.valueAsString("VerticalGuides"),
3387 											newPage,
3388 											GuideManagerCore::Standard,
3389 											attrs.hasAttribute("NumVGuides"));
3390 			GuideManagerIO::readHorizontalGuides(attrs.valueAsString("HorizontalGuides"),
3391 											newPage,
3392 											GuideManagerCore::Standard,
3393 											attrs.hasAttribute("NumHGuides"));
3394 			GuideManagerIO::readSelection(attrs.valueAsString("AGSelection"), newPage);
3395 
3396 			newPage->guides.addHorizontals(newPage->guides.getAutoHorizontals(newPage), GuideManagerCore::Auto);
3397 			newPage->guides.addVerticals(newPage->guides.getAutoVerticals(newPage), GuideManagerCore::Auto);
3398 		}
3399 		if ((tagName == "PAGEOBJECT") || (tagName == "MASTEROBJECT") || (tagName == "FRAMEOBJECT"))
3400 		{
3401 			if ((Mpage && tagName != "MASTEROBJECT") || (!Mpage && tagName == "MASTEROBJECT"))
3402 			{
3403 				// Go to end of node
3404 				reader.readToElementEnd();
3405 				continue;
3406 			}
3407 			if (attrs.valueAsInt("OwnPage") != pageNumber)
3408 			{
3409 				if (tagName == "PAGEOBJECT")
3410 					itemRemap[itemCount++] = -1;
3411 				else if (tagName == "MASTEROBJECT")
3412 					itemRemapM[itemCountM++] = -1;
3413 				reader.readToElementEnd();
3414 			}
3415 			else
3416 			{
3417 				// first of linked chain?
3418 				if (tagName == "PAGEOBJECT")
3419 				{
3420 					itemRemap[itemCount++] = m_Doc->DocItems.count();
3421 					if (attrs.valueAsInt("NEXTITEM") != -1)
3422 						itemNext[m_Doc->DocItems.count()] = attrs.valueAsInt("NEXTITEM");
3423 				}
3424 				else if (tagName == "MASTEROBJECT")
3425 				{
3426 					itemRemapM[itemCountM++] = m_Doc->MasterItems.count();
3427 					if (attrs.valueAsInt("NEXTITEM") != -1)
3428 						itemNextM[m_Doc->MasterItems.count()] = attrs.valueAsInt("NEXTITEM");
3429 				}
3430 
3431 				ItemInfo itemInfo;
3432 				QString masterPageName = Mpage ? renamedPageName : QString();
3433 				success = readObject(m_Doc, reader, itemInfo, fileDir, true, masterPageName);
3434 				if (!success) break;
3435 
3436 				PageItem* newItem = itemInfo.item;
3437 				newItem->moveBy(-pageX + newPage->xOffset(), - pageY + newPage->yOffset());
3438 				newItem->setOwnerPage(m_Doc->currentPageNumber());
3439 				if (tagName == "PAGEOBJECT")
3440 					newItem->setMasterPageName(QString());
3441 				else if (Mpage && !renamedPageName.isEmpty())
3442 					newItem->setMasterPageName(renamedPageName);
3443 				newItem->setLayer(layerTrans.value(newItem->m_layerID, newItem->m_layerID));
3444 
3445 				if (newItem->isTableItem)
3446 				{
3447 					TableItems.append(newItem);
3448 					TableID.insert(itemInfo.ownLink, newItem);
3449 				}
3450 
3451 				if ((tagName == "PAGEOBJECT") && (groupStackPI.count() > 0))
3452 				{
3453 					groupStackPI.top().append(itemInfo.item);
3454 					while (itemInfo.ownNr == groupStackPI2.top())
3455 					{
3456 						groupStackP.push(groupStackPI.pop());
3457 						groupStackPI2.pop();
3458 						if (groupStackPI2.count() == 0)
3459 							break;
3460 					}
3461 				}
3462 				else if ((tagName == "FRAMEOBJECT") && (groupStackFI.count() > 0))
3463 				{
3464 					groupStackFI.top().append(itemInfo.item);
3465 					while (itemInfo.ownNr == groupStackFI2.top())
3466 					{
3467 						groupStackF.push(groupStackFI.pop());
3468 						groupStackFI2.pop();
3469 						if (groupStackFI2.count() == 0)
3470 							break;
3471 					}
3472 				}
3473 				else if ((tagName == "MASTEROBJECT") && (groupStackMI.count() > 0))
3474 				{
3475 					groupStackMI.top().append(itemInfo.item);
3476 					while (itemInfo.ownNr == groupStackMI2.top())
3477 					{
3478 						groupStackM.push(groupStackMI.pop());
3479 						groupStackMI2.pop();
3480 						if (groupStackMI2.count() == 0)
3481 							break;
3482 					}
3483 				}
3484 
3485 				if (itemInfo.isGroupFlag)
3486 				{
3487 					QList<PageItem*> groupItems;
3488 					groupItems.append(itemInfo.item);
3489 					if (tagName == "PAGEOBJECT")
3490 					{
3491 						groupStackPI.push(groupItems);
3492 						groupStackPI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
3493 					}
3494 					else if (tagName == "FRAMEOBJECT")
3495 					{
3496 						groupStackFI.push(groupItems);
3497 						groupStackFI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
3498 					}
3499 					else
3500 					{
3501 						groupStackMI.push(groupItems);
3502 						groupStackMI2.push(itemInfo.groupLastItem + itemInfo.ownNr);
3503 					}
3504 				}
3505 			}
3506 		}
3507 	}
3508 
3509 	if (reader.hasError())
3510 	{
3511 		setDomParsingError(reader.errorString(), reader.lineNumber(), reader.columnNumber());
3512 		return false;
3513 	}
3514 
3515 	QMap<int, ScribusDoc::BookMa>::Iterator it;
3516 	for (it = bookmarks.begin(); it != bookmarks.end(); ++it)
3517 	{
3518 		int elem = it.key();
3519 		if (elem < m_Doc->Items->count())
3520 		{
3521 			ScribusDoc::BookMa bookmark = it.value();
3522 			bookmark.PageObject = m_Doc->Items->at(elem);
3523 			m_Doc->BookMarks.append( bookmark );
3524 		}
3525 	}
3526 
3527 	if (TableItems.count() != 0)
3528 	{
3529 		for (int ttc = 0; ttc < TableItems.count(); ++ttc)
3530 		{
3531 			PageItem* ta = TableItems.at(ttc);
3532 			if (ta->TopLinkID != -1)
3533 				ta->m_topLink = TableID[ta->TopLinkID];
3534 			else
3535 				ta->m_topLink = nullptr;
3536 			if (ta->LeftLinkID != -1)
3537 				ta->m_leftLink = TableID[ta->LeftLinkID];
3538 			else
3539 				ta->m_leftLink = nullptr;
3540 			if (ta->RightLinkID != -1)
3541 				ta->m_rightLink = TableID[ta->RightLinkID];
3542 			else
3543 				ta->m_rightLink = nullptr;
3544 			if (ta->BottomLinkID != -1)
3545 				ta->m_bottomLink = TableID[ta->BottomLinkID];
3546 			else
3547 				ta->m_bottomLink = nullptr;
3548 		}
3549 	}
3550 
3551 	// reestablish textframe links
3552 	if (itemNext.count() != 0 && !Mpage)
3553 	{
3554 		QMap<int,int>::Iterator lc;
3555 		for (lc = itemNext.begin(); lc != itemNext.end(); ++lc)
3556 		{
3557 			if (itemRemap[lc.value()] >= 0)
3558 			{
3559 				PageItem *Its(nullptr), *Itn(nullptr);
3560 				if (lc.key() < m_Doc->DocItems.count())
3561 					Its = m_Doc->DocItems.at(lc.key());
3562 				if (itemRemap[lc.value()] < m_Doc->DocItems.count())
3563 					Itn = m_Doc->DocItems.at(itemRemap[lc.value()]);
3564 				if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
3565 				{
3566 					qDebug() << "scribus134format: corruption in linked textframes detected";
3567 					continue;
3568 				}
3569 				Its->link(Itn);
3570 			}
3571 		}
3572 	}
3573 	else if (itemNextM.count() != 0 && Mpage)
3574 	{
3575 		QMap<int,int>::Iterator lc;
3576 		for (lc = itemNextM.begin(); lc != itemNextM.end(); ++lc)
3577 		{
3578 			if (itemRemapM[lc.value()] >= 0)
3579 			{
3580 				PageItem *Its(nullptr), *Itn(nullptr);
3581 				if (lc.key() < m_Doc->MasterItems.count())
3582 					Its = m_Doc->MasterItems.at(lc.key());
3583 				if (itemRemapM[lc.value()] < m_Doc->MasterItems.count())
3584 					Itn = m_Doc->MasterItems.at(itemRemapM[lc.value()]);
3585 				if (!Its || !Itn || !Its->canBeLinkedTo(Itn))
3586 				{
3587 					qDebug() << "scribus134format: corruption in linked textframes detected";
3588 					continue;
3589 				}
3590 				Its->link(Itn);
3591 			}
3592 		}
3593 	}
3594 
3595 	while (groupStackP.count() > 0)
3596 	{
3597 		bool isTableIt = false;
3598 		QList<PageItem*> gpL = groupStackP.pop();
3599 		PageItem* gItem = gpL.takeFirst();
3600 		for (int id = 0; id < gpL.count(); id++)
3601 		{
3602 			PageItem* cItem = gpL.at(id);
3603 			isTableIt = cItem->isTableItem;
3604 			cItem->gXpos = cItem->xPos() - gItem->xPos();
3605 			cItem->gYpos = cItem->yPos() - gItem->yPos();
3606 			cItem->Parent = gItem;
3607 			if (gItem->rotation() != 0)
3608 			{
3609 				QTransform ma;
3610 				ma.rotate(-gItem->rotation());
3611 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
3612 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
3613 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
3614 				cItem->setRotation(cItem->rotation() - gItem->rotation());
3615 				cItem->oldRot = cItem->rotation();
3616 			}
3617 			m_Doc->DocItems.removeOne(cItem);
3618 		}
3619 		bool converted = false;
3620 		if (isTableIt)
3621 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackP, &m_Doc->DocItems);
3622 		if (!converted)
3623 			gItem->groupItemList = gpL;
3624 	}
3625 
3626 	while (groupStackF.count() > 0)
3627 	{
3628 		bool isTableIt = false;
3629 		QList<PageItem*> gpL = groupStackF.pop();
3630 		PageItem* gItem = gpL.takeFirst();
3631 		for (int id = 0; id < gpL.count(); id++)
3632 		{
3633 			PageItem* cItem = gpL.at(id);
3634 			isTableIt = cItem->isTableItem;
3635 			cItem->gXpos = cItem->xPos() - gItem->xPos();
3636 			cItem->gYpos = cItem->yPos() - gItem->yPos();
3637 			cItem->Parent = gItem;
3638 			if (gItem->rotation() != 0)
3639 			{
3640 				QTransform ma;
3641 				ma.rotate(-gItem->rotation());
3642 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
3643 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
3644 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
3645 				cItem->setRotation(cItem->rotation() - gItem->rotation());
3646 				cItem->oldRot = cItem->rotation();
3647 			}
3648 			m_Doc->FrameItems.remove(m_Doc->FrameItems.key(cItem));
3649 		}
3650 		bool converted = false;
3651 		if (isTableIt)
3652 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackF, nullptr);
3653 		if (!converted)
3654 			gItem->groupItemList = gpL;
3655 	}
3656 
3657 	while (groupStackM.count() > 0)
3658 	{
3659 		bool isTableIt = false;
3660 		QList<PageItem*> gpL = groupStackM.pop();
3661 		PageItem* gItem = gpL.takeFirst();
3662 		for (int id = 0; id < gpL.count(); id++)
3663 		{
3664 			PageItem* cItem = gpL.at(id);
3665 			isTableIt = cItem->isTableItem;
3666 			cItem->gXpos = cItem->xPos() - gItem->xPos();
3667 			cItem->gYpos = cItem->yPos() - gItem->yPos();
3668 			cItem->Parent = gItem;
3669 			if (gItem->rotation() != 0)
3670 			{
3671 				QTransform ma;
3672 				ma.rotate(-gItem->rotation());
3673 				FPoint n = FPoint(cItem->gXpos, cItem->gYpos);
3674 				cItem->gXpos = ma.m11() * n.x() + ma.m21() * n.y() + ma.dx();
3675 				cItem->gYpos = ma.m22() * n.y() + ma.m12() * n.x() + ma.dy();
3676 				cItem->setRotation(cItem->rotation() - gItem->rotation());
3677 				cItem->oldRot = cItem->rotation();
3678 			}
3679 			m_Doc->MasterItems.removeOne(cItem);
3680 		}
3681 		bool converted = false;
3682 		if (isTableIt)
3683 			converted = convertOldTable(m_Doc, gItem, gpL, &groupStackM, &m_Doc->MasterItems);
3684 		if (!converted)
3685 			gItem->groupItemList = gpL;
3686 	}
3687 
3688 	// reestablish first/lastAuto
3689 	m_Doc->FirstAuto = m_Doc->LastAuto;
3690 	if (m_Doc->LastAuto)
3691 	{
3692 		while (m_Doc->LastAuto->nextInChain())
3693 			m_Doc->LastAuto = m_Doc->LastAuto->nextInChain();
3694 		while (m_Doc->FirstAuto->prevInChain())
3695 			m_Doc->FirstAuto = m_Doc->FirstAuto->prevInChain();
3696 	}
3697 
3698 	return true;
3699 }
3700 
getStyle(ParagraphStyle & style,ScXmlStreamReader & reader,StyleSet<ParagraphStyle> * tempStyles,ScribusDoc * doc,bool equiv)3701 void Scribus134Format::getStyle(ParagraphStyle& style, ScXmlStreamReader& reader, StyleSet<ParagraphStyle> *tempStyles, ScribusDoc* doc, bool equiv)
3702 {
3703 	bool  found(false);
3704 	const StyleSet<ParagraphStyle> &docParagraphStyles = tempStyles ? *tempStyles : doc->paragraphStyles();
3705 
3706 	style.erase();
3707 	readParagraphStyle(doc, reader, style);
3708 
3709 	// Do not duplicate default style
3710 	if (style.isDefaultStyle())
3711 		style.setDefaultStyle(false);
3712 
3713 	const ParagraphStyle* foundStyle = docParagraphStyles.getPointer(style.name());
3714 	if (foundStyle)
3715 	{
3716 		found = style.equiv(*foundStyle);
3717 		if (found)
3718 		{
3719 			if (equiv)
3720 			{
3721 				legacyStyleMap[legacyStyleCount] = style.name();
3722 				legacyStyleCount++;
3723 			}
3724 			return;
3725 		}
3726 		QString newName = docParagraphStyles.getUniqueCopyName(style.name());
3727 		parStyleMap[style.name()] = newName;
3728 		style.setName(newName);
3729 	}
3730 
3731 	if (equiv)
3732 	{
3733 		const ParagraphStyle* equivStyle = docParagraphStyles.findEquivalent(style);
3734 		if (equivStyle)
3735 		{
3736 			parStyleMap[style.name()] = equivStyle->name();
3737 			style.setName(equivStyle->name());
3738 			legacyStyleMap[legacyStyleCount] = style.name();
3739 			legacyStyleCount++;
3740 			return;
3741 		}
3742 	}
3743 
3744 	if (tempStyles)
3745 		tempStyles->create(style);
3746 	else
3747 	{
3748 		StyleSet<ParagraphStyle> tmp;
3749 		tmp.create(style);
3750 		doc->redefineStyles(tmp, false);
3751 	}
3752 	if (equiv)
3753 	{
3754 		legacyStyleMap[legacyStyleCount] = style.name();
3755 		legacyStyleCount++;
3756 	}
3757 }
3758 
getStyle(CharStyle & style,ScXmlStreamReader & reader,StyleSet<CharStyle> * tempStyles,ScribusDoc * doc,bool equiv)3759 void Scribus134Format::getStyle(CharStyle& style, ScXmlStreamReader& reader, StyleSet<CharStyle> *tempStyles, ScribusDoc* doc, bool equiv)
3760 {
3761 	bool  found(false);
3762 	const StyleSet<CharStyle> &docCharStyles = tempStyles ? *tempStyles : doc->charStyles();
3763 
3764 	style.erase();
3765 	ScXmlStreamAttributes attrs = reader.scAttributes();
3766 	readNamedCharacterStyleAttrs(m_Doc, attrs, style);
3767 
3768 	// Do not duplicate default style
3769 	if (style.isDefaultStyle())
3770 		style.setDefaultStyle(false);
3771 
3772 	const CharStyle* foundStyle = docCharStyles.getPointer(style.name());
3773 	if (foundStyle)
3774 	{
3775 		found = style.equiv(*foundStyle);
3776 		if (found)
3777 			return;
3778 		QString newName = docCharStyles.getUniqueCopyName(style.name());
3779 		parStyleMap[style.name()] = newName;
3780 		style.setName(newName);
3781 	}
3782 
3783 	if (equiv)
3784 	{
3785 		const CharStyle* equivStyle = docCharStyles.findEquivalent(style);
3786 		if (equivStyle)
3787 		{
3788 			charStyleMap[style.name()] = equivStyle->name();
3789 			style.setName(equivStyle->name());
3790 			return;
3791 		}
3792 	}
3793 
3794 	if (tempStyles)
3795 		tempStyles->create(style);
3796 	else
3797 	{
3798 		StyleSet<CharStyle> tmp;
3799 		tmp.create(style);
3800 		doc->redefineCharStyles(tmp, false);
3801 	}
3802 }
3803 
readStyles(const QString & fileName,ScribusDoc * doc,StyleSet<ParagraphStyle> & docParagraphStyles)3804 bool Scribus134Format::readStyles(const QString& fileName, ScribusDoc* doc, StyleSet<ParagraphStyle> &docParagraphStyles)
3805 {
3806 	ParagraphStyle pstyle;
3807 	bool firstElement = true;
3808 	bool success = true;
3809 
3810 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3811 	if (ioDevice.isNull())
3812 		return false;
3813 
3814 	parStyleMap.clear();
3815 	charStyleMap.clear();
3816 
3817 	ScXmlStreamReader reader(ioDevice.data());
3818 	ScXmlStreamAttributes attrs;
3819 	while (!reader.atEnd() && !reader.hasError())
3820 	{
3821 		QXmlStreamReader::TokenType tType = reader.readNext();
3822 		if (tType != QXmlStreamReader::StartElement)
3823 			continue;
3824 		QStringRef tagName = reader.name();
3825 		if (firstElement)
3826 		{
3827 			if (tagName != "SCRIBUSUTF8NEW")
3828 			{
3829 				success = false;
3830 				break;
3831 			}
3832 			firstElement = false;
3833 			continue;
3834 		}
3835 		if (tagName == "STYLE")
3836 		{
3837 			pstyle.erase();
3838 			getStyle(pstyle, reader, &docParagraphStyles, doc, false);
3839 		}
3840 	}
3841 	return success;
3842 }
3843 
readCharStyles(const QString & fileName,ScribusDoc * doc,StyleSet<CharStyle> & docCharStyles)3844 bool Scribus134Format::readCharStyles(const QString& fileName, ScribusDoc* doc, StyleSet<CharStyle> &docCharStyles)
3845 {
3846 	CharStyle cstyle;
3847 	bool firstElement = true;
3848 	bool success = true;
3849 
3850 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3851 	if (ioDevice.isNull())
3852 		return false;
3853 
3854 	parStyleMap.clear();
3855 	charStyleMap.clear();
3856 
3857 	ScXmlStreamReader reader(ioDevice.data());
3858 	ScXmlStreamAttributes attrs;
3859 	while (!reader.atEnd() && !reader.hasError())
3860 	{
3861 		QXmlStreamReader::TokenType tType = reader.readNext();
3862 		if (tType != QXmlStreamReader::StartElement)
3863 			continue;
3864 		QStringRef tagName = reader.name();
3865 		if (firstElement)
3866 		{
3867 			if (tagName != "SCRIBUSUTF8NEW")
3868 			{
3869 				success = false;
3870 				break;
3871 			}
3872 			firstElement = false;
3873 			continue;
3874 		}
3875 		if (tagName == "CHARSTYLE")
3876 		{
3877 			cstyle.erase();
3878 			attrs = reader.scAttributes();
3879 			readNamedCharacterStyleAttrs(doc, attrs, cstyle);
3880 			docCharStyles.create(cstyle);
3881 		}
3882 	}
3883 	return success;
3884 }
3885 
readLineStyles(const QString & fileName,QHash<QString,multiLine> * styles)3886 bool Scribus134Format::readLineStyles(const QString& fileName, QHash<QString,multiLine> *styles)
3887 {
3888 	bool firstElement = true;
3889 	bool success = true;
3890 
3891 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3892 	if (ioDevice.isNull())
3893 		return false;
3894 
3895 	ScXmlStreamReader reader(ioDevice.data());
3896 	ScXmlStreamAttributes attrs;
3897 	while (!reader.atEnd() && !reader.hasError())
3898 	{
3899 		QXmlStreamReader::TokenType tType = reader.readNext();
3900 		if (tType != QXmlStreamReader::StartElement)
3901 			continue;
3902 		QStringRef tagName = reader.name();
3903 		if (firstElement)
3904 		{
3905 			if (tagName != "SCRIBUSUTF8NEW")
3906 			{
3907 				success = false;
3908 				break;
3909 			}
3910 			firstElement = false;
3911 			continue;
3912 		}
3913 		if (tagName == "MultiLine")
3914 		{
3915 			multiLine ml;
3916 			attrs = reader.scAttributes();
3917 			QString mlName  = attrs.valueAsString("Name");
3918 			QString mlName2 = mlName;
3919 			readMultiline(ml, reader);
3920 			int copyC = 1;
3921 			QHash<QString,multiLine>::ConstIterator mlit = styles->constFind(mlName2);
3922 			if (mlit != styles->constEnd() && ml != mlit.value())
3923 			{
3924 				while (styles->contains(mlName2))
3925 				{
3926 					mlName2 = tr("Copy #%1 of ").arg(copyC)+mlName;
3927 					copyC++;
3928 				}
3929 			}
3930 			styles->insert(mlName2, ml);
3931 		}
3932 	}
3933 	return success;
3934 }
3935 
readColors(const QString & fileName,ColorList & colors)3936 bool Scribus134Format::readColors(const QString& fileName, ColorList & colors)
3937 {
3938 	bool firstElement = true;
3939 //	bool success = true;
3940 
3941 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3942 	if (ioDevice.isNull())
3943 		return false;
3944 
3945 	ScXmlStreamReader reader(ioDevice.data());
3946 	ScXmlStreamAttributes attrs;
3947 	while (!reader.atEnd() && !reader.hasError())
3948 	{
3949 		QXmlStreamReader::TokenType tType = reader.readNext();
3950 		if (tType != QXmlStreamReader::StartElement)
3951 			continue;
3952 		QStringRef tagName = reader.name();
3953 		if (firstElement)
3954 		{
3955 			if (tagName != "SCRIBUSUTF8NEW")
3956 			{
3957 			//	success = false;
3958 				break;
3959 			}
3960 			firstElement = false;
3961 			continue;
3962 		}
3963 		if (tagName == "COLOR" && attrs.valueAsString("NAME") != CommonStrings::None)
3964 		{
3965 			attrs = reader.scAttributes();
3966 			if (attrs.valueAsString("NAME") != CommonStrings::None)
3967 			{
3968 				readColor(colors, attrs);
3969 			}
3970 		}
3971 	}
3972 	return true;
3973 }
3974 
readPageCount(const QString & fileName,int * num1,int * num2,QStringList & masterPageNames)3975 bool Scribus134Format::readPageCount(const QString& fileName, int *num1, int *num2, QStringList & masterPageNames)
3976 {
3977 	QString pageName;
3978 	int counter = 0;
3979 	int counter2 = 0;
3980 	bool firstElement = true;
3981 	bool success = true;
3982 
3983 	QScopedPointer<QIODevice> ioDevice(slaReader(fileName));
3984 	if (ioDevice.isNull())
3985 		return false;
3986 
3987 	ScXmlStreamReader reader(ioDevice.data());
3988 	ScXmlStreamAttributes attrs;
3989 	while (!reader.atEnd() && !reader.hasError())
3990 	{
3991 		QXmlStreamReader::TokenType tType = reader.readNext();
3992 		if (tType != QXmlStreamReader::StartElement)
3993 			continue;
3994 		QStringRef tagName = reader.name();
3995 		if (firstElement)
3996 		{
3997 			if (tagName != "SCRIBUSUTF8NEW")
3998 			{
3999 				success = false;
4000 				break;
4001 			}
4002 			firstElement = false;
4003 			continue;
4004 		}
4005 		if (tagName == "PAGE")
4006 			counter++;
4007 		if (tagName == "MASTERPAGE")
4008 		{
4009 			pageName = reader.scAttributes().valueAsString("NAM");
4010 			if (!pageName.isEmpty())
4011 			{
4012 				counter2++;
4013 				masterPageNames.append(pageName);
4014 			}
4015 		}
4016 	}
4017 	*num1 = counter;
4018 	*num2 = counter2;
4019 	return success;
4020 }
4021