1 /*
2 For general Scribus (>=1.3.2) copyright and licensing information please refer
3 to the COPYING file provided with the program. Following this notice may exist
4 a copyright and/or license notice that predates the release of Scribus 1.3.2
5 for which a new license (GPL+exception) is in place.
6 */
7 #include "scribus150format.h"
8 #include "scribus150formatimpl.h"
9 
10 #include <ctime>
11 #include <memory>
12 
13 #include "../../formatidlist.h"
14 #include "commonstrings.h"
15 #include "ui/missing.h"
16 #include "prefsmanager.h"
17 #include "qtiocompressor.h"
18 #include "resourcecollection.h"
19 #include "scconfig.h"
20 #include "scpaths.h"
21 #include "scpattern.h"
22 #include "scribusdoc.h"
23 #include "scribusview.h"
24 #include "hyphenator.h"
25 #include "notesstyles.h"
26 #include "pageitem_arc.h"
27 #include "pageitem_latexframe.h"
28 #include "pageitem_noteframe.h"
29 #ifdef HAVE_OSG
30 	#include "pageitem_osgframe.h"
31 #endif
32 #include "pageitem_regularpolygon.h"
33 #include "pageitem_spiral.h"
34 #include "pageitem_table.h"
35 
36 #include "api/api_application.h"
37 
38 #include "units.h"
39 #include "util.h"
40 #include "util_math.h"
41 #include "util_color.h"
42 #include <QCursor>
43 #include <QFileInfo>
44 #include <QList>
45 #include <QDataStream>
46 #include <QScopedPointer>
47 
48 #include "scxmlstreamwriter.h"
49 
saveElements(double xp,double yp,double wp,double hp,Selection * selection,QByteArray & prevData)50 QString Scribus150Format::saveElements(double xp, double yp, double wp, double hp, Selection* selection, QByteArray &prevData)
51 {
52 	ResourceCollection lists;
53 	QList<PageItem*> emG;
54 	QList<PageItem*> emF;
55 
56 	QString fileDir = ScPaths::applicationDataDir();
57 	QString documentStr;
58 	documentStr.reserve(524288);
59 
60 	ScXmlStreamWriter writer(&documentStr);
61 	writer.setAutoFormatting(true);
62 //	writer.writeStartDocument();
63 	writer.writeStartElement("SCRIBUSELEMUTF8");
64 	writer.writeAttribute("XP", xp);
65 	writer.writeAttribute("YP", yp);
66 	writer.writeAttribute("W", wp);
67 	writer.writeAttribute("H", hp);
68 	writer.writeAttribute("COUNT",   selection->count());
69 	writer.writeAttribute("Version", ScribusAPI::getVersion());
70 	writer.writeAttribute("previewData", QString(prevData));
71 	writeColors(writer, true);
72 	writeGradients(writer, true);
73 
74 	for (int i = 0; i < selection->count(); ++i)
75 	{
76 		PageItem *currItem = selection->itemAt(i);
77 		currItem->getNamedResources(lists);
78 		emG.append(currItem);
79 		if ((!currItem->isTextFrame()) && (!currItem->isPathText()))
80 			continue;
81 		//for notes frames text should not be saved
82 		if (currItem->isNoteFrame())
83 			continue;
84 		for (int j = currItem->firstInFrame(); j <= currItem->lastInFrame(); ++j)
85 		{
86 			QChar chr = currItem->itemText.text(j);
87 			if (chr != SpecialChars::OBJECT)
88 				continue;
89 			if (!currItem->itemText.hasObject(j))
90 				continue;
91 			PageItem* pi = currItem->itemText.object(j).getPageItem(currItem->doc());
92 			if (!emF.contains(pi))
93 				emF.append(pi);
94 		}
95 	}
96 
97 	// Write character styles
98 	QList<QString> names = lists.charStyleNames();
99 	QList<int> styleList = m_Doc->getSortedCharStyleList();
100 	for (int i = 0; i < styleList.count(); ++i)
101 	{
102 		const CharStyle& charStyle = m_Doc->charStyles()[styleList[i]];
103 		if (!names.contains(charStyle.name()))
104 			continue;
105 		writer.writeStartElement("CHARSTYLE");
106 		putNamedCStyle(writer, charStyle);
107 		writer.writeEndElement();
108 	}
109 
110 	// Write paragraph styles
111 	names = lists.styleNames();
112 	styleList = m_Doc->getSortedStyleList();
113 	for (int i = 0; i < styleList.count(); ++i)
114 	{
115 		const ParagraphStyle& paragraphStyle = m_Doc->paragraphStyles()[styleList[i]];
116 		if (names.contains(paragraphStyle.name()))
117 			putPStyle(writer, paragraphStyle, "STYLE");
118 	}
119 
120 	writeLineStyles(writer, lists.lineStyleNames());
121 	writeArrowStyles(writer);
122 
123 	// TODO Write used marks
124 	// writeMarks(writer);
125 
126 	// Write note styles
127 	names = lists.noteStyleNames();
128 	writeNotesStyles(writer, names);
129 
130 	// Write note frames
131 	QList<PageItem_NoteFrame*> nfList;
132 	for (int i = 0; i < selection->count(); ++i)
133 	{
134 		PageItem* item = selection->itemAt(i);
135 		if (!item->isNoteFrame())
136 			continue;
137 		nfList.append(dynamic_cast<PageItem_NoteFrame*>(item));
138 	}
139 	writeNotesFrames(writer, nfList);
140 
141 	// TODO Write text notes (once marks are also written)
142 	// Do not uncomment before otherwise pasting note frame
143 	// will trigger a crash
144 	/*QList<TextNote*> textNotes;
145 	for (int i = 0; i < nfList.count(); ++i)
146 	{
147 		PageItem_NoteFrame* noteFrame = nfList.at(i);
148 		textNotes.append(noteFrame->notesList());
149 	}
150 	writeNotes(writer, textNotes);*/
151 
152 	writePatterns(writer, fileDir, true, selection);
153 	if (!emF.isEmpty())
154 		WriteObjects(m_Doc, writer, fileDir, nullptr, 0, ItemSelectionFrame, &emF);
155 	WriteObjects(m_Doc, writer, fileDir, nullptr, 0, ItemSelectionElements, &emG);
156 	writer.writeEndElement();
157 //	writer.writeEndDocument();
158 	documentStr.squeeze();
159 	return documentStr.trimmed();
160 }
161 
saveStory(StoryText & story,PageItem * item,QByteArray & data)162 bool Scribus150Format::saveStory(StoryText& story, PageItem* item, QByteArray& data)
163 {
164 	ResourceCollection lists;
165 	QList<PageItem*> embeddedFrames;
166 
167 	QString fileDir = ScPaths::applicationDataDir();
168 	QString documentStr;
169 	documentStr.reserve(524288);
170 
171 	story.getNamedResources(lists);
172 
173 	ScXmlStreamWriter writer(&documentStr);
174 	writer.setAutoFormatting(true);
175 //	writer.writeStartDocument();
176 	writer.writeStartElement("ScribusStory");
177 	writer.writeAttribute("Version", ScribusAPI::getVersion());
178 
179 	writeColors(writer, lists.colorNames());
180 	writeGradients(writer, lists.gradientNames());
181 
182 	for (int i = 0; i < story.length(); ++i)
183 	{
184 		QChar chr = story.text(i);
185 		if (chr != SpecialChars::OBJECT)
186 			continue;
187 		if (!story.hasObject(i))
188 			continue;
189 		PageItem* pi = story.object(i).getPageItem(story.doc());
190 		if (pi && !embeddedFrames.contains(pi))
191 			embeddedFrames.append(pi);
192 	}
193 
194 	// Write character styles
195 	QList<QString> names = lists.charStyleNames();
196 	QList<int> styleList = m_Doc->getSortedCharStyleList();
197 	for (int i = 0; i < styleList.count(); ++i)
198 	{
199 		const CharStyle& charStyle = m_Doc->charStyles()[styleList[i]];
200 		if (!names.contains(charStyle.name()))
201 			continue;
202 		writer.writeStartElement("CHARSTYLE");
203 		putNamedCStyle(writer, charStyle);
204 		writer.writeEndElement();
205 	}
206 
207 	// Write paragraph styles
208 	names = lists.styleNames();
209 	styleList = m_Doc->getSortedStyleList();
210 	for (int i = 0; i < styleList.count(); ++i)
211 	{
212 		const ParagraphStyle& paragraphStyle = m_Doc->paragraphStyles()[styleList[i]];
213 		if (names.contains(paragraphStyle.name()))
214 			putPStyle(writer, paragraphStyle, "STYLE");
215 	}
216 
217 	writeLineStyles(writer, lists.lineStyleNames());
218 	writeArrowStyles(writer);
219 
220 	// TODO Write used marks
221 	// writeMarks(writer);
222 
223 	// Write note styles
224 	names = lists.noteStyleNames();
225 	writeNotesStyles(writer, names);
226 
227 	// TODO Write text notes (once marks are also written)
228 	// Do not uncomment before otherwise pasting note frame
229 	// will trigger a crash
230 	/*QList<TextNote*> textNotes;
231 	for (int i = 0; i < nfList.count(); ++i)
232 	{
233 		PageItem_NoteFrame* noteFrame = nfList.at(i);
234 		textNotes.append(noteFrame->notesList());
235 	}
236 	writeNotes(writer, textNotes);*/
237 
238 	// FIXME: may be used in embedded objects
239 	// writePatterns(writer, fileDir, true, selection);
240 	if (!embeddedFrames.isEmpty())
241 		WriteObjects(m_Doc, writer, fileDir, nullptr, 0, ItemSelectionFrame, &embeddedFrames);
242 	writeStoryText(m_Doc, writer, story);
243 	writer.writeEndElement();
244 //	writer.writeEndDocument();
245 	documentStr.squeeze();
246 	documentStr = documentStr.trimmed();
247 
248 	data = documentStr.toUtf8();
249 
250 	return true;
251 }
252 
savePalette(const QString & fileName)253 bool Scribus150Format::savePalette(const QString & fileName)
254 {
255 	QString fileDir = QFileInfo(fileName).absolutePath();
256 	QScopedPointer<QIODevice> outputFile;
257 	outputFile.reset( new QFile(fileName) );
258 	if (!outputFile->open(QIODevice::WriteOnly))
259 		return false;
260 	ScXmlStreamWriter docu;
261 	docu.setAutoFormatting(true);
262 	docu.setDevice(outputFile.data());
263 	docu.writeStartDocument();
264 	docu.writeStartElement("SCRIBUSCOLORS");
265 	writeColors(docu);
266 	writeGradients(docu);
267 	writePatterns(docu, fileDir);
268 	docu.writeEndElement();
269 	docu.writeEndDocument();
270 	bool  writeSucceed = false;
271 	const QFile* qFile = qobject_cast<QFile*>(outputFile.data());
272 	writeSucceed = (qFile->error() == QFile::NoError);
273 	outputFile->close();
274 	return writeSucceed;
275 }
276 
saveFile(const QString & fileName,const FileFormat &)277 bool Scribus150Format::saveFile(const QString & fileName, const FileFormat & /* fmt */)
278 {
279 	m_lastSavedFile = "";
280 
281 	// #11279: Image links get corrupted when symlinks involved
282 	// We have to proceed in tow steps here as QFileInfo::canonicalPath()
283 	// may no return correct result if fileName does not exists
284 	QString fileDir = QFileInfo(fileName).absolutePath();
285 	QString canonicalPath = QFileInfo(fileDir).canonicalFilePath();
286 	if (!canonicalPath.isEmpty())
287 		fileDir = canonicalPath;
288 
289 	// Create a random temporary file name
290 	srand(time(nullptr)); // initialize random sequence each time
291 	long randt = 0;
292 	long randn = 1 + (int) (((double) rand() / ((double) RAND_MAX + 1)) * 10000);
293 	QString  tmpFileName  = QString("%1.%2").arg(fileName).arg(randn);
294 	while (QFile::exists(tmpFileName) && (randt < 100))
295 	{
296 		randn = 1 + (int) (((double) rand() / ((double) RAND_MAX + 1)) * 10000);
297 		tmpFileName = QString("%1.%2").arg(fileName).arg(randn);
298 		++randt;
299 	}
300 	if (QFile::exists(tmpFileName))
301 		return false;
302 
303 	QScopedPointer<QIODevice> outputFile;
304 	if (fileName.toLower().right(2) == "gz")
305 	{
306 		aFile.setFileName(tmpFileName);
307 		QtIOCompressor *compressor = new QtIOCompressor(&aFile);
308 		compressor->setStreamFormat(QtIOCompressor::GzipFormat);
309 		outputFile.reset(compressor);
310 	}
311 	else
312 		outputFile.reset( new QFile(tmpFileName) );
313 
314 	if (!outputFile->open(QIODevice::WriteOnly))
315 		return false;
316 
317 	ScXmlStreamWriter docu;
318 	docu.setAutoFormatting(true);
319 	docu.setDevice(outputFile.data());
320 	docu.writeStartDocument();
321 	docu.writeStartElement("SCRIBUSUTF8NEW");
322 	docu.writeAttribute("Version", ScribusAPI::getVersion());
323 
324 	docu.writeStartElement("DOCUMENT");
325 	docu.writeAttribute("ANZPAGES"    , m_Doc->DocPages.count());
326 	docu.writeAttribute("PAGEWIDTH"   , m_Doc->pageWidth());
327 	docu.writeAttribute("PAGEHEIGHT"  , m_Doc->pageHeight());
328 	docu.writeAttribute("BORDERLEFT"  , m_Doc->margins()->left());
329 	docu.writeAttribute("BORDERRIGHT" , m_Doc->margins()->right());
330 	docu.writeAttribute("BORDERTOP"   , m_Doc->margins()->top());
331 	docu.writeAttribute("BORDERBOTTOM", m_Doc->margins()->bottom());
332 	docu.writeAttribute("PRESET"      , m_Doc->marginPreset());
333 	docu.writeAttribute("BleedTop"    , m_Doc->bleeds()->top());
334 	docu.writeAttribute("BleedLeft"   , m_Doc->bleeds()->left());
335 	docu.writeAttribute("BleedRight"  , m_Doc->bleeds()->right());
336 	docu.writeAttribute("BleedBottom" , m_Doc->bleeds()->bottom());
337 	docu.writeAttribute("ORIENTATION" , m_Doc->pageOrientation());
338 	docu.writeAttribute("PAGESIZE"    , m_Doc->pageSize());
339 	docu.writeAttribute("FIRSTNUM"    , m_Doc->FirstPnum);
340 	docu.writeAttribute("BOOK"        , m_Doc->pagePositioning());
341 	if (m_Doc->usesAutomaticTextFrames())
342 		docu.writeAttribute("AUTOTEXT", 1);
343 	docu.writeAttribute("AUTOSPALTEN" , m_Doc->PageSp);
344 	docu.writeAttribute("ABSTSPALTEN" , m_Doc->PageSpa);
345 	docu.writeAttribute("UNITS"       , m_Doc->unitIndex());
346 	docu.writeAttribute("DFONT"       , m_Doc->itemToolPrefs().textFont);
347 	docu.writeAttribute("DSIZE"       , m_Doc->itemToolPrefs().textSize / 10.0);
348 	docu.writeAttribute("DCOL"        , m_Doc->itemToolPrefs().textColumns);
349 	docu.writeAttribute("DGAP"        , m_Doc->itemToolPrefs().textColumnGap);
350 	docu.writeAttribute("TabFill"     , m_Doc->itemToolPrefs().textTabFillChar);
351 	docu.writeAttribute("TabWidth"    , m_Doc->itemToolPrefs().textTabWidth);
352 	docu.writeAttribute("TextDistLeft", m_Doc->itemToolPrefs().textDistances.left());
353 	docu.writeAttribute("TextDistRight", m_Doc->itemToolPrefs().textDistances.right());
354 	docu.writeAttribute("TextDistBottom", m_Doc->itemToolPrefs().textDistances.bottom());
355 	docu.writeAttribute("TextDistTop" , m_Doc->itemToolPrefs().textDistances.top());
356 	docu.writeAttribute("FirstLineOffset" , (int) m_Doc->itemToolPrefs().firstLineOffset);
357 	docu.writeAttribute("AUTHOR"      , m_Doc->documentInfo().author());
358 	docu.writeAttribute("COMMENTS"    , m_Doc->documentInfo().comments());
359 	docu.writeAttribute("KEYWORDS"    , m_Doc->documentInfo().keywords());
360 	docu.writeAttribute("PUBLISHER",m_Doc->documentInfo().publisher());
361 	docu.writeAttribute("DOCDATE",m_Doc->documentInfo().date());
362 	docu.writeAttribute("DOCTYPE",m_Doc->documentInfo().type());
363 	docu.writeAttribute("DOCFORMAT",m_Doc->documentInfo().format());
364 	docu.writeAttribute("DOCIDENT",m_Doc->documentInfo().ident());
365 	docu.writeAttribute("DOCSOURCE",m_Doc->documentInfo().source());
366 	docu.writeAttribute("DOCLANGINFO",m_Doc->documentInfo().langInfo());
367 	docu.writeAttribute("DOCRELATION",m_Doc->documentInfo().relation());
368 	docu.writeAttribute("DOCCOVER",m_Doc->documentInfo().cover());
369 	docu.writeAttribute("DOCRIGHTS",m_Doc->documentInfo().rights());
370 	docu.writeAttribute("DOCCONTRIB",m_Doc->documentInfo().contrib());
371 	docu.writeAttribute("TITLE",m_Doc->documentInfo().title());
372 	docu.writeAttribute("SUBJECT",m_Doc->documentInfo().subject());
373 	docu.writeAttribute("VHOCH"  , m_Doc->typographicPrefs().valueSuperScript);
374 	docu.writeAttribute("VHOCHSC", m_Doc->typographicPrefs().scalingSuperScript);
375 	docu.writeAttribute("VTIEF"  , m_Doc->typographicPrefs().valueSubScript);
376 	docu.writeAttribute("VTIEFSC", m_Doc->typographicPrefs().scalingSubScript);
377 	docu.writeAttribute("VKAPIT" , m_Doc->typographicPrefs().valueSmallCaps);
378 	docu.writeAttribute("BASEGRID",m_Doc->guidesPrefs().valueBaselineGrid);
379 	docu.writeAttribute("BASEO"  , m_Doc->guidesPrefs().offsetBaselineGrid);
380 	docu.writeAttribute("AUTOL"  , m_Doc->typographicPrefs().autoLineSpacing);
381 	docu.writeAttribute("UnderlinePos"   , m_Doc->typographicPrefs().valueUnderlinePos);
382 	docu.writeAttribute("UnderlineWidth" , m_Doc->typographicPrefs().valueUnderlineWidth);
383 	docu.writeAttribute("StrikeThruPos"  , m_Doc->typographicPrefs().valueStrikeThruPos);
384 	docu.writeAttribute("StrikeThruWidth", m_Doc->typographicPrefs().valueStrikeThruWidth);
385 	docu.writeAttribute("GROUPC",m_Doc->GroupCounter);
386 	docu.writeAttribute("HCMS" , static_cast<int>(m_Doc->HasCMS));
387 	docu.writeAttribute("DPSo" , static_cast<int>(m_Doc->cmsSettings().SoftProofOn));
388 	docu.writeAttribute("DPSFo", static_cast<int>(m_Doc->cmsSettings().SoftProofFullOn));
389 	docu.writeAttribute("DPuse", static_cast<int>(m_Doc->cmsSettings().CMSinUse));
390 	docu.writeAttribute("DPgam", static_cast<int>(m_Doc->cmsSettings().GamutCheck));
391 	docu.writeAttribute("DPbla", static_cast<int>(m_Doc->cmsSettings().BlackPoint));
392 	 // Monitor profile is now an application level parameter
393 	//docu.writeAttribute("DPMo",m_Doc->cmsSettings().DefaultMonitorProfile);
394 	docu.writeAttribute("DPPr",m_Doc->cmsSettings().DefaultPrinterProfile);
395 	docu.writeAttribute("DPIn",m_Doc->cmsSettings().DefaultImageRGBProfile);
396 	docu.writeAttribute("DPInCMYK",m_Doc->cmsSettings().DefaultImageCMYKProfile);
397 	docu.writeAttribute("DPIn2",m_Doc->cmsSettings().DefaultSolidColorRGBProfile);
398 	docu.writeAttribute("DPIn3",m_Doc->cmsSettings().DefaultSolidColorCMYKProfile);
399 	docu.writeAttribute("DISc",m_Doc->cmsSettings().DefaultIntentColors);
400 	docu.writeAttribute("DIIm",m_Doc->cmsSettings().DefaultIntentImages);
401 	docu.writeAttribute("ALAYER", m_Doc->activeLayer());
402 	docu.writeAttribute("LANGUAGE", m_Doc->language());
403 //	docu.writeAttribute("MINWORDLEN", m_Doc->hyphMinimumWordLength());
404 //	docu.writeAttribute("HYCOUNT", m_Doc->hyphConsecutiveLines());
405 	docu.writeAttribute("AUTOMATIC", static_cast<int>(m_Doc->hyphAutomatic()));
406 	docu.writeAttribute("AUTOCHECK", static_cast<int>(m_Doc->hyphAutoCheck()));
407 	docu.writeAttribute("GUIDELOCK", static_cast<int>(m_Doc->GuideLock));
408 	docu.writeAttribute("SnapToGuides", static_cast<int>(m_Doc->SnapGuides));
409 	docu.writeAttribute("SnapToGrid", static_cast<int>(m_Doc->SnapGrid));
410 	docu.writeAttribute("SnapToElement", static_cast<int>(m_Doc->SnapElement));
411 	docu.writeAttribute("MINGRID", m_Doc->guidesPrefs().minorGridSpacing);
412 	docu.writeAttribute("MAJGRID", m_Doc->guidesPrefs().majorGridSpacing);
413 	docu.writeAttribute("SHOWGRID", static_cast<int>(m_Doc->guidesPrefs().gridShown));
414 	docu.writeAttribute("SHOWGUIDES", static_cast<int>(m_Doc->guidesPrefs().guidesShown));
415 	docu.writeAttribute("showcolborders", static_cast<int>(m_Doc->guidesPrefs().colBordersShown));
416 	// #15308: the preview mode state should not be stored in the .sla
417 	// docu.writeAttribute("previewMode", static_cast<int>(m_Doc->drawAsPreview));
418 	if (m_Doc->drawAsPreview)
419 	{
420 		docu.writeAttribute("SHOWFRAME", static_cast<int>(m_View->storedFramesShown));
421 		docu.writeAttribute("SHOWControl", static_cast<int>(m_View->storedShowControls));
422 	}
423 	else
424 	{
425 		docu.writeAttribute("SHOWFRAME", static_cast<int>(m_Doc->guidesPrefs().framesShown));
426 		docu.writeAttribute("SHOWControl", static_cast<int>(m_Doc->guidesPrefs().showControls));
427 	}
428 	docu.writeAttribute("SHOWLAYERM", static_cast<int>(m_Doc->guidesPrefs().layerMarkersShown));
429 	docu.writeAttribute("SHOWMARGIN", static_cast<int>(m_Doc->guidesPrefs().marginsShown));
430 	docu.writeAttribute("SHOWBASE", static_cast<int>(m_Doc->guidesPrefs().baselineGridShown));
431 	docu.writeAttribute("SHOWPICT", static_cast<int>(m_Doc->guidesPrefs().showPic));
432 	docu.writeAttribute("SHOWLINK", static_cast<int>(m_Doc->guidesPrefs().linkShown));
433 	docu.writeAttribute("rulerMode", static_cast<int>(m_Doc->guidesPrefs().rulerMode));
434 	docu.writeAttribute("showrulers", static_cast<int>(m_Doc->guidesPrefs().rulersShown));
435 	docu.writeAttribute("showBleed", static_cast<int>(m_Doc->guidesPrefs().showBleed));
436 	docu.writeAttribute("rulerXoffset", m_Doc->rulerXoffset);
437 	docu.writeAttribute("rulerYoffset", m_Doc->rulerYoffset);
438 	docu.writeAttribute("GuideRad", m_Doc->guidesPrefs().guideRad);
439 	docu.writeAttribute("GRAB",m_Doc->guidesPrefs().grabRadius);
440 	docu.writeAttribute("POLYC", m_Doc->itemToolPrefs().polyCorners);
441 	docu.writeAttribute("POLYF", m_Doc->itemToolPrefs().polyFactor);
442 	docu.writeAttribute("POLYR", m_Doc->itemToolPrefs().polyRotation);
443 	docu.writeAttribute("POLYIR", m_Doc->itemToolPrefs().polyInnerRot);
444 	docu.writeAttribute("POLYCUR", m_Doc->itemToolPrefs().polyCurvature);
445 	docu.writeAttribute("POLYOCUR", m_Doc->itemToolPrefs().polyOuterCurvature);
446 	docu.writeAttribute("POLYS", static_cast<int>(m_Doc->itemToolPrefs().polyUseFactor));
447 	docu.writeAttribute("arcStartAngle", m_Doc->itemToolPrefs().arcStartAngle);
448 	docu.writeAttribute("arcSweepAngle", m_Doc->itemToolPrefs().arcSweepAngle);
449 	docu.writeAttribute("spiralStartAngle", m_Doc->itemToolPrefs().spiralStartAngle);
450 	docu.writeAttribute("spiralEndAngle", m_Doc->itemToolPrefs().spiralEndAngle);
451 	docu.writeAttribute("spiralFactor", m_Doc->itemToolPrefs().spiralFactor);
452 	docu.writeAttribute("AutoSave", static_cast<int>(m_Doc->autoSave()));
453 	docu.writeAttribute("AutoSaveTime", m_Doc->autoSaveTime());
454 	docu.writeAttribute("AutoSaveCount", m_Doc->autoSaveCount());
455 	docu.writeAttribute("AutoSaveKeep", static_cast<int>(m_Doc->autoSaveKeep()));
456 	docu.writeAttribute("AUtoSaveInDocDir", static_cast<int>(m_Doc->autoSaveInDocDir()));
457 	docu.writeAttribute("AutoSaveDir", m_Doc->autoSaveDir());
458 	docu.writeAttribute("ScratchBottom", m_Doc->scratch()->bottom());
459 	docu.writeAttribute("ScratchLeft", m_Doc->scratch()->left());
460 	docu.writeAttribute("ScratchRight", m_Doc->scratch()->right());
461 	docu.writeAttribute("ScratchTop", m_Doc->scratch()->top());
462 	docu.writeAttribute("GapHorizontal", m_Doc->pageGapHorizontal());
463 	docu.writeAttribute("GapVertical", m_Doc->pageGapVertical());
464 	docu.writeAttribute("StartArrow", m_Doc->itemToolPrefs().lineStartArrow);
465 	docu.writeAttribute("EndArrow", m_Doc->itemToolPrefs().lineEndArrow);
466 	docu.writeAttribute("PEN",m_Doc->itemToolPrefs().shapeLineColor);
467 	docu.writeAttribute("BRUSH",m_Doc->itemToolPrefs().shapeFillColor);
468 	docu.writeAttribute("PENLINE",m_Doc->itemToolPrefs().lineColor);
469 	docu.writeAttribute("PENTEXT",m_Doc->itemToolPrefs().textColor);
470 	docu.writeAttribute("StrokeText",m_Doc->itemToolPrefs().textStrokeColor);
471 	docu.writeAttribute("TextBackGround", m_Doc->itemToolPrefs().textFillColor);
472 	docu.writeAttribute("TextLineColor", m_Doc->itemToolPrefs().textLineColor);
473 	docu.writeAttribute("TextBackGroundShade", m_Doc->itemToolPrefs().textFillColorShade);
474 	docu.writeAttribute("TextLineShade", m_Doc->itemToolPrefs().textLineColorShade);
475 	docu.writeAttribute("TextPenShade", m_Doc->itemToolPrefs().textShade);
476 	docu.writeAttribute("TextStrokeShade", m_Doc->itemToolPrefs().textStrokeShade);
477 	docu.writeAttribute("STIL",m_Doc->itemToolPrefs().shapeLineStyle);
478 	docu.writeAttribute("STILLINE",m_Doc->itemToolPrefs().lineStyle);
479 	docu.writeAttribute("WIDTH",m_Doc->itemToolPrefs().shapeLineWidth);
480 	docu.writeAttribute("WIDTHLINE",m_Doc->itemToolPrefs().lineWidth);
481 	docu.writeAttribute("PENSHADE",m_Doc->itemToolPrefs().shapeLineColorShade);
482 	docu.writeAttribute("LINESHADE",m_Doc->itemToolPrefs().lineColorShade);
483 	docu.writeAttribute("BRUSHSHADE",m_Doc->itemToolPrefs().shapeFillColorShade);
484 	docu.writeAttribute("CPICT",m_Doc->itemToolPrefs().imageFillColor);
485 	docu.writeAttribute("PICTSHADE",m_Doc->itemToolPrefs().imageFillColorShade);
486 	docu.writeAttribute("CSPICT",m_Doc->itemToolPrefs().imageStrokeColor);
487 	docu.writeAttribute("PICTSSHADE",m_Doc->itemToolPrefs().imageStrokeColorShade);
488 	docu.writeAttribute("PICTSCX",m_Doc->itemToolPrefs().imageScaleX);
489 	docu.writeAttribute("PICTSCY",m_Doc->itemToolPrefs().imageScaleY);
490 	docu.writeAttribute("PSCALE", static_cast<int>(m_Doc->itemToolPrefs().imageScaleType));
491 	docu.writeAttribute("PASPECT", static_cast<int>(m_Doc->itemToolPrefs().imageAspectRatio));
492 	docu.writeAttribute("EmbeddedPath", static_cast<int>(m_Doc->itemToolPrefs().imageUseEmbeddedPath));
493 	docu.writeAttribute("HalfRes", m_Doc->itemToolPrefs().imageLowResType);
494 	docu.writeAttribute("dispX", m_Doc->opToolPrefs().dispX);
495 	docu.writeAttribute("dispY", m_Doc->opToolPrefs().dispY);
496 	docu.writeAttribute("constrain", m_Doc->opToolPrefs().constrain);
497 	docu.writeAttribute("MINORC",m_Doc->guidesPrefs().minorGridColor.name());
498 	docu.writeAttribute("MAJORC",m_Doc->guidesPrefs().majorGridColor.name());
499 	docu.writeAttribute("GuideC", m_Doc->guidesPrefs().guideColor.name());
500 	docu.writeAttribute("BaseC", m_Doc->guidesPrefs().baselineGridColor.name());
501 	QString renderStack = "";
502 	int renderStackCount = m_Doc->guidesPrefs().renderStackOrder.count();
503 	for (int r = 0; r < renderStackCount; r++)
504 	{
505 		renderStack += QString("%1 ").arg(m_Doc->guidesPrefs().renderStackOrder[r]);
506 	}
507 	docu.writeAttribute("renderStack", renderStack.trimmed());
508 	docu.writeAttribute("GridType", m_Doc->guidesPrefs().gridType);
509 	docu.writeAttribute("PAGEC",m_Doc->paperColor().name());
510 	docu.writeAttribute("MARGC",m_Doc->guidesPrefs().marginColor.name());
511 	docu.writeAttribute("RANDF", static_cast<int>(m_Doc->marginColored()));
512 	docu.writeAttribute("currentProfile", m_Doc->curCheckProfile());
513 	docu.writeAttribute("calligraphicPenFillColor", m_Doc->itemToolPrefs().calligraphicPenFillColor);
514 	docu.writeAttribute("calligraphicPenLineColor", m_Doc->itemToolPrefs().calligraphicPenLineColor);
515 	docu.writeAttribute("calligraphicPenFillColorShade", m_Doc->itemToolPrefs().calligraphicPenFillColorShade);
516 	docu.writeAttribute("calligraphicPenLineColorShade", m_Doc->itemToolPrefs().calligraphicPenLineColorShade);
517 	docu.writeAttribute("calligraphicPenLineWidth", m_Doc->itemToolPrefs().calligraphicPenLineWidth);
518 	docu.writeAttribute("calligraphicPenAngle", m_Doc->itemToolPrefs().calligraphicPenAngle);
519 	docu.writeAttribute("calligraphicPenWidth", m_Doc->itemToolPrefs().calligraphicPenWidth);
520 	docu.writeAttribute("calligraphicPenStyle", m_Doc->itemToolPrefs().calligraphicPenStyle);
521 
522 	writeCheckerProfiles(docu);
523 	writeJavascripts(docu);
524 	writeBookmarks(docu);
525 	writeColors(docu);
526 	writeGradients(docu);
527 	writeHyphenatorLists(docu);
528 	writeCharStyles(docu);
529 	writeParagraphStyles(docu);
530 	writeTableStyles(docu);
531 	writeCellStyles(docu);
532 	writeLineStyles(docu);
533 	writeArrowStyles(docu);
534 	writeLayers(docu);
535 	writePrintOptions(docu);
536 	writePdfOptions(docu);
537 	writeDocItemAttributes(docu);
538 	writeTOC(docu);
539 	writeMarks(docu);
540 	writeNotesStyles(docu);
541 	writeNotesFrames(docu);
542 	writeNotes(docu);
543 	writePageSets(docu);
544 	writeSections(docu);
545 	writePatterns(docu, fileDir);
546 	writeContent(docu, fileDir);
547 
548 	docu.writeEndElement();
549 	docu.writeEndDocument();
550 
551 	bool  writeSucceed = false;
552 	const QFile* qFile = qobject_cast<QFile*>(outputFile.data());
553 	if (qFile)
554 		writeSucceed = (qFile->error() == QFile::NoError);
555 	else
556 		writeSucceed = true;
557 	outputFile->close();
558 
559 	if (writeSucceed)
560 	{
561 		if (QFile::exists(fileName))
562 			writeSucceed = QFile::remove(fileName) ? QFile::rename(tmpFileName, fileName) : false;
563 		else
564 			writeSucceed = QFile::rename(tmpFileName, fileName);
565 		m_lastSavedFile = writeSucceed ? fileName : tmpFileName;
566 	}
567 	else if (QFile::exists(tmpFileName))
568 		QFile::remove(tmpFileName);
569 	if (writeSucceed)
570 		QFile::remove(tmpFileName);
571 #ifdef Q_OS_UNIX
572 	if (writeSucceed)
573 		QFile::setPermissions(fileName, m_Doc->filePermissions());
574 #endif
575 	return writeSucceed;
576 }
577 
writeCheckerProfiles(ScXmlStreamWriter & docu)578 void Scribus150Format::writeCheckerProfiles(ScXmlStreamWriter & docu)
579 {
580 	CheckerPrefsList::Iterator itcp;
581 	CheckerPrefsList::Iterator itcpend=m_Doc->checkerProfiles().end();
582 	for (itcp = m_Doc->checkerProfiles().begin(); itcp != itcpend; ++itcp)
583 	{
584 		docu.writeEmptyElement("CheckProfile");
585 		docu.writeAttribute("Name",itcp.key());
586 		docu.writeAttribute("ignoreErrors", static_cast<int>(itcp.value().ignoreErrors));
587 		docu.writeAttribute("autoCheck", static_cast<int>(itcp.value().autoCheck));
588 		docu.writeAttribute("checkGlyphs", static_cast<int>(itcp.value().checkGlyphs));
589 		docu.writeAttribute("checkOrphans", static_cast<int>(itcp.value().checkOrphans));
590 		docu.writeAttribute("checkOverflow", static_cast<int>(itcp.value().checkOverflow));
591 		docu.writeAttribute("checkPictures", static_cast<int>(itcp.value().checkPictures));
592 		docu.writeAttribute("checkPartFilledImageFrames", static_cast<int>(itcp.value().checkPartFilledImageFrames));
593 		docu.writeAttribute("checkResolution", static_cast<int>(itcp.value().checkResolution));
594 		docu.writeAttribute("checkTransparency", static_cast<int>(itcp.value().checkTransparency));
595 		docu.writeAttribute("minResolution",itcp.value().minResolution);
596 		docu.writeAttribute("maxResolution",itcp.value().maxResolution);
597 		docu.writeAttribute("checkAnnotations", static_cast<int>(itcp.value().checkAnnotations));
598 		docu.writeAttribute("checkRasterPDF", static_cast<int>(itcp.value().checkRasterPDF));
599 		docu.writeAttribute("checkForGIF", static_cast<int>(itcp.value().checkForGIF));
600 		docu.writeAttribute("ignoreOffLayers", static_cast<int>(itcp.value().ignoreOffLayers));
601 		docu.writeAttribute("checkNotCMYKOrSpot", static_cast<int>(itcp.value().checkNotCMYKOrSpot));
602 		docu.writeAttribute("checkDeviceColorsAndOutputIntent", static_cast<int>(itcp.value().checkDeviceColorsAndOutputIntent));
603 		docu.writeAttribute("checkFontNotEmbedded", static_cast<int>(itcp.value().checkFontNotEmbedded));
604 		docu.writeAttribute("checkFontIsOpenType", static_cast<int>(itcp.value().checkFontIsOpenType));
605 		docu.writeAttribute("checkAppliedMasterDifferentSide", static_cast<int>(itcp.value().checkAppliedMasterDifferentSide));
606 		docu.writeAttribute("checkEmptyTextFrames", static_cast<int>(itcp.value().checkEmptyTextFrames));
607 	}
608 }
609 
writeLineStyles(ScXmlStreamWriter & docu)610 void Scribus150Format::writeLineStyles(ScXmlStreamWriter& docu)
611 {
612 	QStringList styleNames = m_Doc->docLineStyles.keys();
613 	if (styleNames.isEmpty())
614 		return;
615 	writeLineStyles(docu, styleNames);
616 }
617 
writeLineStyles(ScXmlStreamWriter & docu,const QStringList & styleNames)618 void Scribus150Format::writeLineStyles(ScXmlStreamWriter& docu, const QStringList& styleNames)
619 {
620 	if (styleNames.isEmpty())
621 		return;
622 
623 	for (auto itMU = m_Doc->docLineStyles.begin(); itMU != m_Doc->docLineStyles.end(); ++itMU)
624 	{
625 		if (!styleNames.contains(itMU.key()))
626 			continue;
627 		docu.writeStartElement("MultiLine");
628 		docu.writeAttribute("Name", itMU.key());
629 		multiLine ml = itMU.value();
630 		for (auto itMU2 = ml.cbegin(); itMU2 != ml.cend(); ++itMU2)
631 		{
632 			docu.writeEmptyElement("SubLine");
633 			docu.writeAttribute("Color", itMU2->Color);
634 			docu.writeAttribute("Shade", itMU2->Shade);
635 			docu.writeAttribute("Dash", itMU2->Dash);
636 			docu.writeAttribute("LineEnd", itMU2->LineEnd);
637 			docu.writeAttribute("LineJoin", itMU2->LineJoin);
638 			docu.writeAttribute("Width", itMU2->Width);
639 			docu.writeAttribute("Shortcut", ml.shortcut);
640 		}
641 		docu.writeEndElement();
642 	}
643 }
644 
writeArrowStyles(ScXmlStreamWriter & docu)645 void Scribus150Format::writeArrowStyles(ScXmlStreamWriter& docu)
646 {
647 	const QList<ArrowDesc>& arrowStyles = m_Doc->arrowStyles();
648 	for (const ArrowDesc& arrow : arrowStyles)
649 	{
650 		if (!arrow.userArrow)
651 			continue;
652 		docu.writeEmptyElement("Arrows");
653 		docu.writeAttribute("NumPoints", arrow.points.size());
654 		QString arp;
655 		QString tmp, tmpy;
656 		double xa, ya;
657 		for (int nxx = 0; nxx < arrow.points.size(); ++nxx)
658 		{
659 			arrow.points.point(nxx, &xa, &ya);
660 			arp += tmp.setNum(xa) + " " + tmpy.setNum(ya) + " ";
661 		}
662 		docu.writeAttribute("Points", arp);
663 		docu.writeAttribute("Name", arrow.name);
664 	}
665 }
666 
writeJavascripts(ScXmlStreamWriter & docu)667 void Scribus150Format::writeJavascripts(ScXmlStreamWriter & docu)
668 {
669 	QMap<QString,QString>::Iterator itja;
670 	for (itja = m_Doc->JavaScripts.begin(); itja != m_Doc->JavaScripts.end(); ++itja)
671 	{
672 		docu.writeEmptyElement("JAVA");
673 		docu.writeAttribute("NAME",itja.key());
674 		docu.writeAttribute("SCRIPT",itja.value());
675 	}
676 
677 }
678 
679 
writeBookmarks(ScXmlStreamWriter & docu)680 void Scribus150Format::writeBookmarks(ScXmlStreamWriter & docu)
681 {
682 	QList<ScribusDoc::BookMa>::Iterator itbm;
683 	for (itbm = m_Doc->BookMarks.begin(); itbm != m_Doc->BookMarks.end(); ++itbm)
684 	{
685 		docu.writeEmptyElement("Bookmark");
686 		docu.writeAttribute("Title", itbm->Title);
687 		docu.writeAttribute("Text", itbm->Text);
688 		docu.writeAttribute("Aktion", itbm->Aktion);
689 		docu.writeAttribute("ItemNr", itbm->ItemNr);
690 		docu.writeAttribute("Element", qHash(itbm->PageObject) & 0x7FFFFFFF);
691 		docu.writeAttribute("First", itbm->First);
692 		docu.writeAttribute("Last", itbm->Last);
693 		docu.writeAttribute("Prev", itbm->Prev);
694 		docu.writeAttribute("Next", itbm->Next);
695 		docu.writeAttribute("Parent", itbm->Parent);
696 	}
697 }
698 
699 
writeColors(ScXmlStreamWriter & docu,bool part)700 void Scribus150Format::writeColors(ScXmlStreamWriter & docu, bool part)
701 {
702 	ColorList usedColors;
703 	if (part)
704 		m_Doc->getUsedColors(usedColors);
705 	else
706 		usedColors = m_Doc->PageColors;
707 	writeColors(docu, usedColors.keys());
708 }
709 
writeColors(ScXmlStreamWriter & docu,const QStringList & colorNames)710 void Scribus150Format::writeColors(ScXmlStreamWriter& docu, const QStringList& colorNames)
711 {
712 	for (const QString& colorName : colorNames)
713 	{
714 		if (colorName == CommonStrings::None)
715 			continue;
716 
717 		const ScColor& color = m_Doc->PageColors[colorName];
718 		docu.writeEmptyElement("COLOR");
719 		docu.writeAttribute("NAME", colorName);
720 		if (color.getColorModel() == colorModelRGB)
721 		{
722 			double r, g, b;
723 			color.getRGB(&r, &g, &b);
724 			docu.writeAttribute("SPACE", "RGB");
725 			docu.writeAttribute("R", r * 255.0);
726 			docu.writeAttribute("G", g * 255.0);
727 			docu.writeAttribute("B", b * 255.0);
728 		}
729 		else if (color.getColorModel() == colorModelCMYK)
730 		{
731 			double c, m, y, k;
732 			color.getCMYK(&c, &m, &y, &k);
733 			docu.writeAttribute("SPACE", "CMYK");
734 			docu.writeAttribute("C", c * 100.0);
735 			docu.writeAttribute("M", m * 100.0);
736 			docu.writeAttribute("Y", y * 100.0);
737 			docu.writeAttribute("K", k * 100.0);
738 		}
739 		else
740 		{
741 			double L, a, b;
742 			color.getLab(&L, &a, &b);
743 			docu.writeAttribute("SPACE", "Lab");
744 			docu.writeAttribute("L", L);
745 			docu.writeAttribute("A", a);
746 			docu.writeAttribute("B", b);
747 		}
748 		if (color.isSpotColor())
749 			docu.writeAttribute("Spot", static_cast<int>(color.isSpotColor()));
750 		if (color.isRegistrationColor())
751 			docu.writeAttribute("Register", static_cast<int>(color.isRegistrationColor()));
752 	}
753 }
754 
writeGradients(ScXmlStreamWriter & docu,bool part)755 void Scribus150Format::writeGradients(ScXmlStreamWriter& docu, bool part)
756 {
757 	QHash<QString, VGradient>::Iterator itGrad;
758 	QHash<QString, VGradient> gradMap;
759 	if (part)
760 		m_Doc->getUsedGradients(gradMap);
761 	else
762 		gradMap = m_Doc->docGradients;
763 	writeGradients(docu, gradMap.keys());
764 }
765 
writeGradients(ScXmlStreamWriter & docu,const QStringList & gradientNames)766 void Scribus150Format::writeGradients(ScXmlStreamWriter & docu, const QStringList& gradientNames)
767 {
768 	for (const QString& gradientName : gradientNames)
769 	{
770 		VGradient gradient = m_Doc->docGradients[gradientName];
771 		docu.writeStartElement("Gradient");
772 		docu.writeAttribute("Name", gradientName);
773 		docu.writeAttribute("Ext", gradient.repeatMethod());
774 		const QList<VColorStop*>& cstops = gradient.colorStops();
775 		for (int cst = 0; cst < gradient.stops(); ++cst)
776 		{
777 			docu.writeEmptyElement("CSTOP");
778 			docu.writeAttribute("RAMP", cstops.at(cst)->rampPoint);
779 			docu.writeAttribute("NAME", cstops.at(cst)->name);
780 			docu.writeAttribute("SHADE", cstops.at(cst)->shade);
781 			docu.writeAttribute("TRANS", cstops.at(cst)->opacity);
782 		}
783 		docu.writeEndElement();
784 	}
785 }
786 
writeHyphenatorLists(ScXmlStreamWriter & docu)787 void Scribus150Format::writeHyphenatorLists(ScXmlStreamWriter& docu)
788 {
789 	docu.writeStartElement("HYPHEN");
790 	for (QHash<QString, QString>::Iterator hyit = m_Doc->docHyphenator->specialWords.begin(); hyit != m_Doc->docHyphenator->specialWords.end(); ++hyit)
791 	{
792 		docu.writeEmptyElement("EXCEPTION");
793 		docu.writeAttribute("WORD", hyit.key());
794 		docu.writeAttribute("HYPHENATED", hyit.value());
795 	}
796 	for (QSet<QString>::Iterator hyit2 = m_Doc->docHyphenator->ignoredWords.begin(); hyit2 != m_Doc->docHyphenator->ignoredWords.end(); ++hyit2)
797 	{
798 		docu.writeEmptyElement("IGNORE");
799 		docu.writeAttribute("WORD", (*hyit2));
800 	}
801 	docu.writeEndElement();
802 }
803 
writeParagraphStyles(ScXmlStreamWriter & docu)804 void Scribus150Format::writeParagraphStyles(ScXmlStreamWriter & docu)
805 {
806 	QList<int> styleList = m_Doc->getSortedStyleList();
807 	for (int a = 0; a < styleList.count(); ++a)
808 	{
809 		putPStyle(docu, m_Doc->paragraphStyles()[styleList[a]], "STYLE");
810 	}
811 //	for (int ff = 0; ff < m_Doc->paragraphStyles().count(); ++ff)
812 //		putPStyle(docu, m_Doc->paragraphStyles()[ff], "STYLE");
813 }
814 
putPStyle(ScXmlStreamWriter & docu,const ParagraphStyle & style,const QString & nodeName)815 void Scribus150Format::putPStyle(ScXmlStreamWriter & docu, const ParagraphStyle & style, const QString &nodeName)
816 {
817 	bool styleHasTabs = (!style.isInhTabValues() && (style.tabValues().count() > 0));
818 	if (styleHasTabs)
819 		docu.writeStartElement(nodeName);
820 	else
821 		docu.writeEmptyElement(nodeName);
822 	if ( ! style.name().isEmpty() )
823 		docu.writeAttribute("NAME", style.name());
824 	if ( ! style.parent().isEmpty())
825 		docu.writeAttribute("PARENT", style.parent());
826 	if ( style.isDefaultStyle())
827 		docu.writeAttribute("DefaultStyle", style.isDefaultStyle());
828 
829 	if ( ! style.isInhAlignment())
830 		docu.writeAttribute("ALIGN", style.alignment());
831 	if ( ! style.isInhDirection())
832 		docu.writeAttribute("DIRECTION", style.direction());
833 	if ( ! style.isInhLineSpacingMode())
834 		docu.writeAttribute("LINESPMode", style.lineSpacingMode());
835 	if ( ! style.isInhLineSpacing())
836 		docu.writeAttribute("LINESP", style.lineSpacing());
837 	if ( ! style.isInhLeftMargin())
838 		docu.writeAttribute("INDENT", style.leftMargin());
839 	if ( ! style.isInhRightMargin())
840 		docu.writeAttribute("RMARGIN", style.rightMargin());
841 	if ( ! style.isInhFirstIndent())
842 		docu.writeAttribute("FIRST", style.firstIndent());
843 	if ( ! style.isInhGapBefore())
844 		docu.writeAttribute("VOR", style.gapBefore());
845 	if ( ! style.isInhGapAfter())
846 		docu.writeAttribute("NACH", style.gapAfter());
847 	if ( ! style.isInhPeCharStyleName())
848 		docu.writeAttribute("ParagraphEffectCharStyle", style.peCharStyleName());
849 	if ( ! style.isInhParEffectOffset())
850 		docu.writeAttribute("ParagraphEffectOffset", style.parEffectOffset());
851 	if ( ! style.isInhParEffectIndent())
852 		docu.writeAttribute("ParagraphEffectIndent", static_cast<int>(style.parEffectIndent()));
853 	if ( ! style.isInhHasDropCap())
854 		docu.writeAttribute("DROP", static_cast<int>(style.hasDropCap()));
855 	if ( ! style.isInhDropCapLines())
856 		docu.writeAttribute("DROPLIN", style.dropCapLines());
857 	if ( ! style.isInhHasBullet())
858 		docu.writeAttribute("Bullet", static_cast<int>(style.hasBullet()));
859 	if ( ! style.isInhBulletStr())
860 		docu.writeAttribute("BulletStr", style.bulletStr());
861 	if ( ! style.isInhHasNum())
862 		docu.writeAttribute("Numeration", static_cast<int>(style.hasNum()));
863 	if ( ! style.isInhNumFormat())
864 		docu.writeAttribute("NumerationFormat", style.numFormat());
865 	if ( ! style.isInhNumName())
866 		docu.writeAttribute("NumerationName", style.numName());
867 	if ( ! style.isInhNumLevel())
868 		docu.writeAttribute("NumerationLevel", style.numLevel());
869 	if ( ! style.isInhNumPrefix())
870 		docu.writeAttribute("NumerationPrefix", style.numPrefix());
871 	if ( ! style.isInhNumSuffix())
872 		docu.writeAttribute("NumerationSuffix", style.numSuffix());
873 	if ( ! style.isInhNumStart())
874 		docu.writeAttribute("NumerationStart", style.numStart());
875 	if ( ! style.isInhNumRestart())
876 		docu.writeAttribute("NumerationRestart", style.numRestart());
877 	if ( ! style.isInhNumOther())
878 		docu.writeAttribute("NumerationOther", static_cast<int>(style.numOther()));
879 	if ( ! style.isInhNumHigher())
880 		docu.writeAttribute("NumerationHigher", static_cast<int>(style.numHigher()));
881 	if ( ! style.isInhOpticalMargins())
882 		docu.writeAttribute("OpticalMargins", style.opticalMargins());
883 	if ( ! style.isInhHyphenConsecutiveLines())
884 		docu.writeAttribute("HyphenConsecutiveLines", style.hyphenConsecutiveLines());
885 	if ( ! style.isInhHyphenationMode())
886 		docu.writeAttribute("HyphenationMode", style.hyphenationMode());
887 	if ( ! style.isInhMinWordTracking())
888 		docu.writeAttribute("MinWordTrack", style.minWordTracking());
889 	if ( ! style.isInhMinGlyphExtension())
890 		docu.writeAttribute("MinGlyphShrink", style.minGlyphExtension());
891 	if ( ! style.isInhMaxGlyphExtension())
892 		docu.writeAttribute("MaxGlyphExtend", style.maxGlyphExtension());
893 	if ( ! style.isInhKeepLinesStart())
894 		docu.writeAttribute("KeepLinesStart", style.keepLinesStart());
895 	if ( ! style.isInhKeepLinesEnd())
896 		docu.writeAttribute("KeepLinesEnd", style.keepLinesEnd());
897 	if ( ! style.isInhKeepWithNext())
898 		docu.writeAttribute("KeepWithNext", style.keepWithNext());
899 	if ( ! style.isInhKeepTogether())
900 		docu.writeAttribute("KeepTogether", style.keepTogether());
901 	if ( ! style.isInhBackgroundColor())
902 		docu.writeAttribute("BCOLOR", style.backgroundColor());
903 	if ( ! style.isInhBackgroundShade())
904 		docu.writeAttribute("BSHADE", style.backgroundShade());
905 
906 	if ( ! style.shortcut().isEmpty() )
907 		docu.writeAttribute("PSHORTCUT", style.shortcut()); // shortcuts won't be inherited
908 
909 	putCStyle(docu, style.charStyle());
910 
911 	if ( ! style.isInhTabValues())
912 	{
913 		for (int a = 0; a < style.tabValues().count(); ++a)
914 		{
915 			docu.writeEmptyElement("Tabs");
916 			docu.writeAttribute("Type", (style.tabValues().at(a)).tabType);
917 			docu.writeAttribute("Pos", (style.tabValues().at(a)).tabPosition);
918 			QString tabCh = "";
919 			if (!(style.tabValues().at(a)).tabFillChar.isNull())
920 				tabCh = QString((style.tabValues().at(a)).tabFillChar);
921 			docu.writeAttribute("Fill", tabCh);
922 		}
923 	}
924 
925 	if (styleHasTabs)
926 		docu.writeEndElement();
927 }
928 
929 
writeCharStyles(ScXmlStreamWriter & docu)930 void Scribus150Format::writeCharStyles(ScXmlStreamWriter & docu)
931 {
932 	QList<int> styleList = m_Doc->getSortedCharStyleList();
933 	for (int a = 0; a < styleList.count(); ++a)
934 	{
935 		docu.writeStartElement("CHARSTYLE");
936 		putNamedCStyle(docu, m_Doc->charStyles()[styleList[a]]);
937 		docu.writeEndElement();
938 	}
939 //	for (int ff = 0; ff < m_Doc->charStyles().count(); ++ff)
940 //	{
941 //		docu.writeStartElement("CHARSTYLE");
942 //		putNamedCStyle(docu, m_Doc->charStyles()[ff]);
943 //		docu.writeEndElement();
944 //	}
945 }
946 
putCStyle(ScXmlStreamWriter & docu,const CharStyle & style)947 void Scribus150Format::putCStyle(ScXmlStreamWriter & docu, const CharStyle & style)
948 {
949 	if ( ! style.parent().isEmpty() )
950 		docu.writeAttribute("CPARENT", style.parent());
951 	if ( ! style.isInhFont())
952 		docu.writeAttribute("FONT", style.font().scName());
953 	if ( ! style.isInhFontSize())
954 		docu.writeAttribute("FONTSIZE", style.fontSize() / 10.0);
955 	if ( ! style.isInhFontFeatures())
956 		docu.writeAttribute("FONTFEATURES", style.fontFeatures());
957 	if ( ! style.isInhFeatures())
958 		docu.writeAttribute("FEATURES", style.features().join(" "));
959 	if ( ! style.isInhFillColor())
960 		docu.writeAttribute("FCOLOR", style.fillColor());
961 	if ( ! style.isInhFillShade())
962 		docu.writeAttribute("FSHADE", style.fillShade());
963 	if ( ! style.isInhHyphenChar())
964 		docu.writeAttribute("HyphenChar", style.hyphenChar());
965 	if ( ! style.isInhHyphenWordMin())
966 		docu.writeAttribute("HyphenWordMin", style.hyphenWordMin());
967 	if ( ! style.isInhStrokeColor())
968 		docu.writeAttribute("SCOLOR", style.strokeColor());
969 	if ( ! style.isInhBackColor())
970 		docu.writeAttribute("BGCOLOR", style.backColor());
971 	if ( ! style.isInhBackShade())
972 		docu.writeAttribute("BGSHADE", style.backShade());
973 	if ( ! style.isInhStrokeShade())
974 		docu.writeAttribute("SSHADE", style.strokeShade());
975 	if ( ! style.isInhShadowXOffset())
976 		docu.writeAttribute("TXTSHX", style.shadowXOffset() / 10.0);
977 	if ( ! style.isInhShadowYOffset())
978 		docu.writeAttribute("TXTSHY", style.shadowYOffset() / 10.0);
979 	if ( ! style.isInhOutlineWidth())
980 		docu.writeAttribute("TXTOUT", style.outlineWidth() / 10.0);
981 	if ( ! style.isInhUnderlineOffset())
982 		docu.writeAttribute("TXTULP", style.underlineOffset() / 10.0);
983 	if ( ! style.isInhUnderlineWidth())
984 		docu.writeAttribute("TXTULW", style.underlineWidth() / 10.0);
985 	if ( ! style.isInhStrikethruOffset())
986 		docu.writeAttribute("TXTSTP", style.strikethruOffset() / 10.0);
987 	if ( ! style.isInhStrikethruWidth())
988 		docu.writeAttribute("TXTSTW", style.strikethruWidth() / 10.0);
989 	if ( ! style.isInhScaleH())
990 		docu.writeAttribute("SCALEH", style.scaleH() / 10.0);
991 	if ( ! style.isInhScaleV())
992 		docu.writeAttribute("SCALEV", style.scaleV() / 10.0);
993 	if ( ! style.isInhBaselineOffset())
994 		docu.writeAttribute("BASEO", style.baselineOffset() / 10.0);
995 	if ( ! style.isInhTracking())
996 		docu.writeAttribute("KERN", style.tracking() / 10.0);
997 	if ( ! style.isInhWordTracking())
998 		docu.writeAttribute("wordTrack", style.wordTracking());
999 	if ( ! style.isInhLanguage())
1000 		docu.writeAttribute("LANGUAGE", style.language());
1001 	if ( ! style.shortcut().isEmpty() )
1002 		docu.writeAttribute("SHORTCUT", style.shortcut()); // shortcuts won't be inherited
1003 }
1004 
putNamedCStyle(ScXmlStreamWriter & docu,const CharStyle & style)1005 void Scribus150Format::putNamedCStyle(ScXmlStreamWriter& docu, const CharStyle & style)
1006 {
1007 	if ( ! style.name().isEmpty() )
1008 		docu.writeAttribute("CNAME", style.name());
1009 	if ( style.hasName() && style.isDefaultStyle())
1010 		docu.writeAttribute("DefaultStyle", style.isDefaultStyle());
1011 	putCStyle(docu, style);
1012 }
1013 
writeTableStyles(ScXmlStreamWriter & docu)1014 void Scribus150Format::writeTableStyles(ScXmlStreamWriter& docu)
1015 {
1016 	QList<int> styleList = m_Doc->getSortedTableStyleList();
1017 	for (int i = 0; i < styleList.count(); ++i)
1018 	{
1019 		docu.writeStartElement("TableStyle");
1020 		putTableStyle(docu, m_Doc->tableStyles()[styleList[i]]);
1021 		docu.writeEndElement();
1022 	}
1023 }
1024 
writeCellStyles(ScXmlStreamWriter & docu)1025 void Scribus150Format::writeCellStyles(ScXmlStreamWriter& docu)
1026 {
1027 	QList<int> styleList = m_Doc->getSortedCellStyleList();
1028 	for (int i = 0; i < styleList.count(); ++i)
1029 	{
1030 		docu.writeStartElement("CellStyle");
1031 		putCellStyle(docu, m_Doc->cellStyles()[styleList[i]]);
1032 		docu.writeEndElement();
1033 	}
1034 }
1035 
putTableStyle(ScXmlStreamWriter & docu,const TableStyle & style)1036 void Scribus150Format::putTableStyle(ScXmlStreamWriter &docu, const TableStyle &style)
1037 {
1038 	if ( ! style.name().isEmpty() )
1039 		docu.writeAttribute("NAME", style.name());
1040 	if ( style.hasName() && style.isDefaultStyle())
1041 		docu.writeAttribute("DefaultStyle", style.isDefaultStyle());
1042 	if ( ! style.parent().isEmpty() )
1043 		docu.writeAttribute("PARENT", style.parent());
1044 	if ( ! style.isInhFillColor())
1045 		docu.writeAttribute("FillColor", style.fillColor());
1046 	if ( ! style.isInhFillShade())
1047 		docu.writeAttribute("FillShade", style.fillShade());
1048 	if ( ! style.isInhLeftBorder())
1049 	{
1050 		const TableBorder& tbLeft = style.leftBorder();
1051 		docu.writeStartElement("TableBorderLeft");
1052 		for (const TableBorderLine& tbl : tbLeft.borderLines())
1053 		{
1054 			docu.writeStartElement("TableBorderLine");
1055 			docu.writeAttribute("Width", tbl.width());
1056 			docu.writeAttribute("PenStyle", tbl.style());
1057 			docu.writeAttribute("Color", tbl.color());
1058 			docu.writeAttribute("Shade", tbl.shade());
1059 			docu.writeEndElement();
1060 		}
1061 		docu.writeEndElement();
1062 	}
1063 	if ( ! style.isInhRightBorder())
1064 	{
1065 		const TableBorder& tbRight = style.rightBorder();
1066 		docu.writeStartElement("TableBorderRight");
1067 		for (const TableBorderLine& tbl : tbRight.borderLines())
1068 		{
1069 			docu.writeStartElement("TableBorderLine");
1070 			docu.writeAttribute("Width", tbl.width());
1071 			docu.writeAttribute("PenStyle", tbl.style());
1072 			docu.writeAttribute("Color", tbl.color());
1073 			docu.writeAttribute("Shade", tbl.shade());
1074 			docu.writeEndElement();
1075 		}
1076 		docu.writeEndElement();
1077 	}
1078 	if ( ! style.isInhTopBorder())
1079 	{
1080 		const TableBorder& tbTop = style.topBorder();
1081 		docu.writeStartElement("TableBorderTop");
1082 		for (const TableBorderLine& tbl : tbTop.borderLines())
1083 		{
1084 			docu.writeStartElement("TableBorderLine");
1085 			docu.writeAttribute("Width", tbl.width());
1086 			docu.writeAttribute("PenStyle", tbl.style());
1087 			docu.writeAttribute("Color", tbl.color());
1088 			docu.writeAttribute("Shade", tbl.shade());
1089 			docu.writeEndElement();
1090 		}
1091 		docu.writeEndElement();
1092 	}
1093 	if ( ! style.isInhBottomBorder())
1094 	{
1095 		const TableBorder& tbBottom = style.bottomBorder();
1096 		docu.writeStartElement("TableBorderBottom");
1097 		for (const TableBorderLine& tbl : tbBottom.borderLines())
1098 		{
1099 			docu.writeStartElement("TableBorderLine");
1100 			docu.writeAttribute("Width", tbl.width());
1101 			docu.writeAttribute("PenStyle", tbl.style());
1102 			docu.writeAttribute("Color", tbl.color());
1103 			docu.writeAttribute("Shade", tbl.shade());
1104 			docu.writeEndElement();
1105 		}
1106 		docu.writeEndElement();
1107 	}
1108 }
1109 
putCellStyle(ScXmlStreamWriter & docu,const CellStyle & style)1110 void Scribus150Format::putCellStyle(ScXmlStreamWriter &docu, const CellStyle &style)
1111 {
1112 	if ( ! style.name().isEmpty() )
1113 		docu.writeAttribute("NAME", style.name());
1114 	if ( style.hasName() && style.isDefaultStyle())
1115 		docu.writeAttribute("DefaultStyle", style.isDefaultStyle());
1116 	if ( ! style.parent().isEmpty() )
1117 		docu.writeAttribute("PARENT", style.parent());
1118 	if ( ! style.isInhFillColor())
1119 		docu.writeAttribute("FillColor", style.fillColor());
1120 	if ( ! style.isInhFillShade())
1121 		docu.writeAttribute("FillShade", style.fillShade());
1122 	if ( ! style.isInhLeftPadding())
1123 		docu.writeAttribute("LeftPadding",style.leftPadding());
1124 	if ( ! style.isInhRightPadding())
1125 		docu.writeAttribute("RightPadding", style.rightPadding());
1126 	if ( ! style.isInhTopPadding())
1127 		docu.writeAttribute("TopPadding",style.topPadding());
1128 	if ( ! style.isInhBottomPadding())
1129 		docu.writeAttribute("BottomPadding", style.bottomPadding());
1130 	if ( ! style.isInhLeftBorder())
1131 	{
1132 		const TableBorder& tbLeft = style.leftBorder();
1133 		docu.writeStartElement("TableBorderLeft");
1134 		for (const TableBorderLine& tbl : tbLeft.borderLines())
1135 		{
1136 			docu.writeStartElement("TableBorderLine");
1137 			docu.writeAttribute("Width", tbl.width());
1138 			docu.writeAttribute("PenStyle", tbl.style());
1139 			docu.writeAttribute("Color", tbl.color());
1140 			docu.writeAttribute("Shade", tbl.shade());
1141 			docu.writeEndElement();
1142 		}
1143 		docu.writeEndElement();
1144 	}
1145 	if ( ! style.isInhRightBorder())
1146 	{
1147 		const TableBorder& tbRight = style.rightBorder();
1148 		docu.writeStartElement("TableBorderRight");
1149 		for (const TableBorderLine& tbl : tbRight.borderLines())
1150 		{
1151 			docu.writeStartElement("TableBorderLine");
1152 			docu.writeAttribute("Width", tbl.width());
1153 			docu.writeAttribute("PenStyle", tbl.style());
1154 			docu.writeAttribute("Color", tbl.color());
1155 			docu.writeAttribute("Shade", tbl.shade());
1156 			docu.writeEndElement();
1157 		}
1158 		docu.writeEndElement();
1159 	}
1160 	if ( ! style.isInhTopBorder())
1161 	{
1162 		const TableBorder& tbTop = style.topBorder();
1163 		docu.writeStartElement("TableBorderTop");
1164 		for (const TableBorderLine& tbl : tbTop.borderLines())
1165 		{
1166 			docu.writeStartElement("TableBorderLine");
1167 			docu.writeAttribute("Width", tbl.width());
1168 			docu.writeAttribute("PenStyle", tbl.style());
1169 			docu.writeAttribute("Color", tbl.color());
1170 			docu.writeAttribute("Shade", tbl.shade());
1171 			docu.writeEndElement();
1172 		}
1173 		docu.writeEndElement();
1174 	}
1175 	if ( ! style.isInhBottomBorder())
1176 	{
1177 		const TableBorder& tbBottom = style.bottomBorder();
1178 		docu.writeStartElement("TableBorderBottom");
1179 		for (const TableBorderLine& tbl : tbBottom.borderLines())
1180 		{
1181 			docu.writeStartElement("TableBorderLine");
1182 			docu.writeAttribute("Width", tbl.width());
1183 			docu.writeAttribute("PenStyle", tbl.style());
1184 			docu.writeAttribute("Color", tbl.color());
1185 			docu.writeAttribute("Shade", tbl.shade());
1186 			docu.writeEndElement();
1187 		}
1188 		docu.writeEndElement();
1189 	}
1190 }
1191 
writeLayers(ScXmlStreamWriter & docu)1192 void Scribus150Format::writeLayers(ScXmlStreamWriter & docu)
1193 {
1194 	uint layerCount=m_Doc->layerCount();
1195 	for (uint lay = 0; lay < layerCount; ++lay)
1196 	{
1197 		docu.writeEmptyElement("LAYERS");
1198 		docu.writeAttribute("NUMMER",m_Doc->Layers[lay].ID);
1199 		docu.writeAttribute("LEVEL",m_Doc->Layers[lay].Level);
1200 		docu.writeAttribute("NAME",m_Doc->Layers[lay].Name);
1201 		docu.writeAttribute("SICHTBAR", static_cast<int>(m_Doc->Layers[lay].isViewable));
1202 		docu.writeAttribute("DRUCKEN", static_cast<int>(m_Doc->Layers[lay].isPrintable));
1203 		docu.writeAttribute("EDIT", static_cast<int>(m_Doc->Layers[lay].isEditable));
1204 		docu.writeAttribute("SELECT", static_cast<int>(m_Doc->Layers[lay].isSelectable));
1205 		docu.writeAttribute("FLOW", static_cast<int>(m_Doc->Layers[lay].flowControl));
1206 		docu.writeAttribute("TRANS", m_Doc->Layers[lay].transparency);
1207 		docu.writeAttribute("BLEND", m_Doc->Layers[lay].blendMode);
1208 		docu.writeAttribute("OUTL", static_cast<int>(m_Doc->Layers[lay].outlineMode));
1209 		docu.writeAttribute("LAYERC",m_Doc->Layers[lay].markerColor.name());
1210 	}
1211 }
1212 
writePrintOptions(ScXmlStreamWriter & docu)1213 void Scribus150Format::writePrintOptions(ScXmlStreamWriter & docu)
1214 {
1215 	docu.writeStartElement("Printer");
1216 	docu.writeAttribute("firstUse", static_cast<int>(m_Doc->Print_Options.firstUse));
1217 	docu.writeAttribute("toFile", static_cast<int>(m_Doc->Print_Options.toFile));
1218 	docu.writeAttribute("useAltPrintCommand", static_cast<int>(m_Doc->Print_Options.useAltPrintCommand));
1219 	docu.writeAttribute("outputSeparations", static_cast<int>(m_Doc->Print_Options.outputSeparations));
1220 	docu.writeAttribute("useSpotColors", static_cast<int>(m_Doc->Print_Options.useSpotColors));
1221 	docu.writeAttribute("useColor", static_cast<int>(m_Doc->Print_Options.useColor));
1222 	docu.writeAttribute("mirrorH", static_cast<int>(m_Doc->Print_Options.mirrorH));
1223 	docu.writeAttribute("mirrorV", static_cast<int>(m_Doc->Print_Options.mirrorV));
1224 	docu.writeAttribute("useICC", static_cast<int>(m_Doc->cmsSettings().CMSinUse)); // Not used anymore, only for backward compatibility
1225 	docu.writeAttribute("doGCR", static_cast<int>(m_Doc->Print_Options.doGCR));
1226 	docu.writeAttribute("doClip", static_cast<int>(m_Doc->Print_Options.doClip));
1227 	docu.writeAttribute("setDevParam", static_cast<int>(m_Doc->Print_Options.setDevParam));
1228 	docu.writeAttribute("useDocBleeds", static_cast<int>(m_Doc->Print_Options.useDocBleeds));
1229 	docu.writeAttribute("cropMarks", static_cast<int>(m_Doc->Print_Options.cropMarks));
1230 	docu.writeAttribute("bleedMarks", static_cast<int>(m_Doc->Print_Options.bleedMarks));
1231 	docu.writeAttribute("registrationMarks", static_cast<int>(m_Doc->Print_Options.registrationMarks));
1232 	docu.writeAttribute("colorMarks", static_cast<int>(m_Doc->Print_Options.colorMarks));
1233 	docu.writeAttribute("includePDFMarks", static_cast<int>(m_Doc->Print_Options.includePDFMarks));
1234 	docu.writeAttribute("PSLevel", (int) ((m_Doc->Print_Options.prnLanguage < PrintLanguage::WindowsGDI) ? m_Doc->Print_Options.prnLanguage : PrintLanguage::PostScript3));
1235 	docu.writeAttribute("PrintEngine" , (int) m_Doc->Print_Options.prnLanguage);
1236 	docu.writeAttribute("markLength" , m_Doc->Print_Options.markLength);
1237 	docu.writeAttribute("markOffset" , m_Doc->Print_Options.markOffset);
1238 	docu.writeAttribute("BleedTop"   , m_Doc->Print_Options.bleeds.top());
1239 	docu.writeAttribute("BleedLeft"  , m_Doc->Print_Options.bleeds.left());
1240 	docu.writeAttribute("BleedRight" , m_Doc->Print_Options.bleeds.right());
1241 	docu.writeAttribute("BleedBottom", m_Doc->Print_Options.bleeds.bottom());
1242 	docu.writeAttribute("printer" , m_Doc->Print_Options.printer);
1243 	docu.writeAttribute("filename", m_Doc->Print_Options.filename);
1244 	docu.writeAttribute("separationName", m_Doc->Print_Options.separationName);
1245 	docu.writeAttribute("printerCommand", m_Doc->Print_Options.printerCommand);
1246 	for (int i = 0; i < m_Doc->Print_Options.allSeparations.count(); ++i)
1247 	{
1248 		docu.writeEmptyElement("Separation");
1249 		docu.writeAttribute("Name", m_Doc->Print_Options.allSeparations[i]);
1250 	}
1251 	docu.writeEndElement();
1252 }
1253 
writePdfOptions(ScXmlStreamWriter & docu)1254 void Scribus150Format::writePdfOptions(ScXmlStreamWriter & docu)
1255 {
1256 	docu.writeStartElement("PDF");
1257 	docu.writeAttribute("firstUse", static_cast<int>(m_Doc->pdfOptions().firstUse));
1258 	docu.writeAttribute("Thumbnails", static_cast<int>(m_Doc->pdfOptions().Thumbnails));
1259 	docu.writeAttribute("Articles", static_cast<int>(m_Doc->pdfOptions().Articles));
1260 	docu.writeAttribute("Bookmarks", static_cast<int>(m_Doc->pdfOptions().Bookmarks));
1261 	docu.writeAttribute("Compress", static_cast<int>(m_Doc->pdfOptions().Compress));
1262 	docu.writeAttribute("CMethod", m_Doc->pdfOptions().CompressMethod);
1263 	docu.writeAttribute("Quality", m_Doc->pdfOptions().Quality);
1264 	docu.writeAttribute("EmbedPDF", static_cast<int>(m_Doc->pdfOptions().embedPDF));
1265 	docu.writeAttribute("MirrorH", static_cast<int>(m_Doc->pdfOptions().MirrorH));
1266 	docu.writeAttribute("MirrorV", static_cast<int>(m_Doc->pdfOptions().MirrorV));
1267 	docu.writeAttribute("Clip", static_cast<int>(m_Doc->pdfOptions().doClip));
1268 	docu.writeAttribute("rangeSel", m_Doc->pdfOptions().pageRangeSelection);
1269 	docu.writeAttribute("rangeTxt", m_Doc->pdfOptions().pageRangeString);
1270 	docu.writeAttribute("RotateDeg", static_cast<int>(m_Doc->pdfOptions().RotateDeg));
1271 	docu.writeAttribute("PresentMode", static_cast<int>(m_Doc->pdfOptions().PresentMode));
1272 	docu.writeAttribute("RecalcPic", static_cast<int>(m_Doc->pdfOptions().RecalcPic));
1273 	docu.writeAttribute("FontEmbedding", static_cast<int>(m_Doc->pdfOptions().FontEmbedding));
1274 	docu.writeAttribute("Grayscale", static_cast<int>(m_Doc->pdfOptions().isGrayscale));
1275 	docu.writeAttribute("RGBMode", static_cast<int>(m_Doc->pdfOptions().UseRGB));
1276 	docu.writeAttribute("UseProfiles", static_cast<int>(m_Doc->pdfOptions().UseProfiles));
1277 	docu.writeAttribute("UseProfiles2", static_cast<int>(m_Doc->pdfOptions().UseProfiles2));
1278 	docu.writeAttribute("Binding", m_Doc->pdfOptions().Binding);
1279 	docu.writeAttribute("PicRes", m_Doc->pdfOptions().PicRes);
1280 	docu.writeAttribute("Resolution", m_Doc->pdfOptions().Resolution);
1281 	docu.writeAttribute("Version", m_Doc->pdfOptions().Version);
1282 	docu.writeAttribute("Intent", m_Doc->pdfOptions().Intent);
1283 	docu.writeAttribute("Intent2", m_Doc->pdfOptions().Intent2);
1284 	docu.writeAttribute("SolidP", m_Doc->pdfOptions().SolidProf);
1285 	docu.writeAttribute("ImageP", m_Doc->pdfOptions().ImageProf);
1286 	docu.writeAttribute("PrintP", m_Doc->pdfOptions().PrintProf);
1287 	docu.writeAttribute("InfoString", m_Doc->pdfOptions().Info);
1288 	docu.writeAttribute("BTop", m_Doc->pdfOptions().bleeds.top());
1289 	docu.writeAttribute("BLeft", m_Doc->pdfOptions().bleeds.left());
1290 	docu.writeAttribute("BRight", m_Doc->pdfOptions().bleeds.right());
1291 	docu.writeAttribute("BBottom", m_Doc->pdfOptions().bleeds.bottom());
1292 	docu.writeAttribute("useDocBleeds", static_cast<int>(m_Doc->pdfOptions().useDocBleeds));
1293 	docu.writeAttribute("cropMarks", static_cast<int>(m_Doc->pdfOptions().cropMarks));
1294 	docu.writeAttribute("bleedMarks", static_cast<int>(m_Doc->pdfOptions().bleedMarks));
1295 	docu.writeAttribute("registrationMarks", static_cast<int>(m_Doc->pdfOptions().registrationMarks));
1296 	docu.writeAttribute("colorMarks", static_cast<int>(m_Doc->pdfOptions().colorMarks));
1297 	docu.writeAttribute("docInfoMarks", static_cast<int>(m_Doc->pdfOptions().docInfoMarks));
1298 	docu.writeAttribute("markLength", m_Doc->pdfOptions().markLength);
1299 	docu.writeAttribute("markOffset", m_Doc->pdfOptions().markOffset);
1300 	docu.writeAttribute("ImagePr", static_cast<int>(m_Doc->pdfOptions().EmbeddedI));
1301 	docu.writeAttribute("PassOwner", m_Doc->pdfOptions().PassOwner);
1302 	docu.writeAttribute("PassUser", m_Doc->pdfOptions().PassUser);
1303 	docu.writeAttribute("Permissions", m_Doc->pdfOptions().Permissions);
1304 	docu.writeAttribute("Encrypt", static_cast<int>(m_Doc->pdfOptions().Encrypt));
1305 	docu.writeAttribute("UseLayers", static_cast<int>(m_Doc->pdfOptions().useLayers));
1306 	docu.writeAttribute("UseLpi", static_cast<int>(m_Doc->pdfOptions().UseLPI));
1307 	docu.writeAttribute("UseSpotColors", static_cast<int>(m_Doc->pdfOptions().UseSpotColors));
1308 	docu.writeAttribute("doMultiFile", static_cast<int>(m_Doc->pdfOptions().doMultiFile));
1309 	docu.writeAttribute("displayBookmarks", static_cast<int>(m_Doc->pdfOptions().displayBookmarks));
1310 	docu.writeAttribute("displayFullscreen", static_cast<int>(m_Doc->pdfOptions().displayFullscreen));
1311 	docu.writeAttribute("displayLayers", static_cast<int>(m_Doc->pdfOptions().displayLayers));
1312 	docu.writeAttribute("displayThumbs", static_cast<int>(m_Doc->pdfOptions().displayThumbs));
1313 	docu.writeAttribute("hideMenuBar", static_cast<int>(m_Doc->pdfOptions().hideMenuBar));
1314 	docu.writeAttribute("hideToolBar", static_cast<int>(m_Doc->pdfOptions().hideToolBar));
1315 	docu.writeAttribute("fitWindow", static_cast<int>(m_Doc->pdfOptions().fitWindow));
1316 	docu.writeAttribute("openAfterExport", static_cast<int>(m_Doc->pdfOptions().openAfterExport));
1317 	docu.writeAttribute("PageLayout", m_Doc->pdfOptions().PageLayout);
1318 	docu.writeAttribute("openAction", m_Doc->pdfOptions().openAction);
1319 
1320 	const QList<QString>& embedList = m_Doc->pdfOptions().EmbedList;
1321 	for (int pdoF = 0; pdoF < embedList.count(); ++pdoF)
1322 	{
1323 		docu.writeEmptyElement("Fonts");
1324 		docu.writeAttribute("Name", embedList.at(pdoF));
1325 	}
1326 
1327 	const QList<QString>& subsetList = m_Doc->pdfOptions().SubsetList;
1328 	for (int pdoS = 0; pdoS < subsetList.count(); ++pdoS)
1329 	{
1330 		docu.writeEmptyElement("Subset");
1331 		docu.writeAttribute("Name", subsetList.at(pdoS));
1332 	}
1333 
1334 	QMap<QString,LPIData>::Iterator itlp;
1335 	for (itlp = m_Doc->pdfOptions().LPISettings.begin(); itlp != m_Doc->pdfOptions().LPISettings.end(); ++itlp)
1336 	{
1337 		docu.writeEmptyElement("LPI");
1338 		docu.writeAttribute("Color", itlp.key());
1339 		docu.writeAttribute("Frequency", itlp.value().Frequency);
1340 		docu.writeAttribute("Angle", itlp.value().Angle);
1341 		docu.writeAttribute("SpotFunction", itlp.value().SpotFunc);
1342 	}
1343 	docu.writeEndElement();
1344 }
1345 
writeDocItemAttributes(ScXmlStreamWriter & docu)1346 void Scribus150Format::writeDocItemAttributes(ScXmlStreamWriter & docu)
1347 {
1348 	docu.writeStartElement("DocItemAttributes");
1349 	for (ObjAttrVector::Iterator objAttrIt = m_Doc->itemAttributes().begin() ; objAttrIt != m_Doc->itemAttributes().end(); ++objAttrIt )
1350 	{
1351 		docu.writeEmptyElement("ItemAttribute");
1352 		docu.writeAttribute("Name", objAttrIt->name);
1353 		docu.writeAttribute("Type", objAttrIt->type);
1354 		docu.writeAttribute("Value", objAttrIt->value);
1355 		docu.writeAttribute("Parameter", objAttrIt->parameter);
1356 		docu.writeAttribute("Relationship", objAttrIt->relationship);
1357 		docu.writeAttribute("RelationshipTo", objAttrIt->relationshipto);
1358 		docu.writeAttribute("AutoAddTo", objAttrIt->autoaddto);
1359 	}
1360 	docu.writeEndElement();
1361 }
1362 
1363 
writeTOC(ScXmlStreamWriter & docu)1364 void Scribus150Format::writeTOC(ScXmlStreamWriter & docu)
1365 {
1366 	docu.writeStartElement("TablesOfContents");
1367 	for (ToCSetupVector::Iterator tocSetupIt = m_Doc->tocSetups().begin() ; tocSetupIt != m_Doc->tocSetups().end(); ++tocSetupIt )
1368 	{
1369 		docu.writeEmptyElement("TableOfContents");
1370 		docu.writeAttribute("Name", tocSetupIt->name);
1371 		docu.writeAttribute("ItemAttributeName", tocSetupIt->itemAttrName);
1372 		docu.writeAttribute("FrameName", tocSetupIt->frameName);
1373 		docu.writeAttribute("ListNonPrinting", tocSetupIt->listNonPrintingFrames);
1374 		docu.writeAttribute("Style", tocSetupIt->textStyle);
1375 		switch (tocSetupIt->pageLocation)
1376 		{
1377 			case Beginning:
1378 				docu.writeAttribute("NumberPlacement", "Beginning");
1379 				break;
1380 			case End:
1381 				docu.writeAttribute("NumberPlacement", "End");
1382 				break;
1383 			case NotShown:
1384 				docu.writeAttribute("NumberPlacement", "NotShown");
1385 				break;
1386 		}
1387 	}
1388 	docu.writeEndElement();
1389 }
1390 
1391 
writeSections(ScXmlStreamWriter & docu)1392 void Scribus150Format::writeSections(ScXmlStreamWriter & docu)
1393 {
1394 	docu.writeStartElement("Sections");
1395 	for (DocumentSectionMap::Iterator it = m_Doc->sections().begin() ; it != m_Doc->sections().end(); ++it )
1396 	{
1397 		docu.writeEmptyElement("Section");
1398 		docu.writeAttribute("Number", (*it).number);
1399 		docu.writeAttribute("Name", (*it).name);
1400 		docu.writeAttribute("From", (*it).fromindex);
1401 		docu.writeAttribute("To", (*it).toindex);
1402 		switch ((*it).type)
1403 		{
1404 			case Type_1_2_3:
1405 				docu.writeAttribute("Type", "Type_1_2_3");
1406 				break;
1407 			case Type_1_2_3_ar:
1408 				docu.writeAttribute("Type", "Type_1_2_3_ar");
1409 				break;
1410 			case Type_i_ii_iii:
1411 				docu.writeAttribute("Type", "Type_i_ii_iii");
1412 				break;
1413 			case Type_I_II_III:
1414 				docu.writeAttribute("Type", "Type_I_II_III");
1415 				break;
1416 			case Type_a_b_c:
1417 				docu.writeAttribute("Type", "Type_a_b_c");
1418 				break;
1419 			case Type_A_B_C:
1420 				docu.writeAttribute("Type", "Type_A_B_C");
1421 				break;
1422 			case Type_Alphabet_ar:
1423 				docu.writeAttribute("Type", "Type_Alphabet_ar");
1424 				break;
1425 			case Type_Abjad_ar:
1426 				docu.writeAttribute("Type", "Type_Abjad_ar");
1427 				break;
1428 			case Type_Hebrew:
1429 				docu.writeAttribute("Type", "Type_Hebrew");
1430 				break;
1431 			case Type_asterix:
1432 				docu.writeAttribute("Type", "Type_asterix");
1433 				break;
1434 			case Type_CJK:
1435 				docu.writeAttribute("Type", "Type_CJK");
1436 				break;
1437 			case Type_None:
1438 				docu.writeAttribute("Type", "Type_None");
1439 				break;
1440 		}
1441 		docu.writeAttribute("Start", (*it).sectionstartindex);
1442 		docu.writeAttribute("Reversed", (*it).reversed);
1443 		docu.writeAttribute("Active", (*it).active);
1444 		docu.writeAttribute("FillChar", (*it).pageNumberFillChar.unicode());
1445 		docu.writeAttribute("FieldWidth", (*it).pageNumberWidth);
1446 	}
1447 	docu.writeEndElement();
1448 }
1449 
writeMarks(ScXmlStreamWriter & docu)1450 void Scribus150Format::writeMarks(ScXmlStreamWriter & docu)
1451 {
1452 	//write list of definied marks to SLA
1453 	if (m_Doc->marksList().isEmpty())
1454 		return;
1455 
1456 	docu.writeStartElement("Marks");
1457 	for (Mark* mrk : m_Doc->marksList())
1458 	{
1459 		if (mrk->isType(MARKNoteFrameType))
1460 			continue;
1461 		docu.writeEmptyElement("Mark");
1462 		docu.writeAttribute("label", mrk->label);
1463 		docu.writeAttribute("type", mrk->getType());
1464 		if (mrk->isType(MARK2ItemType) && mrk->hasItemPtr())
1465 		{
1466 			const PageItem* item = mrk->getItemPtr();
1467 			assert(item != nullptr);
1468 			docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
1469 			//docu.writeAttribute("itemName", item->itemName());
1470 		}
1471 		else if (mrk->isType(MARKVariableTextType) && mrk->hasString())
1472 			docu.writeAttribute("str", mrk->getString());
1473 		else if (mrk->isType(MARK2MarkType) && mrk->hasMark())
1474 		{
1475 			QString label;
1476 			MarkType type;
1477 			mrk->getMark(label, type);
1478 			docu.writeAttribute("MARKlabel", label);
1479 			docu.writeAttribute("MARKtype", type);
1480 		}
1481 	}
1482 	docu.writeEndElement();
1483 }
1484 
writeNotesStyles(ScXmlStreamWriter & docu)1485 void Scribus150Format::writeNotesStyles(ScXmlStreamWriter & docu)
1486 {
1487 	if (m_Doc->m_docNotesStylesList.isEmpty())
1488 		return;
1489 
1490 	//write notes styles
1491 	QStringList noteStyleNames;
1492 	QList<NotesStyle*>::ConstIterator end = m_Doc->m_docNotesStylesList.constEnd();
1493 	for (auto itNS = m_Doc->m_docNotesStylesList.constBegin(); itNS != end; ++itNS)
1494 	{
1495 		const NotesStyle* noteStyle = (*itNS);
1496 		noteStyleNames.append(noteStyle->name());
1497 	}
1498 	writeNotesStyles(docu, noteStyleNames);
1499 }
1500 
writeNotesStyles(ScXmlStreamWriter & docu,const QStringList & styleSelection)1501 void  Scribus150Format::writeNotesStyles(ScXmlStreamWriter & docu, const QStringList& styleSelection)
1502 {
1503 	if (styleSelection.isEmpty())
1504 		return;
1505 
1506 	//write notes styles
1507 	docu.writeStartElement("NotesStyles");
1508 	QList<NotesStyle*>::Iterator itNS;
1509 	QList<NotesStyle*>::Iterator end = m_Doc->m_docNotesStylesList.end();
1510 	for (itNS = m_Doc->m_docNotesStylesList.begin(); itNS != end; ++itNS)
1511 	{
1512 		NotesStyle* noteStyle = (*itNS);
1513 		if (!styleSelection.contains(noteStyle->name()))
1514 			continue;
1515 		docu.writeEmptyElement("notesStyle");
1516 		docu.writeAttribute("Name", noteStyle->name());
1517 		docu.writeAttribute("Start", noteStyle->start());
1518 		docu.writeAttribute("Endnotes", noteStyle->isEndNotes());
1519 		switch (noteStyle->getType())
1520 		{
1521 			case Type_1_2_3:
1522 				docu.writeAttribute("Type", "Type_1_2_3");
1523 				break;
1524 			case Type_1_2_3_ar:
1525 				docu.writeAttribute("Type", "Type_1_2_3_ar");
1526 				break;
1527 			case Type_i_ii_iii:
1528 				docu.writeAttribute("Type", "Type_i_ii_iii");
1529 				break;
1530 			case Type_I_II_III:
1531 				docu.writeAttribute("Type", "Type_I_II_III");
1532 				break;
1533 			case Type_a_b_c:
1534 				docu.writeAttribute("Type", "Type_a_b_c");
1535 				break;
1536 			case Type_A_B_C:
1537 				docu.writeAttribute("Type", "Type_A_B_C");
1538 				break;
1539 			case Type_Alphabet_ar:
1540 				docu.writeAttribute("Type", "Type_Alphabet_ar");
1541 				break;
1542 			case Type_Abjad_ar:
1543 				docu.writeAttribute("Type", "Type_Abjad_ar");
1544 				break;
1545 			case Type_Hebrew:
1546 				docu.writeAttribute("Type", "Type_Hebrew");
1547 				break;
1548 			case Type_asterix:
1549 				docu.writeAttribute("Type", "Type_asterix");
1550 				break;
1551 			case Type_CJK:
1552 				docu.writeAttribute("Type", "Type_CJK");
1553 				break;
1554 			case Type_None:
1555 				docu.writeAttribute("Type", "Type_None");
1556 				break;
1557 		}
1558 		docu.writeAttribute("Range", (int) noteStyle->range());
1559 		docu.writeAttribute("Prefix", noteStyle->prefix());
1560 		docu.writeAttribute("Suffix", noteStyle->suffix());
1561 		docu.writeAttribute("AutoHeight", noteStyle->isAutoNotesHeight());
1562 		docu.writeAttribute("AutoWidth", noteStyle->isAutoNotesWidth());
1563 		docu.writeAttribute("AutoRemove", noteStyle->isAutoRemoveEmptyNotesFrames());
1564 		docu.writeAttribute("AutoWeld", noteStyle->isAutoWeldNotesFrames());
1565 		docu.writeAttribute("SuperNote", noteStyle->isSuperscriptInNote());
1566 		docu.writeAttribute("SuperMaster", noteStyle->isSuperscriptInMaster());
1567 		docu.writeAttribute("MarksStyle", noteStyle->marksChStyle());
1568 		docu.writeAttribute("NotesStyle", noteStyle->notesParStyle());
1569 	}
1570 	docu.writeEndElement();
1571 }
1572 
writeNotesFrames(ScXmlStreamWriter & docu)1573 void Scribus150Format::writeNotesFrames(ScXmlStreamWriter &docu)
1574 {
1575 	QList<PageItem_NoteFrame*> nfList;
1576 	for (NotesStyle* noteStyle : qAsConst(m_Doc->m_docNotesStylesList))
1577 		nfList.append(m_Doc->listNotesFrames(noteStyle));
1578 
1579 	writeNotesFrames(docu, nfList);
1580 }
1581 
writeNotesFrames(ScXmlStreamWriter & docu,const QList<PageItem_NoteFrame * > & itemList)1582 void Scribus150Format::writeNotesFrames(ScXmlStreamWriter & docu, const QList<PageItem_NoteFrame*>& itemList)
1583 {
1584 	if (itemList.isEmpty())
1585 		return;
1586 
1587 	docu.writeStartElement("NotesFrames");
1588 
1589 	for (int i = 0; i < itemList.count(); ++i)
1590 	{
1591 		PageItem_NoteFrame* noteFrame = itemList.at(i);
1592 		NotesStyle* noteStyle = noteFrame->notesStyle();
1593 		if (noteStyle->isEndNotes())
1594 		{
1595 			docu.writeEmptyElement("ENDNOTEFRAME");
1596 			docu.writeAttribute("NSname", noteStyle->name());
1597 			docu.writeAttribute("range", (int) noteStyle->range());
1598 			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
1599 
1600 			rangeItem rI = m_Doc->m_docEndNotesFramesMap.value(noteFrame);
1601 			if (noteStyle->range() == NSRstory)
1602 				docu.writeAttribute("ItemID", qHash(rI.firstStoryFrame) & 0x7FFFFFFF);
1603 		}
1604 		else //footnotes frame
1605 		{
1606 			docu.writeEmptyElement("FOOTNOTEFRAME");
1607 			docu.writeAttribute("NSname", noteStyle->name());
1608 			docu.writeAttribute("myID", qHash(noteFrame) & 0x7FFFFFFF);
1609 			docu.writeAttribute("MasterID", qHash(noteFrame->masterFrame()) & 0x7FFFFFFF);
1610 		}
1611 	}
1612 	docu.writeEndElement();
1613 }
1614 
writeNotes(ScXmlStreamWriter & docu)1615 void Scribus150Format::writeNotes(ScXmlStreamWriter & docu)
1616 {
1617 	//write notes
1618 	if (m_Doc->notesList().isEmpty())
1619 		return;
1620 
1621 	const QList<TextNote*>& noteList = m_Doc->notesList();
1622 	writeNotes(docu, noteList);
1623 }
1624 
writeNotes(ScXmlStreamWriter & docu,const QList<TextNote * > & noteList)1625 void Scribus150Format::writeNotes(ScXmlStreamWriter & docu, const QList<TextNote*>& noteList)
1626 {
1627 	if (noteList.isEmpty())
1628 		return;
1629 
1630 	docu.writeStartElement("Notes");
1631 	for (int i = 0; i < noteList.count(); ++i)
1632 	{
1633 		TextNote* textNote = noteList.at(i);
1634 		if (textNote->masterMark() == nullptr)
1635 			continue;
1636 		docu.writeEmptyElement("Note");
1637 		docu.writeAttribute("Master", textNote->masterMark()->label);
1638 		docu.writeAttribute("NStyle", textNote->notesStyle()->name());
1639 		docu.writeAttribute("Text", textNote->saxedText());
1640 	}
1641 	docu.writeEndElement();
1642 }
1643 
writePageSets(ScXmlStreamWriter & docu)1644 void Scribus150Format::writePageSets(ScXmlStreamWriter & docu)
1645 {
1646 	docu.writeStartElement("PageSets");
1647 	QList<PageSet>::Iterator itpgset;
1648 	QList<PageSet> pageSet(m_Doc->pageSets());
1649 	for (itpgset = pageSet.begin(); itpgset != pageSet.end(); ++itpgset )
1650 	{
1651 		docu.writeStartElement("Set");
1652 		docu.writeAttribute("Name", itpgset->Name);
1653 		docu.writeAttribute("FirstPage", itpgset->FirstPage);
1654 		docu.writeAttribute("Rows", itpgset->Rows);
1655 		docu.writeAttribute("Columns", itpgset->Columns);
1656 //		docu.writeAttribute("GapHorizontal", itpgset->GapHorizontal);
1657 //		docu.writeAttribute("GapVertical", itpgset->GapVertical);
1658 //		docu.writeAttribute("GapBelow", itpgset->GapBelow);
1659 		QStringList pNames = itpgset->pageNames;
1660 		QStringList::Iterator itpgsetN;
1661 		for (itpgsetN = pNames.begin(); itpgsetN != pNames.end(); ++itpgsetN )
1662 		{
1663 			docu.writeEmptyElement("PageNames");
1664 			docu.writeAttribute("Name", (*itpgsetN));
1665 		}
1666 		docu.writeEndElement();
1667 	}
1668 	docu.writeEndElement();
1669 }
1670 
writePatterns(ScXmlStreamWriter & docu,const QString & baseDir,bool part,Selection * selection)1671 void Scribus150Format::writePatterns(ScXmlStreamWriter & docu, const QString& baseDir, bool part, Selection* selection)
1672 {
1673 	QStringList patterns;
1674 	if (part)
1675 		patterns = m_Doc->getPatternDependencyList(m_Doc->getUsedPatternsSelection(selection));
1676 	else
1677 		patterns = m_Doc->getPatternDependencyList(m_Doc->docPatterns.keys());
1678 	for (int a = 0; a < patterns.count(); a++)
1679 	{
1680 		docu.writeStartElement("Pattern");
1681 		docu.writeAttribute("Name", patterns[a]);
1682 		ScPattern pa = m_Doc->docPatterns[patterns[a]];
1683 		docu.writeAttribute("width", pa.width);
1684 		docu.writeAttribute("height", pa.height);
1685 		docu.writeAttribute("scaleX", pa.scaleX);
1686 		docu.writeAttribute("scaleY", pa.scaleY);
1687 		docu.writeAttribute("xoffset", pa.xoffset);
1688 		docu.writeAttribute("yoffset", pa.yoffset);
1689 		WriteObjects(m_Doc, docu, baseDir, nullptr, 0, ItemSelectionPattern, &pa.items);
1690 		docu.writeEndElement();
1691 	}
1692 }
1693 
writeContent(ScXmlStreamWriter & docu,const QString & baseDir)1694 void Scribus150Format::writeContent(ScXmlStreamWriter & docu, const QString& baseDir)
1695 {
1696 	if (m_mwProgressBar != nullptr)
1697 	{
1698 		m_mwProgressBar->setMaximum(m_Doc->DocPages.count()+m_Doc->MasterPages.count()+m_Doc->DocItems.count()+m_Doc->MasterItems.count()+m_Doc->FrameItems.count());
1699 		m_mwProgressBar->setValue(0);
1700 	}
1701 	WritePages(m_Doc, docu, m_mwProgressBar, 0, true);
1702 	WritePages(m_Doc, docu, m_mwProgressBar, m_Doc->MasterPages.count(), false);
1703 	WriteObjects(m_Doc, docu, baseDir, m_mwProgressBar, m_Doc->MasterPages.count()+m_Doc->DocPages.count(), ItemSelectionFrame);
1704 	WriteObjects(m_Doc, docu, baseDir, m_mwProgressBar, m_Doc->MasterPages.count()+m_Doc->DocPages.count()+m_Doc->FrameItems.count(), ItemSelectionMaster);
1705 	WriteObjects(m_Doc, docu, baseDir, m_mwProgressBar, m_Doc->MasterPages.count()+m_Doc->DocPages.count()+m_Doc->MasterItems.count()+m_Doc->FrameItems.count(), ItemSelectionPage);
1706 }
1707 
WritePages(ScribusDoc * doc,ScXmlStreamWriter & docu,QProgressBar * dia2,uint maxC,bool master)1708 void Scribus150Format::WritePages(ScribusDoc *doc, ScXmlStreamWriter& docu, QProgressBar *dia2, uint maxC, bool master)
1709 {
1710 	uint ObCount = maxC;
1711 	ScPage *page;
1712 	uint pages;
1713 	if (master)
1714 		pages = doc->MasterPages.count();
1715 	else
1716 		pages = doc->DocPages.count();
1717 	for (uint i = 0; i < pages; ++i)
1718 	{
1719 		ObCount++;
1720 		if (dia2 != nullptr)
1721 			dia2->setValue(ObCount);
1722 		if (master)
1723 		{
1724 			docu.writeStartElement("MASTERPAGE");
1725 			page = doc->MasterPages.at(i);
1726 		}
1727 		else
1728 		{
1729 			docu.writeStartElement("PAGE");
1730 			page = doc->DocPages.at(i);
1731 		}
1732 		docu.writeAttribute("PAGEXPOS",page->xOffset());
1733 		docu.writeAttribute("PAGEYPOS",page->yOffset());
1734 		docu.writeAttribute("PAGEWIDTH",page->width());
1735 		docu.writeAttribute("PAGEHEIGHT",page->height());
1736 		docu.writeAttribute("BORDERLEFT",page->initialMargins.left());
1737 		docu.writeAttribute("BORDERRIGHT",page->initialMargins.right());
1738 		docu.writeAttribute("BORDERTOP",page->initialMargins.top());
1739 		docu.writeAttribute("BORDERBOTTOM",page->initialMargins.bottom());
1740 		docu.writeAttribute("NUM",page->pageNr());
1741 		docu.writeAttribute("NAM",page->pageName());
1742 		docu.writeAttribute("MNAM",page->masterPageName());
1743 		docu.writeAttribute("Size", page->size());
1744 		docu.writeAttribute("Orientation", page->orientation());
1745 		docu.writeAttribute("LEFT", page->LeftPg);
1746 		docu.writeAttribute("PRESET", page->marginPreset);
1747 		docu.writeAttribute("VerticalGuides", GuideManagerIO::writeVerticalGuides(
1748 													page, GuideManagerCore::Standard));
1749 		docu.writeAttribute("HorizontalGuides", GuideManagerIO::writeHorizontalGuides(
1750 													page, GuideManagerCore::Standard));
1751 		docu.writeAttribute("AGhorizontalAutoGap", page->guides.horizontalAutoGap());
1752 		docu.writeAttribute("AGverticalAutoGap", page->guides.verticalAutoGap());
1753 		docu.writeAttribute("AGhorizontalAutoCount", page->guides.horizontalAutoCount());
1754 		docu.writeAttribute("AGverticalAutoCount", page->guides.verticalAutoCount());
1755 		docu.writeAttribute("AGhorizontalAutoRefer", page->guides.horizontalAutoRefer());
1756 		docu.writeAttribute("AGverticalAutoRefer", page->guides.verticalAutoRefer());
1757 		docu.writeAttribute("AGSelection", GuideManagerIO::writeSelection(page));
1758 		docu.writeAttribute("pageEffectDuration", page->PresentVals.pageEffectDuration);
1759 		docu.writeAttribute("pageViewDuration", page->PresentVals.pageViewDuration);
1760 		docu.writeAttribute("effectType", page->PresentVals.effectType);
1761 		docu.writeAttribute("Dm", page->PresentVals.Dm);
1762 		docu.writeAttribute("M", page->PresentVals.M);
1763 		docu.writeAttribute("Di", page->PresentVals.Di);
1764 		docu.writeEndElement();
1765 	}
1766 }
1767 
1768 
1769 namespace { // anon
textWithSoftHyphens(StoryText & itemText,int from,int to)1770 	QString textWithSoftHyphens(StoryText& itemText, int from, int to)
1771 	{
1772 		QString result("");
1773 		int lastPos = from;
1774 		for (int i = from; i < to; ++i)
1775 		{
1776 			if (itemText.hasFlag(i, ScLayout_HyphenationPossible)
1777 				// duplicate SHYPHEN if already present to indicate a user provided SHYPHEN:
1778 				|| itemText.text(i) == SpecialChars::SHYPHEN)
1779 			{
1780 				result += itemText.text(lastPos, i + 1 - lastPos);
1781 				result += SpecialChars::SHYPHEN;
1782 				lastPos = i+1;
1783 			}
1784 		}
1785 		if (lastPos < to)
1786 			result += itemText.text(lastPos, to - lastPos);
1787 		return result;
1788 	}
1789 } // namespace anon
1790 
writeStoryText(ScribusDoc * doc,ScXmlStreamWriter & docu,StoryText & story,PageItem * item)1791 void Scribus150Format::writeStoryText(ScribusDoc *doc, ScXmlStreamWriter& docu, StoryText& story, PageItem* item)
1792 {
1793 	docu.writeStartElement("StoryText");
1794 
1795 	const ParagraphStyle& defaultStyle = story.defaultStyle();
1796 	putPStyle(docu, defaultStyle, "DefaultStyle");
1797 
1798 	writeITEXTs(doc, docu, story, item);
1799 
1800 	docu.writeEndElement();
1801 }
1802 
writeITEXTs(ScribusDoc * doc,ScXmlStreamWriter & docu,StoryText & story,PageItem * item)1803 void Scribus150Format::writeITEXTs(ScribusDoc *doc, ScXmlStreamWriter &docu, StoryText& story, PageItem* item)
1804 {
1805 	CharStyle lastStyle;
1806 	int lastPos = 0;
1807 	QString tmpnum;
1808 	int iTLen = story.length();
1809 	if (item && item->isNoteFrame())
1810 		iTLen = 0;  //used for saving empty endnotes frames, as they will be filled automatically
1811 	for (int k = 0; k < iTLen; ++k)
1812 	{
1813 		const CharStyle& style1(story.charStyle(k));
1814 		const QChar ch = story.text(k);
1815 
1816 		if (ch == SpecialChars::OBJECT ||
1817 			ch == SpecialChars::TAB ||
1818 			ch == SpecialChars::PARSEP ||
1819 			ch == SpecialChars::LINEBREAK ||
1820 			ch == SpecialChars::COLBREAK ||
1821 			ch == SpecialChars::FRAMEBREAK ||
1822 			ch == SpecialChars::PAGENUMBER ||
1823 			ch == SpecialChars::PAGECOUNT ||
1824 			ch == SpecialChars::NBHYPHEN ||
1825 			ch == SpecialChars::NBSPACE ||
1826 			ch == SpecialChars::ZWNBSPACE ||
1827 			ch == SpecialChars::ZWSPACE ||
1828 			ch.unicode() < 32 ||
1829 			(0xd800 <= ch.unicode() && ch.unicode() < 0xe000) ||
1830 			ch.unicode() == 0xfffe || ch.unicode() == 0xffff ||
1831 			style1 != lastStyle)
1832 		{
1833 			// something new, write pending chars
1834 			if  (k - lastPos > 0)
1835 			{
1836 				docu.writeEmptyElement("ITEXT");
1837 				putCStyle(docu, lastStyle);
1838 				docu.writeAttribute("CH", textWithSoftHyphens(story, lastPos, k));
1839 			}
1840 			lastStyle = style1;
1841 			lastPos = k;
1842 		}
1843 
1844 		if (ch == SpecialChars::OBJECT && story.object(k).getPageItem(doc) != nullptr)
1845 		{
1846 			// each obj in its own ITEXT for now
1847 			docu.writeEmptyElement("ITEXT");
1848 			putCStyle(docu, lastStyle);
1849 			tmpnum.setNum(ch.unicode());
1850 			docu.writeAttribute("Unicode", tmpnum);
1851 			docu.writeAttribute("COBJ", story.object(k).getInlineCharID());
1852 		}
1853 		else if (ch == SpecialChars::OBJECT && story.hasMark(k))
1854 		{
1855 			Mark* mark = story.mark(k);
1856 			if (!mark->isType(MARKBullNumType))
1857 			{ //dont save marks for bullets and numbering
1858 				docu.writeEmptyElement("MARK");
1859 				docu.writeAttribute("label", mark->label);
1860 				docu.writeAttribute("type", mark->getType());
1861 				putCStyle(docu, lastStyle);
1862 			}
1863 		}
1864 		else if (ch == SpecialChars::PARSEP)	// stores also the paragraphstyle for preceding chars
1865 			putPStyle(docu, story.paragraphStyle(k), "para");
1866 		else if (ch == SpecialChars::TAB)
1867 		{
1868 			docu.writeEmptyElement("tab");
1869 			putCStyle(docu, lastStyle);
1870 		}
1871 		else if (ch == SpecialChars::LINEBREAK)
1872 			docu.writeEmptyElement("breakline");
1873 		else if (ch == SpecialChars::COLBREAK)
1874 			docu.writeEmptyElement("breakcol");
1875 		else if (ch == SpecialChars::FRAMEBREAK)
1876 			docu.writeEmptyElement("breakframe");
1877 		else if (ch == SpecialChars::NBHYPHEN)
1878 		{
1879 			docu.writeEmptyElement("nbhyphen");
1880 			putCStyle(docu, lastStyle);
1881 		}
1882 		else if (ch == SpecialChars::NBSPACE)
1883 		{
1884 			docu.writeEmptyElement("nbspace");
1885 			putCStyle(docu, lastStyle);
1886 		}
1887 		else if (ch == SpecialChars::ZWNBSPACE)
1888 		{
1889 			docu.writeEmptyElement("zwnbspace");
1890 			putCStyle(docu, lastStyle);
1891 		}
1892 		else if (ch == SpecialChars::ZWSPACE)
1893 		{
1894 			docu.writeEmptyElement("zwspace");
1895 			putCStyle(docu, lastStyle);
1896 		}
1897 		else if (ch == SpecialChars::PAGENUMBER)
1898 		{
1899 			docu.writeEmptyElement("var");
1900 			docu.writeAttribute("name", "pgno");
1901 			putCStyle(docu, lastStyle);
1902 		}
1903 		else if (ch == SpecialChars::PAGECOUNT)
1904 		{
1905 			docu.writeEmptyElement("var");
1906 			docu.writeAttribute("name", "pgco");
1907 			putCStyle(docu, lastStyle);
1908 		}
1909 		else if (ch.unicode() < 32 ||
1910 				 (0xd800 <= ch.unicode() && ch.unicode() < 0xe000) ||
1911 				 ch.unicode() == 0xfffe || ch.unicode() == 0xffff)
1912 		{
1913 			docu.writeEmptyElement("ITEXT");
1914 			putCStyle(docu, lastStyle);
1915 			tmpnum.setNum(ch.unicode());
1916 			docu.writeAttribute("Unicode", tmpnum);
1917 		}
1918 		else
1919 		{
1920 			continue;
1921 		}
1922 		// otherwise we just wrote something special and are done with position 'k'
1923 		lastPos = k + 1;
1924 	}
1925 	// write pending chars
1926 	if (story.length() - lastPos > 0)
1927 	{
1928 		docu.writeEmptyElement("ITEXT");
1929 		putCStyle(docu, lastStyle);
1930 		docu.writeAttribute("CH", textWithSoftHyphens(story, lastPos, story.length()));
1931 	}
1932 	// paragraphstyle for trailing chars
1933 	if (story.length() == 0 || story.text(story.length() - 1) != SpecialChars::PARSEP)
1934 	{
1935 		putPStyle(docu, story.paragraphStyle(story.length()), "trail");
1936 	}
1937 }
1938 
WriteObjects(ScribusDoc * doc,ScXmlStreamWriter & docu,const QString & baseDir,QProgressBar * dia2,uint maxC,ItemSelection master,QList<PageItem * > * some_items)1939 void Scribus150Format::WriteObjects(ScribusDoc *doc, ScXmlStreamWriter& docu, const QString& baseDir, QProgressBar *dia2, uint maxC, ItemSelection master, QList<PageItem*> *some_items)
1940 {
1941 	uint ObCount = maxC;
1942 	QList<PageItem*> *items = nullptr;
1943 	QList<PageItem*> itemList;
1944 	PageItem *item = nullptr;
1945 	uint objects = 0;
1946 	switch (master)
1947 	{
1948 		case ItemSelectionMaster:
1949 			items = &doc->MasterItems;
1950 			break;
1951 		case ItemSelectionPage:
1952 			items = &doc->DocItems;
1953 			break;
1954 		case ItemSelectionFrame:
1955 			if (some_items != nullptr)
1956 				items = some_items;
1957 			else
1958 			{
1959 				itemList = doc->FrameItems.values();
1960 				items = &itemList;
1961 			}
1962 			break;
1963 		case ItemSelectionGroup:
1964 		case ItemSelectionPattern:
1965 		case ItemSelectionElements:
1966 			items = some_items;
1967 			break;
1968 		default:
1969 			assert(false);
1970 	}
1971 	objects = items->count();
1972 	for (uint j = 0; j < objects;++j)
1973 	{
1974 		ObCount++;
1975 		if (dia2 != nullptr)
1976 			dia2->setValue(ObCount);
1977 		item = items->at(j);
1978 		switch (master)
1979 		{
1980 			case ItemSelectionMaster:
1981 				docu.writeStartElement("MASTEROBJECT");
1982 				break;
1983 			case ItemSelectionGroup:
1984 			case ItemSelectionPage:
1985 				docu.writeStartElement("PAGEOBJECT");
1986 				break;
1987 			case ItemSelectionFrame:
1988 				docu.writeStartElement("FRAMEOBJECT");
1989 				break;
1990 			case ItemSelectionPattern:
1991 				docu.writeStartElement("PatternItem");
1992 				break;
1993 			case ItemSelectionElements:
1994 				docu.writeStartElement("ITEM");
1995 				break;
1996 		}
1997 		if (master == ItemSelectionFrame)
1998 			docu.writeAttribute("InID", item->inlineCharID);
1999 		if (master == ItemSelectionElements)
2000 		{
2001 			docu.writeAttribute("XPOS", item->xPos() - doc->currentPage()->xOffset());
2002 			docu.writeAttribute("YPOS", item->yPos() - doc->currentPage()->yOffset());
2003 		}
2004 		else
2005 		{
2006 			docu.writeAttribute("XPOS", item->xPos());
2007 			docu.writeAttribute("YPOS", item->yPos());
2008 		}
2009 		SetItemProps(docu, item, baseDir);
2010 		if (!item->OnMasterPage.isEmpty())
2011 			docu.writeAttribute("OnMasterPage", item->OnMasterPage);
2012 		if (!item->pixm.imgInfo.usedPath.isEmpty())
2013 			docu.writeAttribute("ImageClip", item->pixm.imgInfo.usedPath);
2014 		if (item->pixm.imgInfo.lowResType != 1)
2015 			docu.writeAttribute("ImageRes", item->pixm.imgInfo.lowResType);
2016 		if (item->isEmbedded)
2017 			docu.writeAttribute("isInline", 1);
2018 		if (!item->fillRule)
2019 			docu.writeAttribute("fillRule", 0);
2020 		if (item->doOverprint)
2021 			docu.writeAttribute("doOverprint", 1);
2022 		docu.writeAttribute("gXpos", item->gXpos);
2023 		docu.writeAttribute("gYpos", item->gYpos);
2024 		docu.writeAttribute("gWidth", item->gWidth);
2025 		docu.writeAttribute("gHeight", item->gHeight);
2026 		if (item->itemType() == PageItem::Symbol)
2027 			docu.writeAttribute("pattern", item->pattern());
2028 		if (item->GrType != 0)
2029 		{
2030 			if (item->GrType == Gradient_Pattern)
2031 			{
2032 				docu.writeAttribute("pattern", item->pattern());
2033 				double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
2034 				item->patternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
2035 				bool mirrorX, mirrorY;
2036 				item->patternFlip(mirrorX, mirrorY);
2037 				docu.writeAttribute("pScaleX", patternScaleX);
2038 				docu.writeAttribute("pScaleY", patternScaleY);
2039 				docu.writeAttribute("pOffsetX", patternOffsetX);
2040 				docu.writeAttribute("pOffsetY", patternOffsetY);
2041 				docu.writeAttribute("pRotation", patternRotation);
2042 				docu.writeAttribute("pSkewX", patternSkewX);
2043 				docu.writeAttribute("pSkewY", patternSkewY);
2044 				docu.writeAttribute("pMirrorX" , mirrorX);
2045 				docu.writeAttribute("pMirrorY" , mirrorY);
2046 			}
2047 			else
2048 			{
2049 				if (item->GrType == Gradient_Mesh)
2050 				{
2051 					docu.writeAttribute("GMAY", item->meshGradientArray[0].count());
2052 					docu.writeAttribute("GMAX", item->meshGradientArray.count());
2053 				}
2054 				else if (item->GrType == Gradient_PatchMesh)
2055 				{
2056 					docu.writeAttribute("GMAX", item->meshGradientPatches.count());
2057 				}
2058 				else if (item->GrType == Gradient_Hatch)
2059 				{
2060 					docu.writeAttribute("HatchMode", item->hatchType);
2061 					docu.writeAttribute("HatchDist", item->hatchDistance);
2062 					docu.writeAttribute("HatchAngle", item->hatchAngle);
2063 					docu.writeAttribute("HatchSolidB", item->hatchUseBackground);
2064 					docu.writeAttribute("HatchBackG", item->hatchBackground);
2065 					docu.writeAttribute("HatchForeC", item->hatchForeground);
2066 				}
2067 				else
2068 				{
2069 					docu.writeAttribute("GRSTARTX", item->GrStartX);
2070 					docu.writeAttribute("GRSTARTY", item->GrStartY);
2071 					docu.writeAttribute("GRENDX", item->GrEndX);
2072 					docu.writeAttribute("GRENDY", item->GrEndY);
2073 					docu.writeAttribute("GRFOCALX", item->GrFocalX);
2074 					docu.writeAttribute("GRFOCALY", item->GrFocalY);
2075 					docu.writeAttribute("GRSCALE" , item->GrScale);
2076 					docu.writeAttribute("GRSKEW" , item->GrSkew);
2077 					docu.writeAttribute("GRExt", item->getGradientExtend());
2078 					if ((item->GrType == Gradient_4Colors) || (item->GrType == Gradient_Diamond))
2079 					{
2080 						docu.writeAttribute("GRC1X"   , item->GrControl1.x());
2081 						docu.writeAttribute("GRC1Y"   , item->GrControl1.y());
2082 						docu.writeAttribute("GRCOLP1" , item->GrColorP1);
2083 						docu.writeAttribute("GRC2X"   , item->GrControl2.x());
2084 						docu.writeAttribute("GRC2Y"   , item->GrControl2.y());
2085 						docu.writeAttribute("GRCOLP2" , item->GrColorP2);
2086 						docu.writeAttribute("GRC3X"   , item->GrControl3.x());
2087 						docu.writeAttribute("GRC3Y"   , item->GrControl3.y());
2088 						docu.writeAttribute("GRCOLP3" , item->GrColorP3);
2089 						docu.writeAttribute("GRC4X"   , item->GrControl4.x());
2090 						docu.writeAttribute("GRC4Y"   , item->GrControl4.y());
2091 						docu.writeAttribute("GRC5X"   , item->GrControl5.x());
2092 						docu.writeAttribute("GRC5Y"   , item->GrControl5.y());
2093 						docu.writeAttribute("GRCOLP4" , item->GrColorP4);
2094 						docu.writeAttribute("GRCOLT1" , item->GrCol1transp);
2095 						docu.writeAttribute("GRCOLT2" , item->GrCol2transp);
2096 						docu.writeAttribute("GRCOLT3" , item->GrCol3transp);
2097 						docu.writeAttribute("GRCOLT4" , item->GrCol4transp);
2098 						docu.writeAttribute("GRCOLS1" , item->GrCol1Shade);
2099 						docu.writeAttribute("GRCOLS2" , item->GrCol2Shade);
2100 						docu.writeAttribute("GRCOLS3" , item->GrCol3Shade);
2101 						docu.writeAttribute("GRCOLS4" , item->GrCol4Shade);
2102 					}
2103 				}
2104 			}
2105 		}
2106 		if (!item->gradient().isEmpty())
2107 			docu.writeAttribute("GRNAME", item->gradient());
2108 		if (!item->strokeGradient().isEmpty())
2109 			docu.writeAttribute("GRNAMES", item->strokeGradient());
2110 		if (!item->gradientMask().isEmpty())
2111 			docu.writeAttribute("GRNAMEM", item->gradientMask());
2112 		if (item->GrTypeStroke > 0)
2113 		{
2114 			docu.writeAttribute("GRExtS", item->getStrokeGradientExtend());
2115 			docu.writeAttribute("GRSTARTXS", item->GrStrokeStartX);
2116 			docu.writeAttribute("GRSTARTYS", item->GrStrokeStartY);
2117 			docu.writeAttribute("GRENDXS", item->GrStrokeEndX);
2118 			docu.writeAttribute("GRENDYS", item->GrStrokeEndY);
2119 			docu.writeAttribute("GRFOCALXS", item->GrStrokeFocalX);
2120 			docu.writeAttribute("GRFOCALYS", item->GrStrokeFocalY);
2121 			docu.writeAttribute("GRSCALES" , item->GrStrokeScale);
2122 			docu.writeAttribute("GRSKEWS" , item->GrStrokeSkew);
2123 		}
2124 		if (!item->strokePattern().isEmpty())
2125 		{
2126 			docu.writeAttribute("patternS", item->strokePattern());
2127 			double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace;
2128 			item->strokePatternTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY, patternSpace);
2129 			bool mirrorX, mirrorY, atPath;
2130 			item->strokePatternFlip(mirrorX, mirrorY);
2131 			atPath = item->isStrokePatternToPath();
2132 			docu.writeAttribute("pScaleXS", patternScaleX);
2133 			docu.writeAttribute("pScaleYS", patternScaleY);
2134 			docu.writeAttribute("pOffsetXS", patternOffsetX);
2135 			docu.writeAttribute("pOffsetYS", patternOffsetY);
2136 			docu.writeAttribute("pRotationS", patternRotation);
2137 			docu.writeAttribute("pSkewXS", patternSkewX);
2138 			docu.writeAttribute("pSkewYS", patternSkewY);
2139 			docu.writeAttribute("pSpaceS", patternSpace);
2140 			docu.writeAttribute("pMirrorXS" , mirrorX);
2141 			docu.writeAttribute("pMirrorYS" , mirrorY);
2142 			docu.writeAttribute("pAtPathS" , atPath);
2143 		}
2144 		if (item->GrMask > 0)
2145 		{
2146 			docu.writeAttribute("GRExtM", item->mask_gradient.repeatMethod());
2147 			docu.writeAttribute("GRTYPM", item->GrMask);
2148 			docu.writeAttribute("GRSTARTXM", item->GrMaskStartX);
2149 			docu.writeAttribute("GRSTARTYM", item->GrMaskStartY);
2150 			docu.writeAttribute("GRENDXM", item->GrMaskEndX);
2151 			docu.writeAttribute("GRENDYM", item->GrMaskEndY);
2152 			docu.writeAttribute("GRFOCALXM", item->GrMaskFocalX);
2153 			docu.writeAttribute("GRFOCALYM", item->GrMaskFocalY);
2154 			docu.writeAttribute("GRSCALEM" , item->GrMaskScale);
2155 			docu.writeAttribute("GRSKEWM" , item->GrMaskSkew);
2156 		}
2157 		if (!item->patternMask().isEmpty())
2158 		{
2159 			docu.writeAttribute("patternM", item->patternMask());
2160 			double patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY;
2161 			item->maskTransform(patternScaleX, patternScaleY, patternOffsetX, patternOffsetY, patternRotation, patternSkewX, patternSkewY);
2162 			bool mirrorX, mirrorY;
2163 			item->maskFlip(mirrorX, mirrorY);
2164 			docu.writeAttribute("pScaleXM", patternScaleX);
2165 			docu.writeAttribute("pScaleYM", patternScaleY);
2166 			docu.writeAttribute("pOffsetXM", patternOffsetX);
2167 			docu.writeAttribute("pOffsetYM", patternOffsetY);
2168 			docu.writeAttribute("pRotationM", patternRotation);
2169 			docu.writeAttribute("pSkewXM", patternSkewX);
2170 			docu.writeAttribute("pSkewYM", patternSkewY);
2171 			docu.writeAttribute("pMirrorXM" , mirrorX);
2172 			docu.writeAttribute("pMirrorYM" , mirrorY);
2173 		}
2174 		if (item->itemText.defaultStyle().hasParent())
2175 			docu.writeAttribute("PSTYLE", item->itemText.defaultStyle().parent());
2176 		if (! item->itemText.defaultStyle().isInhAlignment())
2177 			docu.writeAttribute("ALIGN", item->itemText.defaultStyle().alignment());
2178 
2179 		docu.writeAttribute("LAYER", item->m_layerID);
2180 		if (item->isBookmark)
2181 			docu.writeAttribute("BOOKMARK", 1);
2182 
2183 		if (item->isTextFrame() || item->isPathText() || item->isImageFrame())
2184 		{
2185 			if (item->nextInChain() != nullptr)
2186 				docu.writeAttribute("NEXTITEM", qHash(item->nextInChain()) & 0x7FFFFFFF);
2187 			else
2188 				docu.writeAttribute("NEXTITEM", -1);
2189 
2190 			bool prevTopParentCheck = (master == ItemSelectionGroup);
2191 			if (master != ItemSelectionGroup)
2192 			{
2193 				PageItem* prevTopParent = item->prevInChain();
2194 				while (prevTopParent && prevTopParent->Parent)
2195 					prevTopParent = prevTopParent->Parent;
2196 				prevTopParentCheck = items->contains(prevTopParent);
2197 			}
2198 
2199 			if (item->prevInChain() != nullptr && prevTopParentCheck)
2200 				docu.writeAttribute("BACKITEM", qHash(item->prevInChain()) & 0x7FFFFFFF);
2201 			else
2202 			{
2203 				docu.writeAttribute("BACKITEM", -1);
2204 				if (item->isNoteFrame())
2205 					docu.writeAttribute("isNoteFrame", 1);
2206 				else if (item->isTextFrame() || item->isPathText())
2207 					writeStoryText(doc, docu, item->itemText, item);
2208 			}
2209 		}
2210 
2211 		if (item->isWelded())
2212 		{
2213 			// bool isWelded = false;
2214 			for (int i = 0 ; i <  item->weldList.count(); i++)
2215 			{
2216 				PageItem::WeldingInfo wInf = item->weldList.at(i);
2217 				PageItem *pIt = wInf.weldItem;
2218 				if (pIt == nullptr)
2219 				{
2220 					qDebug() << "Saving welding info - empty pointer!!!";
2221 					continue;
2222 				}
2223 				if (pIt->isAutoNoteFrame())
2224 					continue;
2225 				docu.writeEmptyElement("WeldEntry");
2226 				docu.writeAttribute("Target", qHash(wInf.weldItem) & 0x7FFFFFFF);
2227 				docu.writeAttribute("WX", wInf.weldPoint.x());
2228 				docu.writeAttribute("WY", wInf.weldPoint.y());
2229 			}
2230 		}
2231 		if (item->effectsInUse.count() != 0)
2232 		{
2233 			for (int a = 0; a < item->effectsInUse.count(); ++a)
2234 			{
2235 				docu.writeEmptyElement("ImageEffect");
2236 				docu.writeAttribute("Code", item->effectsInUse.at(a).effectCode);
2237 				docu.writeAttribute("Param", item->effectsInUse.at(a).effectParameters);
2238 			}
2239 		}
2240 		if (((item->isImageFrame()) || (item->isTextFrame())) && (!item->Pfile.isEmpty()) && (item->pixm.imgInfo.layerInfo.count() != 0) && (item->pixm.imgInfo.isRequest))
2241 		{
2242 			for (auto it2 = item->pixm.imgInfo.RequestProps.begin(); it2 != item->pixm.imgInfo.RequestProps.end(); ++it2)
2243 			{
2244 				docu.writeEmptyElement("PSDLayer");
2245 				docu.writeAttribute("Layer",it2.key());
2246 				docu.writeAttribute("Visible", static_cast<int>(it2.value().visible));
2247 				docu.writeAttribute("useMask", static_cast<int>(it2.value().useMask));
2248 				docu.writeAttribute("Opacity", it2.value().opacity);
2249 				docu.writeAttribute("Blend", it2.value().blend);
2250 			}
2251 		}
2252 		if (((item->GrType > 0) && (item->GrType != Gradient_Pattern) && (item->GrType != Gradient_4Colors) && (item->GrType != Gradient_Mesh) && (item->GrType != Gradient_Hatch)) && (item->gradient().isEmpty()))
2253 		{
2254 			QList<VColorStop*> cstops = item->fill_gradient.colorStops();
2255 			for (int cst = 0; cst < item->fill_gradient.stops(); ++cst)
2256 			{
2257 				docu.writeEmptyElement("CSTOP");
2258 				docu.writeAttribute("RAMP", cstops.at(cst)->rampPoint);
2259 				docu.writeAttribute("NAME", cstops.at(cst)->name);
2260 				docu.writeAttribute("SHADE", cstops.at(cst)->shade);
2261 				docu.writeAttribute("TRANS", cstops.at(cst)->opacity);
2262 			}
2263 		}
2264 		if ((item->GrTypeStroke > 0) && (item->strokeGradient().isEmpty()))
2265 		{
2266 			QList<VColorStop*> cstops = item->stroke_gradient.colorStops();
2267 			for (int cst = 0; cst < item->stroke_gradient.stops(); ++cst)
2268 			{
2269 				docu.writeEmptyElement("S_CSTOP");
2270 				docu.writeAttribute("RAMP", cstops.at(cst)->rampPoint);
2271 				docu.writeAttribute("NAME", cstops.at(cst)->name);
2272 				docu.writeAttribute("SHADE", cstops.at(cst)->shade);
2273 				docu.writeAttribute("TRANS", cstops.at(cst)->opacity);
2274 			}
2275 		}
2276 		if ((item->GrMask > 0) && (item->gradientMask().isEmpty()))
2277 		{
2278 			QList<VColorStop*> cstops = item->mask_gradient.colorStops();
2279 			for (int cst = 0; cst < item->mask_gradient.stops(); ++cst)
2280 			{
2281 				docu.writeEmptyElement("M_CSTOP");
2282 				docu.writeAttribute("RAMP", cstops.at(cst)->rampPoint);
2283 				docu.writeAttribute("NAME", cstops.at(cst)->name);
2284 				docu.writeAttribute("SHADE", cstops.at(cst)->shade);
2285 				docu.writeAttribute("TRANS", cstops.at(cst)->opacity);
2286 			}
2287 		}
2288 		if (item->GrType == Gradient_Mesh)
2289 		{
2290 			for (int grow = 0; grow < item->meshGradientArray.count(); grow++)
2291 			{
2292 				for (int gcol = 0; gcol < item->meshGradientArray[grow].count(); gcol++)
2293 				{
2294 					MeshPoint mp = item->meshGradientArray[grow][gcol];
2295 					docu.writeStartElement("MPoint");
2296 					docu.writeAttribute("GX", mp.gridPoint.x());
2297 					docu.writeAttribute("GY", mp.gridPoint.y());
2298 					docu.writeAttribute("CTX", mp.controlTop.x());
2299 					docu.writeAttribute("CTY", mp.controlTop.y());
2300 					docu.writeAttribute("CBX", mp.controlBottom.x());
2301 					docu.writeAttribute("CBY", mp.controlBottom.y());
2302 					docu.writeAttribute("CLX", mp.controlLeft.x());
2303 					docu.writeAttribute("CLY", mp.controlLeft.y());
2304 					docu.writeAttribute("CRX", mp.controlRight.x());
2305 					docu.writeAttribute("CRY", mp.controlRight.y());
2306 					docu.writeAttribute("CCX", mp.controlColor.x());
2307 					docu.writeAttribute("CCY", mp.controlColor.y());
2308 					docu.writeAttribute("NAME", mp.colorName);
2309 					docu.writeAttribute("SHADE", mp.shade);
2310 					docu.writeAttribute("TRANS", mp.transparency);
2311 					docu.writeEndElement();
2312 				}
2313 			}
2314 		}
2315 		if (item->GrType == Gradient_PatchMesh)
2316 		{
2317 			for (int grow = 0; grow < item->meshGradientPatches.count(); grow++)
2318 			{
2319 				meshGradientPatch patch = item->meshGradientPatches[grow];
2320 				for (int gcol = 0; gcol < 4; gcol++)
2321 				{
2322 					MeshPoint mp;
2323 					docu.writeStartElement("PMPoint");
2324 					if (gcol == 0)
2325 					{
2326 						mp = patch.TL;
2327 						docu.writeAttribute("CBX", mp.controlBottom.x());
2328 						docu.writeAttribute("CBY", mp.controlBottom.y());
2329 						docu.writeAttribute("CRX", mp.controlRight.x());
2330 						docu.writeAttribute("CRY", mp.controlRight.y());
2331 					}
2332 					else if (gcol == 1)
2333 					{
2334 						mp = patch.TR;
2335 						docu.writeAttribute("CBX", mp.controlBottom.x());
2336 						docu.writeAttribute("CBY", mp.controlBottom.y());
2337 						docu.writeAttribute("CLX", mp.controlLeft.x());
2338 						docu.writeAttribute("CLY", mp.controlLeft.y());
2339 					}
2340 					else if (gcol == 2)
2341 					{
2342 						mp = patch.BR;
2343 						docu.writeAttribute("CTX", mp.controlTop.x());
2344 						docu.writeAttribute("CTY", mp.controlTop.y());
2345 						docu.writeAttribute("CLX", mp.controlLeft.x());
2346 						docu.writeAttribute("CLY", mp.controlLeft.y());
2347 					}
2348 					else if (gcol == 3)
2349 					{
2350 						mp = patch.BL;
2351 						docu.writeAttribute("CTX", mp.controlTop.x());
2352 						docu.writeAttribute("CTY", mp.controlTop.y());
2353 						docu.writeAttribute("CRX", mp.controlRight.x());
2354 						docu.writeAttribute("CRY", mp.controlRight.y());
2355 					}
2356 					docu.writeAttribute("GX", mp.gridPoint.x());
2357 					docu.writeAttribute("GY", mp.gridPoint.y());
2358 					docu.writeAttribute("CCX", mp.controlColor.x());
2359 					docu.writeAttribute("CCY", mp.controlColor.y());
2360 					docu.writeAttribute("NAME", mp.colorName);
2361 					docu.writeAttribute("SHADE", mp.shade);
2362 					docu.writeAttribute("TRANS", mp.transparency);
2363 					docu.writeEndElement();
2364 				}
2365 			}
2366 		}
2367 
2368 		if (item->isLatexFrame())
2369 		{
2370 			docu.writeStartElement("LATEX");
2371 			PageItem_LatexFrame *latexitem = item->asLatexFrame();
2372 			QFileInfo fi(latexitem->configFile());
2373 			docu.writeAttribute("ConfigFile", fi.fileName());
2374 			docu.writeAttribute("DPI", latexitem->dpi());
2375 			docu.writeAttribute("USE_PREAMBLE", latexitem->usePreamble());
2376 			QMapIterator<QString, QString> i(latexitem->editorProperties);
2377 			while (i.hasNext())
2378 			{
2379 				i.next();
2380 				docu.writeStartElement("PROPERTY");
2381 				docu.writeAttribute("name", i.key());
2382 				docu.writeAttribute("value", i.value());
2383 				docu.writeEndElement();
2384 			}
2385 			docu.writeCharacters(latexitem->formula());
2386 			docu.writeEndElement();
2387 			/*QDomText latextext = docu->createTextNode(latexitem->formula());
2388 			latexinfo.appendChild(latextext);
2389 			ob.appendChild(latexinfo);*/
2390 		}
2391 #ifdef HAVE_OSG
2392 		if (item->isOSGFrame())
2393 		{
2394 			PageItem_OSGFrame *osgitem = item->asOSGFrame();
2395 			if (!item->Pfile.isEmpty())
2396 			{
2397 				for (auto itv = osgitem->viewMap.begin(); itv != osgitem->viewMap.end(); ++itv)
2398 				{
2399 					QString tmp;
2400 					docu.writeStartElement("OSGViews");
2401 					docu.writeAttribute("viewName", itv.key());
2402 					docu.writeAttribute("angleFOV", itv.value().angleFOV);
2403 					QString trackM = "";
2404 					for (uint matx = 0; matx < 4; ++matx)
2405 					{
2406 						for (uint maty = 0; maty < 4; ++maty)
2407 						{
2408 							trackM += tmp.setNum(itv.value().trackerMatrix(matx, maty))+" ";
2409 						}
2410 					}
2411 					docu.writeAttribute("trackM", trackM);
2412 					QString trackC = "";
2413 					trackC += tmp.setNum(itv.value().trackerCenter[0])+" ";
2414 					trackC += tmp.setNum(itv.value().trackerCenter[1])+" ";
2415 					trackC += tmp.setNum(itv.value().trackerCenter[2]);
2416 					docu.writeAttribute("trackC", trackC);
2417 					QString cameraP = "";
2418 					cameraP += tmp.setNum(itv.value().cameraPosition[0])+" ";
2419 					cameraP += tmp.setNum(itv.value().cameraPosition[1])+" ";
2420 					cameraP += tmp.setNum(itv.value().cameraPosition[2]);
2421 					docu.writeAttribute("cameraP", cameraP);
2422 					QString cameraU = "";
2423 					cameraU += tmp.setNum(itv.value().cameraUp[0])+" ";
2424 					cameraU += tmp.setNum(itv.value().cameraUp[1])+" ";
2425 					cameraU += tmp.setNum(itv.value().cameraUp[2]);
2426 					docu.writeAttribute("cameraU", cameraU);
2427 					docu.writeAttribute("trackerDist", itv.value().trackerDist);
2428 					docu.writeAttribute("trackerSize", itv.value().trackerSize);
2429 					docu.writeAttribute("illumination", itv.value().illumination);
2430 					docu.writeAttribute("rendermode", itv.value().rendermode);
2431 					docu.writeAttribute("trans", itv.value().addedTransparency);
2432 					docu.writeAttribute("colorAC", itv.value().colorAC.name());
2433 					docu.writeAttribute("colorFC", itv.value().colorFC.name());
2434 					docu.writeEndElement();
2435 				}
2436 			}
2437 		}
2438 #endif
2439 		if (item->isGroup())
2440 		{
2441 			WriteObjects(m_Doc, docu, baseDir, nullptr, 0, ItemSelectionGroup, &item->groupItemList);
2442 		}
2443 		//Write all the cells and their data to the document, as sub-elements of the pageitem.
2444 		if (item->isTable())
2445 		{
2446 			//PTYPE == PageItem::Table or 16 (pageitem.h)
2447 			PageItem_Table* tableItem = item->asTable();
2448 			docu.writeStartElement("TableData");
2449 			QString tstyle = tableItem->styleName();
2450 			docu.writeAttribute("Style", tableItem->styleName());
2451 			TableStyle ts;
2452 			if (!tstyle.isEmpty())
2453 				ts = tableItem->style();
2454 
2455 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && (!ts.isInhFillColor())))
2456 				docu.writeAttribute("FillColor", tableItem->fillColor());
2457 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && ( !ts.isInhFillShade())))
2458 				docu.writeAttribute("FillShade", tableItem->fillShade());
2459 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && ( !ts.isInhLeftBorder())))
2460 			{
2461 				TableBorder tbLeft = tableItem->leftBorder();
2462 				docu.writeStartElement("TableBorderLeft");
2463 				for (const TableBorderLine& tbl : tbLeft.borderLines())
2464 				{
2465 					docu.writeStartElement("TableBorderLine");
2466 					docu.writeAttribute("Width", tbl.width());
2467 					docu.writeAttribute("PenStyle", tbl.style());
2468 					docu.writeAttribute("Color", tbl.color());
2469 					docu.writeAttribute("Shade", tbl.shade());
2470 					docu.writeEndElement();
2471 				}
2472 				docu.writeEndElement();
2473 			}
2474 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && ( !ts.isInhRightBorder())))
2475 			{
2476 				TableBorder tbRight = tableItem->rightBorder();
2477 				docu.writeStartElement("TableBorderRight");
2478 				for (const TableBorderLine& tbl : tbRight.borderLines())
2479 				{
2480 					docu.writeStartElement("TableBorderLine");
2481 					docu.writeAttribute("Width", tbl.width());
2482 					docu.writeAttribute("PenStyle", tbl.style());
2483 					docu.writeAttribute("Color", tbl.color());
2484 					docu.writeAttribute("Shade", tbl.shade());
2485 					docu.writeEndElement();
2486 				}
2487 				docu.writeEndElement();
2488 			}
2489 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && ( !ts.isInhTopBorder())))
2490 			{
2491 				TableBorder tbTop = tableItem->topBorder();
2492 				docu.writeStartElement("TableBorderTop");
2493 				for (const TableBorderLine& tbl : tbTop.borderLines())
2494 				{
2495 					docu.writeStartElement("TableBorderLine");
2496 					docu.writeAttribute("Width", tbl.width());
2497 					docu.writeAttribute("PenStyle", tbl.style());
2498 					docu.writeAttribute("Color", tbl.color());
2499 					docu.writeAttribute("Shade", tbl.shade());
2500 					docu.writeEndElement();
2501 				}
2502 				docu.writeEndElement();
2503 			}
2504 			if ((tstyle.isEmpty()) || ((!tstyle.isEmpty()) && ( !ts.isInhBottomBorder())))
2505 			{
2506 				TableBorder tbBottom = tableItem->bottomBorder();
2507 				docu.writeStartElement("TableBorderBottom");
2508 				for (const TableBorderLine& tbl : tbBottom.borderLines())
2509 				{
2510 					docu.writeStartElement("TableBorderLine");
2511 					docu.writeAttribute("Width", tbl.width());
2512 					docu.writeAttribute("PenStyle", tbl.style());
2513 					docu.writeAttribute("Color", tbl.color());
2514 					docu.writeAttribute("Shade", tbl.shade());
2515 					docu.writeEndElement();
2516 				}
2517 				docu.writeEndElement();
2518 			}
2519 			//for each cell, write it to the doc
2520 			for (int row = 0; row < tableItem->rows(); ++row)
2521 			{
2522 				for (int col = 0; col < tableItem->columns(); col ++)
2523 				{
2524 					TableCell cell = tableItem->cellAt(row, col);
2525 					if (cell.row() != row || cell.column() != col)
2526 						continue;
2527 					PageItem* textFrame = cell.textFrame();
2528 					docu.writeStartElement("Cell");
2529 					docu.writeAttribute("Row", cell.row());
2530 					docu.writeAttribute("Column", cell.column());
2531 					docu.writeAttribute("Style", cell.styleName());
2532 					docu.writeAttribute("TextColumns", textFrame->columns());
2533 					docu.writeAttribute("TextColGap", textFrame->columnGap());
2534 					docu.writeAttribute("TextDistLeft", textFrame->textToFrameDistLeft());
2535 					docu.writeAttribute("TextDistTop", textFrame->textToFrameDistTop());
2536 					docu.writeAttribute("TextDistBottom", textFrame->textToFrameDistBottom());
2537 					docu.writeAttribute("TextDistRight", textFrame->textToFrameDistRight());
2538 					docu.writeAttribute("TextVertAlign", textFrame->verticalAlignment());
2539 					docu.writeAttribute("Flop", textFrame->firstLineOffset());
2540 
2541 					QString cstyle = cell.styleName();
2542 					CellStyle cs;
2543 					if (!cstyle.isEmpty())
2544 						cs = cell.style();
2545 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhFillColor())))
2546 						docu.writeAttribute("FillColor", cell.fillColor());
2547 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhFillShade())))
2548 						docu.writeAttribute("FillShade", cell.fillShade());
2549 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhLeftPadding())))
2550 						docu.writeAttribute("LeftPadding",cell.leftPadding());
2551 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhRightPadding())))
2552 						docu.writeAttribute("RightPadding", cell.rightPadding());
2553 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhTopPadding())))
2554 						docu.writeAttribute("TopPadding",cell.topPadding());
2555 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhBottomPadding())))
2556 						docu.writeAttribute("BottomPadding", cell.bottomPadding());
2557 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhLeftBorder())))
2558 					{
2559 						TableBorder tbLeft = cell.leftBorder();
2560 						docu.writeStartElement("TableBorderLeft");
2561 						docu.writeAttribute("Width", tbLeft.width());
2562 						for (const TableBorderLine& tbl : tbLeft.borderLines())
2563 						{
2564 							docu.writeStartElement("TableBorderLine");
2565 							docu.writeAttribute("Width", tbl.width());
2566 							docu.writeAttribute("PenStyle", tbl.style());
2567 							docu.writeAttribute("Color", tbl.color());
2568 							docu.writeAttribute("Shade", tbl.shade());
2569 							docu.writeEndElement();
2570 						}
2571 						docu.writeEndElement();
2572 					}
2573 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhRightBorder())))
2574 					{
2575 						TableBorder tbRight = cell.rightBorder();
2576 						docu.writeStartElement("TableBorderRight");
2577 						docu.writeAttribute("Width", tbRight.width());
2578 						for (const TableBorderLine& tbl : tbRight.borderLines())
2579 						{
2580 							docu.writeStartElement("TableBorderLine");
2581 							docu.writeAttribute("Width", tbl.width());
2582 							docu.writeAttribute("PenStyle", tbl.style());
2583 							docu.writeAttribute("Color", tbl.color());
2584 							docu.writeAttribute("Shade", tbl.shade());
2585 							docu.writeEndElement();
2586 						}
2587 						docu.writeEndElement();
2588 					}
2589 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhTopBorder())))
2590 					{
2591 						TableBorder tbTop = cell.topBorder();
2592 						docu.writeStartElement("TableBorderTop");
2593 						docu.writeAttribute("Width", tbTop.width());
2594 						for (const TableBorderLine& tbl : tbTop.borderLines())
2595 						{
2596 							docu.writeStartElement("TableBorderLine");
2597 							docu.writeAttribute("Width", tbl.width());
2598 							docu.writeAttribute("PenStyle", tbl.style());
2599 							docu.writeAttribute("Color", tbl.color());
2600 							docu.writeAttribute("Shade", tbl.shade());
2601 							docu.writeEndElement();
2602 						}
2603 						docu.writeEndElement();
2604 					}
2605 					if ((cstyle.isEmpty()) || ((!cstyle.isEmpty()) && ( !cs.isInhBottomBorder())))
2606 					{
2607 						TableBorder tbBottom = cell.bottomBorder();
2608 						docu.writeStartElement("TableBorderBottom");
2609 						docu.writeAttribute("Width", tbBottom.width());
2610 						for (const TableBorderLine& tbl : tbBottom.borderLines())
2611 						{
2612 							docu.writeStartElement("TableBorderLine");
2613 							docu.writeAttribute("Width", tbl.width());
2614 							docu.writeAttribute("PenStyle", tbl.style());
2615 							docu.writeAttribute("Color", tbl.color());
2616 							docu.writeAttribute("Shade", tbl.shade());
2617 							docu.writeEndElement();
2618 						}
2619 						docu.writeEndElement();
2620 					}
2621 					//End Cell
2622 
2623 					writeStoryText(doc, docu, cell.textFrame()->itemText);
2624 					docu.writeEndElement();
2625 				}
2626 			}
2627 			docu.writeEndElement();
2628 		}
2629 
2630 		//CB PageItemAttributes
2631 		ObjAttrVector *attributes=item->getObjectAttributes();
2632 		if (attributes->count() > 0)
2633 		{
2634 			docu.writeStartElement("PageItemAttributes");
2635 			for (ObjAttrVector::Iterator objAttrIt = attributes->begin() ; objAttrIt != attributes->end(); ++objAttrIt )
2636 			{
2637 				docu.writeEmptyElement("ItemAttribute");
2638 				docu.writeAttribute("Name", objAttrIt->name);
2639 				docu.writeAttribute("Type", objAttrIt->type);
2640 				docu.writeAttribute("Value", objAttrIt->value);
2641 				docu.writeAttribute("Parameter", objAttrIt->parameter);
2642 				docu.writeAttribute("Relationship", objAttrIt->relationship);
2643 				docu.writeAttribute("RelationshipTo", objAttrIt->relationshipto);
2644 				docu.writeAttribute("AutoAddTo", objAttrIt->autoaddto);
2645 			}
2646 			docu.writeEndElement();
2647 		}
2648 		docu.writeEndElement();
2649 	}
2650 }
2651 
SetItemProps(ScXmlStreamWriter & docu,PageItem * item,const QString & baseDir)2652 void Scribus150Format::SetItemProps(ScXmlStreamWriter& docu, PageItem* item, const QString& baseDir)
2653 {
2654 	docu.writeAttribute("OwnPage", item->OwnPage);
2655 	docu.writeAttribute("ItemID", qHash(item) & 0x7FFFFFFF);
2656 	docu.writeAttribute("PTYPE", item->realItemType());
2657 	docu.writeAttribute("WIDTH", item->width());
2658 	docu.writeAttribute("HEIGHT", item->height());
2659 	if (item->cornerRadius() != 0)
2660 		docu.writeAttribute("RADRECT", item->cornerRadius());
2661 	docu.writeAttribute("FRTYPE", item->FrameType);
2662 	docu.writeAttribute("CLIPEDIT", item->ClipEdited ? 1 : 0);
2663 	if (item->GrType != 0)
2664 		docu.writeAttribute("GRTYP", item->GrType);
2665 	if (item->GrTypeStroke != 0)
2666 		docu.writeAttribute("GRTYPS", item->GrTypeStroke);
2667 	if (item->rotation() != 0)
2668 		docu.writeAttribute("ROT", item->rotation());
2669 	if (!item->printEnabled())
2670 		docu.writeAttribute("PRINTABLE", 0);
2671 	if (item->imageFlippedH())
2672 		docu.writeAttribute("FLIPPEDH", 1);
2673 	if (item->imageFlippedV())
2674 		docu.writeAttribute("FLIPPEDV", 1);
2675 	if (!(item->isGroup() || item->isSymbol()))
2676 	{
2677 		docu.writeAttribute("PWIDTH", item->lineWidth());
2678 		if (item->fillColor() != CommonStrings::None)
2679 			docu.writeAttribute("PCOLOR", item->fillColor());
2680 		if (item->fillShade() != 100)
2681 			docu.writeAttribute("SHADE", item->fillShade());
2682 		if (item->lineColor() != CommonStrings::None)
2683 			docu.writeAttribute("PCOLOR2", item->lineColor());
2684 		if (item->lineShade() != 100)
2685 			docu.writeAttribute("SHADE2", item->lineShade());
2686 		if (!item->NamedLStyle.isEmpty())
2687 			docu.writeAttribute("NAMEDLST", item->NamedLStyle);
2688 		if (item->PLineArt != 0)
2689 			docu.writeAttribute("PLINEART", item->PLineArt);
2690 		if (item->PLineEnd != 0)
2691 			docu.writeAttribute("PLINEEND", item->PLineEnd);
2692 		if (item->PLineJoin != 0)
2693 			docu.writeAttribute("PLINEJOIN", item->PLineJoin);
2694 	}
2695 	//write weld parameter
2696 	if (item->isWelded())
2697 	{
2698 		bool isWelded = false;
2699 		for (int i = 0 ; i <  item->weldList.count(); i++)
2700 		{
2701 			PageItem::WeldingInfo wInf = item->weldList.at(i);
2702 			PageItem *pIt = wInf.weldItem;
2703 			if (pIt != nullptr && !pIt->isAutoNoteFrame())
2704 			{
2705 				isWelded = true;
2706 				break;
2707 			}
2708 		}
2709 		if (isWelded)
2710 		{
2711 			docu.writeAttribute("isWeldItem", 1);
2712 			docu.writeAttribute("WeldSource", qHash(item) & 0x7FFFFFFF);
2713 		}
2714 	}
2715 	if (item->isRegularPolygon())
2716 	{
2717 		PageItem_RegularPolygon *regitem = item->asRegularPolygon();
2718 		docu.writeAttribute("POLYC", regitem->polyCorners);
2719 		docu.writeAttribute("POLYF", regitem->polyFactor);
2720 		docu.writeAttribute("POLYR", regitem->polyRotation);
2721 		docu.writeAttribute("POLYIR", regitem->polyInnerRot);
2722 		docu.writeAttribute("POLYCUR", regitem->polyCurvature);
2723 		docu.writeAttribute("POLYOCUR", regitem->polyOuterCurvature);
2724 		docu.writeAttribute("POLYS", static_cast<int>(regitem->polyUseFactor));
2725 	}
2726 	if (item->isArc())
2727 	{
2728 		PageItem_Arc *arcitem = item->asArc();
2729 		docu.writeAttribute("arcHeight", arcitem->arcHeight);
2730 		docu.writeAttribute("arcWidth", arcitem->arcWidth);
2731 		docu.writeAttribute("arcStartAngle", arcitem->arcStartAngle);
2732 		docu.writeAttribute("arcSweepAngle", arcitem->arcSweepAngle);
2733 	}
2734 	if (item->isSpiral())
2735 	{
2736 		PageItem_Spiral *arcitem = item->asSpiral();
2737 		docu.writeAttribute("spiralStartAngle", arcitem->spiralStartAngle);
2738 		docu.writeAttribute("spiralEndAngle", arcitem->spiralEndAngle);
2739 		docu.writeAttribute("spiralFactor", arcitem->spiralFactor);
2740 	}
2741 	if (item->isAnnotation())
2742 	{
2743 		docu.writeAttribute("ANNOTATION",1);
2744 		docu.writeAttribute("ANTYPE", item->annotation().Type());
2745 		docu.writeAttribute("ANACTION", item->annotation().Action());
2746 		docu.writeAttribute("ANEACT", item->annotation().E_act());
2747 		docu.writeAttribute("ANXACT", item->annotation().X_act());
2748 		docu.writeAttribute("ANDACT", item->annotation().D_act());
2749 		docu.writeAttribute("ANFOACT", item->annotation().Fo_act());
2750 		docu.writeAttribute("ANBLACT", item->annotation().Bl_act());
2751 		docu.writeAttribute("ANKACT", item->annotation().K_act());
2752 		docu.writeAttribute("ANFACT", item->annotation().F_act());
2753 		docu.writeAttribute("ANVACT", item->annotation().V_act());
2754 		docu.writeAttribute("ANCACT", item->annotation().C_act());
2755 		if (item->annotation().ActionType() == Annotation::Action_URI)
2756 			docu.writeAttribute("ANEXTERN", item->annotation().Extern());
2757 		else
2758 			docu.writeAttribute("ANEXTERN", Path2Relative(item->annotation().Extern(), baseDir));
2759 		docu.writeAttribute("ANZIEL", item->annotation().Ziel());
2760 		docu.writeAttribute("ANACTYP", item->annotation().ActionType());
2761 		docu.writeAttribute("ANTOOLTIP", item->annotation().ToolTip());
2762 		docu.writeAttribute("ANBWID", item->annotation().borderWidth());
2763 		docu.writeAttribute("ANBSTY", item->annotation().borderStyle());
2764 		docu.writeAttribute("ANFEED", item->annotation().Feed());
2765 		docu.writeAttribute("ANFLAG", item->annotation().Flag());
2766 		docu.writeAttribute("ANFONT", item->annotation().Font());
2767 		docu.writeAttribute("ANFORMAT", item->annotation().Format());
2768 		docu.writeAttribute("ANROLL", item->annotation().RollOver());
2769 		docu.writeAttribute("ANDOWN", item->annotation().Down());
2770 		docu.writeAttribute("ANVIS", item->annotation().Vis());
2771 		docu.writeAttribute("ANMC", item->annotation().MaxChar());
2772 		docu.writeAttribute("ANCHK", item->annotation().IsChk());
2773 		docu.writeAttribute("ANAA", item->annotation().AAact());
2774 		docu.writeAttribute("ANCHKS", item->annotation().ChkStil());
2775 		docu.writeAttribute("ANBCOL", item->annotation().borderColor());
2776 		docu.writeAttribute("ANHTML", item->annotation().HTML());
2777 		docu.writeAttribute("ANICON", item->annotation().UseIcons());
2778 		docu.writeAttribute("ANPLACE", item->annotation().IPlace());
2779 		docu.writeAttribute("ANSCALE", item->annotation().ScaleW());
2780 		docu.writeAttribute("ANITYP", item->annotation().Icon());
2781 		docu.writeAttribute("ANOPEN", item->annotation().IsAnOpen());
2782 	}
2783 	if (!item->AutoName)
2784 		docu.writeAttribute("ANNAME", item->itemName());
2785 	// "TEXTFLOWMODE" succeed to "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes
2786 	if (item->textFlowMode() != 0)
2787 		docu.writeAttribute("TEXTFLOWMODE", (int) item->textFlowMode() );
2788 	// Set "TEXTFLOW" "TEXTFLOW2" and "TEXTFLOW3" attributes for compatibility
2789 	// with versions prior to 1.3.4
2790 //	docu.writeAttribute("TEXTFLOW" , item->textFlowAroundObject() ? 1 : 0);
2791 //	docu.writeAttribute("TEXTFLOW2", item->textFlowUsesBoundingBox() ? 1 : 0);
2792 //	docu.writeAttribute("TEXTFLOW3", item->textFlowUsesContourLine() ? 1 : 0);
2793 	if (item->isTextFrame() || item->isPathText() || item->isImageFrame())
2794 	{
2795 		docu.writeAttribute("LOCALSCX", item->imageXScale());
2796 		docu.writeAttribute("LOCALSCY", item->imageYScale());
2797 		docu.writeAttribute("LOCALX", item->imageXOffset());
2798 		docu.writeAttribute("LOCALY", item->imageYOffset());
2799 		docu.writeAttribute("LOCALROT" , item->imageRotation());
2800 		docu.writeAttribute("PICART", item->imageVisible() ? 1 : 0);
2801 		docu.writeAttribute("SCALETYPE", item->ScaleType ? 1 : 0);
2802 		docu.writeAttribute("RATIO", item->AspectRatio ? 1 : 0);
2803 	}
2804 	if (item->isTextFrame() || item->isPathText())
2805 	{
2806 		docu.writeAttribute("COLUMNS", item->columns());
2807 		docu.writeAttribute("COLGAP", item->columnGap());
2808 		docu.writeAttribute("AUTOTEXT", item->isAutoText ? 1 : 0);
2809 		docu.writeAttribute("EXTRA", item->textToFrameDistLeft());
2810 		docu.writeAttribute("TEXTRA", item->textToFrameDistTop());
2811 		docu.writeAttribute("BEXTRA", item->textToFrameDistBottom());
2812 		docu.writeAttribute("REXTRA", item->textToFrameDistRight());
2813 		docu.writeAttribute("VAlign", item->verticalAlignment());
2814 		docu.writeAttribute("FLOP", item->firstLineOffset()); // here I think this FLOP "cher à mon cœur" is legitimate!
2815 		docu.writeAttribute("PLTSHOW", item->PoShow ? 1 : 0);
2816 		docu.writeAttribute("BASEOF", item->BaseOffs);
2817 		docu.writeAttribute("textPathType", item->textPathType);
2818 		docu.writeAttribute("textPathFlipped", static_cast<int>(item->textPathFlipped));
2819 	}
2820 #ifdef HAVE_OSG
2821 	if (((item->isImageFrame() && !(item->isLatexFrame() || item->isOSGFrame())) || (item->isTextFrame())) && (!item->Pfile.isEmpty()))
2822 #else
2823 	if (((item->isImageFrame() && !(item->isLatexFrame())) || (item->isTextFrame())) && (!item->Pfile.isEmpty()))
2824 #endif
2825 	{
2826 		docu.writeAttribute("Pagenumber", item->pixm.imgInfo.actualPageNumber);
2827 		if (item->isInlineImage)
2828 		{
2829 			docu.writeAttribute("PFILE", "");
2830 			docu.writeAttribute("isInlineImage", static_cast<int>(item->isInlineImage));
2831 			QFileInfo inlFi(item->Pfile);
2832 			docu.writeAttribute("inlineImageExt", inlFi.suffix());
2833 			QFile inFil(item->Pfile);
2834 			if (inFil.open(QIODevice::ReadOnly))
2835 			{
2836 				QByteArray ba = qCompress(inFil.readAll()).toBase64();
2837 				docu.writeAttribute("ImageData", QString(ba));
2838 				inFil.close();
2839 			}
2840 		}
2841 		else
2842 			docu.writeAttribute("PFILE",Path2Relative(item->Pfile, baseDir));
2843 	}
2844 #ifdef HAVE_OSG
2845 	else if (item->isOSGFrame())
2846 	{
2847 		if (!item->Pfile.isEmpty())
2848 		{
2849 			docu.writeAttribute("PFILE", "");
2850 			docu.writeAttribute("isInlineImage", static_cast<int>(item->isInlineImage));
2851 			QFileInfo inlFi(item->Pfile);
2852 			docu.writeAttribute("inlineImageExt", inlFi.suffix());
2853 			QFile inFil(item->Pfile);
2854 			if (inFil.open(QIODevice::ReadOnly))
2855 			{
2856 				QByteArray ba = qCompress(inFil.readAll()).toBase64();
2857 				docu.writeAttribute("ImageData", QString(ba));
2858 				inFil.close();
2859 			}
2860 			PageItem_OSGFrame *osgframe = item->asOSGFrame();
2861 			docu.writeAttribute("modelFile", Path2Relative(osgframe->modelFile, baseDir));
2862 			docu.writeAttribute("currentViewName", osgframe->currentView);
2863 		}
2864 	}
2865 #endif
2866 	if (!item->Pfile2.isEmpty())
2867 		docu.writeAttribute("PFILE2",Path2Relative(item->Pfile2, baseDir));
2868 	if (!item->Pfile3.isEmpty())
2869 		docu.writeAttribute("PFILE3",Path2Relative(item->Pfile3, baseDir));
2870 	if (!item->ImageProfile.isEmpty())
2871 		docu.writeAttribute("PRFILE", item->ImageProfile);
2872 	if (item->ImageIntent != 1)
2873 		docu.writeAttribute("IRENDER", item->ImageIntent);
2874 	if (!item->EmbeddedProfile.isEmpty())
2875 		docu.writeAttribute("EPROF", item->EmbeddedProfile);
2876 	if (!item->UseEmbedded)
2877 		docu.writeAttribute("EMBEDDED", 0);
2878 	if (item->isImageFrame())
2879 	{
2880 		if (item->OverrideCompressionMethod)
2881 			docu.writeAttribute("COMPRESSIONMETHOD", item->CompressionMethodIndex);
2882 		if (item->OverrideCompressionQuality)
2883 			docu.writeAttribute("COMPRESSIONQUALITY", item->CompressionQualityIndex);
2884 	}
2885 	if (item->locked())
2886 		docu.writeAttribute("LOCK", 1);
2887 	if (item->sizeLocked())
2888 		docu.writeAttribute("LOCKR", 1);
2889 	if (item->fillTransparency() != 0)
2890 		docu.writeAttribute("TransValue", item->fillTransparency());
2891 	if (item->lineTransparency() != 0)
2892 		docu.writeAttribute("TransValueS", item->lineTransparency());
2893 	if (item->fillBlendmode() != 0)
2894 		docu.writeAttribute("TransBlend", item->fillBlendmode());
2895 	if (item->lineBlendmode() != 0)
2896 		docu.writeAttribute("TransBlendS", item->lineBlendmode());
2897 	if (item->hasSoftShadow())
2898 	{
2899 		docu.writeAttribute("HASSOFTSHADOW", item->hasSoftShadow() ? 1 : 0);
2900 		docu.writeAttribute("SOFTSHADOWXOFFSET", item->softShadowXOffset());
2901 		docu.writeAttribute("SOFTSHADOWYOFFSET", item->softShadowYOffset());
2902 		docu.writeAttribute("SOFTSHADOWCOLOR", item->softShadowColor());
2903 		docu.writeAttribute("SOFTSHADOWBLURRADIUS", item->softShadowBlurRadius());
2904 		docu.writeAttribute("SOFTSHADOWSHADE", item->softShadowShade());
2905 		docu.writeAttribute("SOFTSHADOWBLENDMODE", item->softShadowBlendMode());
2906 		docu.writeAttribute("SOFTSHADOWOPACITY", item->softShadowOpacity());
2907 		docu.writeAttribute("SOFTSHADOWERASE", item->softShadowErasedByObject());
2908 		docu.writeAttribute("SOFTSHADOWOBJTRANS", item->softShadowHasObjectTransparency());
2909 	}
2910 
2911 	QString tmp;
2912 	if (item->isTable())
2913 	{
2914 		//PTYPE == PageItem::Table or 16 (pageitem.h)
2915 		PageItem_Table* tableItem = item->asTable();
2916 		docu.writeAttribute("Rows", tableItem->rows());
2917 		docu.writeAttribute("Columns", tableItem->columns());
2918 
2919 		QString outputData;
2920 		//Row Positions
2921 		for (double value : tableItem->rowPositions())
2922 			outputData += tmp.setNum(value) + " ";
2923 		docu.writeAttribute("RowPositions", outputData.simplified());
2924 		outputData.clear();
2925 		//Row Heights
2926 		for (double value : tableItem->rowHeights())
2927 			outputData += tmp.setNum(value) + " ";
2928 		docu.writeAttribute("RowHeights", outputData.simplified());
2929 		outputData.clear();
2930 		//Column Positions
2931 		for (double value : tableItem->columnPositions())
2932 			outputData += tmp.setNum(value) + " ";
2933 		docu.writeAttribute("ColumnPositions", outputData.simplified());
2934 		outputData.clear();
2935 		//Column Widths
2936 		for (double value : tableItem->columnWidths())
2937 			outputData += tmp.setNum(value) + " ";
2938 		docu.writeAttribute("ColumnWidths", outputData.simplified());
2939 		outputData.clear();
2940 		//Cell Areas
2941 		//TODO Is this the best format to write these out?
2942 		QString tmp1,tmp2,tmp3,tmp4;
2943 		for (const CellArea& ca : tableItem->cellAreas())
2944 			outputData += tmp1.setNum(ca.row()) + " " + tmp2.setNum(ca.column()) + " " + tmp3.setNum(ca.height()) + " " + tmp4.setNum(ca.width()) + " ";
2945 		docu.writeAttribute("CellAreas", outputData.simplified());
2946 		outputData.clear();
2947 
2948 		docu.writeAttribute("TableStyle", tableItem->styleName());
2949 	}
2950 
2951 	if (item->isGroup())
2952 	{
2953 		docu.writeAttribute("groupWidth", item->groupWidth);
2954 		docu.writeAttribute("groupHeight", item->groupHeight);
2955 		docu.writeAttribute("groupClips", item->groupClipping());
2956 	}
2957 	if (item->DashValues.count() != 0)
2958 	{
2959 		docu.writeAttribute("NUMDASH", static_cast<int>(item->DashValues.count()));
2960 		QString dlp = "";
2961 		QVector<double>::Iterator dax;
2962 		for (dax = item->DashValues.begin(); dax != item->DashValues.end(); ++dax)
2963 			dlp += tmp.setNum((*dax)) + " ";
2964 		docu.writeAttribute("DASHS", dlp);
2965 		docu.writeAttribute("DASHOFF", item->DashOffset);
2966 	}
2967 	if (!(item->isArc() || item->isSpiral() || item->isRegularPolygon()))
2968 		docu.writeAttribute("path", item->PoLine.svgPath(!(item->isPolyLine() || item->isPathText())));
2969 	QString colp = item->ContourLine.svgPath(true);
2970 	if (!colp.isEmpty())
2971 		docu.writeAttribute("copath", colp);
2972 	if (item->isLine() || item->isPolyLine())
2973 	{
2974 		if (item->startArrowIndex() != 0)
2975 			docu.writeAttribute("startArrowIndex", item->startArrowIndex());
2976 		if (item->endArrowIndex() != 0)
2977 			docu.writeAttribute("endArrowIndex", item->endArrowIndex());
2978 		if (item->startArrowScale() != 100)
2979 			docu.writeAttribute("startArrowScale", item->startArrowScale());
2980 		if (item->endArrowScale() != 100)
2981 			docu.writeAttribute("endArrowScale", item->endArrowScale());
2982 	}
2983 }
2984