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 "pdfoptionsio.h"
8 #include "scribusstructs.h"
9
10 #include <QApplication>
11 #include <QList>
12 #include <QTextStream>
13
14 #include "scclocale.h"
15
16 const int PDFOptionsIO::formatVersion = 1300;
17
PDFOptionsIO(PDFOptions & opts)18 PDFOptionsIO::PDFOptionsIO(PDFOptions& opts) :
19 m_includePasswords(false),
20 m_error()
21 {
22 this->m_opts = &opts;
23 }
24
25 // writeTo(QString) is implemented separately to writeTo(QTextStream)
26 // because we don't want to clobber the output file until we know the
27 // data has been generated ok, and we can't avoid clobbering the file
28 // to create a QTextStream().
writeTo(const QString & outFileName,bool includePasswords)29 bool PDFOptionsIO::writeTo(const QString& outFileName, bool includePasswords)
30 {
31 m_includePasswords = includePasswords;
32 QString xml(buildXMLString());
33 if (xml.isNull())
34 return false;
35 QFile f(outFileName);
36 if (!f.open(QIODevice::WriteOnly|QIODevice::Truncate))
37 {
38 m_error = QObject::tr("Could not open output file %1")
39 .arg(qApp->translate("QFile",f.errorString().toLatin1().constData()));
40 return false;
41 }
42 QTextStream ts(&f);
43 ts.setCodec("UTF-8");
44 ts << xml;
45 m_includePasswords = false; // just to be paranoid
46 m_error.clear();
47 return true;
48 }
49
writeTo(QIODevice & outDevice,bool includePasswords)50 bool PDFOptionsIO::writeTo(QIODevice& outDevice, bool includePasswords)
51 {
52 m_includePasswords = includePasswords;
53 if (!outDevice.isWritable())
54 {
55 m_error = QObject::tr("Output stream not writeable");
56 return false;
57 }
58 QString xml = buildXMLString();
59 if (xml.isNull())
60 return false;
61 QTextStream ts(&outDevice);
62 ts.setCodec("UTF-8");
63 ts << xml;
64 m_includePasswords = false; // just to be paranoid
65 m_error.clear();
66 return true;
67 }
68
69 // Construct and return an XML string representing the settings
buildXMLString()70 QString PDFOptionsIO::buildXMLString()
71 {
72 // Verify to make sure our settings are sane
73 QString vrfyError;
74 // Make sure the options are sane
75 PDFOptions::VerifyResults vr = m_opts->verify(&vrfyError);
76 if (vr != PDFOptions::Verify_NoError)
77 {
78 m_error = QObject::tr("Verification of settings failed: %1").arg(vrfyError);
79 return QString();
80 }
81 // Build the document. Initial implementation uses QDom.
82 m_doc = QDomDocument();
83 m_root = m_doc.createElement("ScribusPDFOptions");
84 m_root.setAttribute("version", formatVersion);
85 m_doc.appendChild(m_root);
86 // Fill the guts of the document
87 buildSettings();
88 // We're done - return a string containing the document XML
89 QString xml = m_doc.toString();
90 xml.prepend(
91 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
92 "<!DOCTYPE ScribusPDFOptions SYSTEM 'scribuspdfoptions.dtd'>\n"
93 );
94 return xml;
95 }
96
97 // Build up the stored settings into the passed DOM objects
buildSettings()98 void PDFOptionsIO::buildSettings()
99 {
100 addElem(m_root, "firstUse", m_opts->firstUse);
101 addElem(m_root, "thumbnails", m_opts->Thumbnails);
102 addElem(m_root, "articles", m_opts->Articles);
103 addElem(m_root, "useLayers", m_opts->useLayers);
104 addElem(m_root, "compress", m_opts->Compress);
105 addElem(m_root, "compressMethod", m_opts->CompressMethod);
106 addElem(m_root, "quality", m_opts->Quality);
107 addElem(m_root, "recalcPic", m_opts->RecalcPic);
108 addElem(m_root, "bookmarks", m_opts->Bookmarks);
109 addElem(m_root, "picRes", m_opts->PicRes);
110 addElem(m_root, "embedPDF", m_opts->embedPDF);
111 QString pdfVersString;
112 switch (m_opts->Version)
113 {
114 case PDFVersion::PDF_X1a:
115 pdfVersString = "X1a";
116 break;
117 case PDFVersion::PDF_X3:
118 pdfVersString = "X3";
119 break;
120 case PDFVersion::PDF_X4:
121 pdfVersString = "X4";
122 break;
123 default:
124 pdfVersString = QString::number(m_opts->Version);
125 break;
126 }
127 addElem(m_root, "pdfVersion", pdfVersString);
128 addElem(m_root, "resolution", m_opts->Resolution);
129 addElem(m_root, "binding", m_opts->Binding);
130 QString embeddingModeString;
131 switch (m_opts->FontEmbedding)
132 {
133 case PDFOptions::OutlineFonts:
134 embeddingModeString = "OutlineFonts";
135 break;
136 case PDFOptions::DontEmbed:
137 embeddingModeString = "DontEmbed";
138 break;
139 default:
140 embeddingModeString = "EmbedFonts";
141 break;
142 }
143 addElem(m_root, "fontEmbedding", embeddingModeString);
144 addList(m_root, "embedFonts", m_opts->EmbedList);
145 addList(m_root, "subsetFonts", m_opts->SubsetList);
146 addElem(m_root, "mirrorH", m_opts->MirrorH);
147 addElem(m_root, "mirrorV", m_opts->MirrorV);
148 addElem(m_root, "rotateDegrees", m_opts->RotateDeg);
149 addElem(m_root, "presentMode", m_opts->PresentMode);
150 // addPresentationData();
151 addElem(m_root, "filename", m_opts->fileName);
152 addElem(m_root, "isGrayscale", m_opts->isGrayscale);
153 addElem(m_root, "useRGB", m_opts->UseRGB);
154 addElem(m_root, "useProfiles", m_opts->UseProfiles);
155 addElem(m_root, "useProfiles2", m_opts->UseProfiles2);
156 addElem(m_root, "useLPI", m_opts->UseLPI);
157 addElem(m_root, "useSpotColors", m_opts->UseSpotColors);
158 addElem(m_root, "doMultiFile", m_opts->doMultiFile);
159 addLPISettings();
160 addElem(m_root, "solidProf", m_opts->SolidProf);
161 addElem(m_root, "sComp", m_opts->SComp);
162 addElem(m_root, "imageProf", m_opts->ImageProf);
163 addElem(m_root, "embeddedI", m_opts->EmbeddedI);
164 addElem(m_root, "intent2", m_opts->Intent2);
165 addElem(m_root, "printProf", m_opts->PrintProf);
166 addElem(m_root, "info", m_opts->Info);
167 addElem(m_root, "intent", m_opts->Intent);
168 addElem(m_root, "bleedTop", m_opts->bleeds.top());
169 addElem(m_root, "bleedLeft", m_opts->bleeds.left());
170 addElem(m_root, "bleedRight", m_opts->bleeds.right());
171 addElem(m_root, "bleedBottom", m_opts->bleeds.bottom());
172 addElem(m_root, "encrypt", m_opts->Encrypt);
173 addElem(m_root, "passOwner", m_includePasswords ? m_opts->PassOwner : "");
174 addElem(m_root, "passUser", m_includePasswords ? m_opts->PassUser : "");
175 addElem(m_root, "permissions", m_opts->Permissions);
176 }
177
178 // Convenience functions to add a single-attribute element
179 // of a particular type to the tree at a given point.
180
addElem(QDomElement & addTo,const QString & name,bool value)181 void PDFOptionsIO::addElem(QDomElement& addTo, const QString& name, bool value)
182 {
183 QDomElement elem = m_doc.createElement(name);
184 elem.setAttribute("value", value ? "true" : "false" );
185 addTo.appendChild(elem);
186 }
187
addElem(QDomElement & addTo,const QString & name,const QString & value)188 void PDFOptionsIO::addElem(QDomElement& addTo, const QString& name, const QString& value)
189 {
190 QDomElement elem = m_doc.createElement(name);
191 elem.setAttribute("value",value);
192 addTo.appendChild(elem);
193 }
194
addElem(QDomElement & addTo,const QString & name,int value)195 void PDFOptionsIO::addElem(QDomElement& addTo, const QString& name, int value)
196 {
197 QDomElement elem = m_doc.createElement(name);
198 elem.setAttribute("value",value);
199 addTo.appendChild(elem);
200 }
201
addElem(QDomElement & addTo,const QString & name,double value)202 void PDFOptionsIO::addElem(QDomElement& addTo, const QString& name, double value)
203 {
204 QDomElement elem = m_doc.createElement(name);
205 elem.setAttribute("value",value);
206 addTo.appendChild(elem);
207 }
208
209 // Save a QValueList<String> or QStringList as a list of
210 // <item value=""> elements
addList(QDomElement & addTo,const QString & name,QList<QString> & value)211 void PDFOptionsIO::addList(QDomElement& addTo, const QString& name, QList<QString>& value)
212 {
213 // List base element has no attributes, only children
214 QDomElement listbase = m_doc.createElement(name);
215 addTo.appendChild(listbase);
216 QList<QString>::iterator it;
217 for (it = value.begin(); it != value.end(); ++it)
218 addElem(listbase, "item", *(it));
219 }
220
221 // save PDFOptions::PresentVals
addPresentationData()222 void PDFOptionsIO::addPresentationData()
223 {
224 // PDFOptions::PresentVals is a QValueList<PDFPresentationData>
225 //
226 // XML structure will be like this:
227 // <presentationSettings>
228 // <presentationSettingsEntry>
229 // <pageEffectDuration value="0"/>
230 // <pageViewDuration value="0"/>
231 // <effectType value="0"/>
232 // <dm value="0"/>
233 // <m value="0"/>
234 // <di value="0"/>
235 // </presentationSettingsEntry>
236 // <presentationSettingsEntry>
237 // ...
238 // </presentationSettingsEntry>
239 // ...
240 // </presentationSettings>
241 /* QDomElement presentationSettings = m_doc.createElement("presentationSettings");
242 m_root.appendChild(presentationSettings);
243 QList<PDFPresentationData>::iterator it;
244 for (it = m_opts->PresentVals.begin(); it != m_opts->PresentVals.end(); ++it)
245 {
246 // Settings entry has no attributes, only children
247 QDomElement psEntry = m_doc.createElement("presentationSettingsEntry");
248 presentationSettings.appendChild(psEntry);
249 // Children:
250 addElem(psEntry, "pageEffectDuration", (*it).pageEffectDuration);
251 addElem(psEntry, "pageViewDuration", (*it).pageViewDuration);
252 addElem(psEntry, "effectType", (*it).effectType);
253 addElem(psEntry, "dm", (*it).Dm);
254 addElem(psEntry, "m", (*it).M);
255 addElem(psEntry, "di", (*it).Di);
256 }*/
257 }
258
259 // Save PDFOptions::LPISettings
addLPISettings()260 void PDFOptionsIO::addLPISettings()
261 {
262 // PDFOptions::LPISettings is a QMap<QString,LPIData>
263 //
264 // XML structure will be like this:
265 // <lpiSettings>
266 // <lpiSettingsEntry name="blah">
267 // <frequency value="0">
268 // <angle value="0">
269 // <spotFunc value="0">
270 // </lpiSettingsEntry>
271 // <lpiSettingsEntry name="blah2">
272 // ...
273 // </lpiSettingsEntry>
274 // ...
275 // </lpiSettings>
276 QDomElement lpiSettings = m_doc.createElement("lpiSettings");
277 m_root.appendChild(lpiSettings);
278 QMap<QString,LPIData>::iterator it;
279 for (it = m_opts->LPISettings.begin(); it != m_opts->LPISettings.end(); ++it)
280 {
281 // Settings entry has no attributes, only children
282 QDomElement lpiEntry = m_doc.createElement("lpiSettingsEntry");
283 lpiEntry.setAttribute("name", it.key());
284 lpiSettings.appendChild(lpiEntry);
285 // Children:
286 addElem(lpiEntry, "frequency", (*it).Frequency);
287 addElem(lpiEntry, "angle", (*it).Angle);
288 addElem(lpiEntry, "spotFunc", (*it).SpotFunc);
289 }
290
291 }
292
293 // overload of bool readFrom(QTextStream& inStream)
readFrom(const QString & inFileName)294 bool PDFOptionsIO::readFrom(const QString& inFileName)
295 {
296 QFile f(inFileName);
297 if (!f.open(QIODevice::ReadOnly))
298 {
299 m_error = QObject::tr("Could not open input file %1")
300 .arg(qApp->translate("QFile",f.errorString().toLatin1().constData()));
301 return false;
302 }
303 return readFrom(f);
304 }
305
readFrom(QIODevice & inDevice)306 bool PDFOptionsIO::readFrom(QIODevice& inDevice)
307 {
308 if (!inDevice.isReadable())
309 return false;
310 QString domError;
311 int errorLine, errorColumn;
312 if (!m_doc.setContent(&inDevice, &domError, &errorLine, &errorColumn))
313 {
314 m_error = QObject::tr("Unable to read settings XML: %1")
315 .arg(QObject::tr("%1 (line %2 col %3)", "Load PDF settings")
316 .arg(domError).arg(errorLine).arg(errorColumn)
317 );
318 return false;
319 }
320 if (!readSettings())
321 // m_error should already be set
322 return false;
323 m_error.clear();
324 return true;
325 }
326
327 // Helper for readFrom(...) to read settings from the DOM
readSettings()328 bool PDFOptionsIO::readSettings()
329 {
330 // Get the root element
331 m_root = m_doc.documentElement();
332 if (m_root.isNull())
333 {
334 m_error = QObject::tr("Unable to read settings XML: %1")
335 .arg(QObject::tr("null root node", "Load PDF settings"));
336 }
337 // and start processing elements
338 if (!readElem(m_root, "firstUse", &m_opts->firstUse))
339 return false;
340 if (!readElem(m_root, "thumbnails", &m_opts->Thumbnails))
341 return false;
342 if (!readElem(m_root, "articles", &m_opts->Articles))
343 return false;
344 if (!readElem(m_root, "useLayers", &m_opts->useLayers))
345 return false;
346 if (!readElem(m_root, "compress", &m_opts->Compress))
347 return false;
348 if (!readElem(m_root, "compressMethod", (int*) &m_opts->CompressMethod))
349 return false;
350 if (!readElem(m_root, "quality", &m_opts->Quality))
351 return false;
352 if (!readElem(m_root, "recalcPic", &m_opts->RecalcPic))
353 return false;
354 if (!readElem(m_root, "bookmarks", &m_opts->Bookmarks))
355 return false;
356 if (!readElem(m_root, "picRes", &m_opts->PicRes))
357 return false;
358 if (!readElem(m_root, "embedPDF", &m_opts->embedPDF))
359 m_opts->embedPDF = false;
360 if (!readPDFVersion())
361 return false;
362 if (!readElem(m_root, "resolution", &m_opts->Resolution))
363 return false;
364 if (!readElem(m_root, "binding", &m_opts->Binding))
365 return false;
366 if (!readPDFFontEmbeddingMode())
367 return false;
368 if (!readList(m_root, "embedFonts", &m_opts->EmbedList))
369 return false;
370 if (!readList(m_root, "subsetFonts", &m_opts->SubsetList))
371 return false;
372 if (!readElem(m_root, "mirrorH", &m_opts->MirrorH))
373 return false;
374 if (!readElem(m_root, "mirrorV", &m_opts->MirrorV))
375 return false;
376 if (!readElem(m_root, "rotateDegrees", &m_opts->RotateDeg))
377 return false;
378 if (!readElem(m_root, "presentMode", &m_opts->PresentMode))
379 return false;
380 // if (!readPresentationData())
381 // return false;
382 if (!readElem(m_root, "filename", &m_opts->fileName))
383 return false;
384 if (!readElem(m_root, "isGrayscale", &m_opts->isGrayscale))
385 return false;
386 if (!readElem(m_root, "useRGB", &m_opts->UseRGB))
387 return false;
388 if (!readElem(m_root, "useProfiles", &m_opts->UseProfiles))
389 return false;
390 if (!readElem(m_root, "useProfiles2", &m_opts->UseProfiles2))
391 return false;
392 if (!readElem(m_root, "useLPI", &m_opts->UseLPI))
393 return false;
394 if (!readElem(m_root, "useSpotColors", &m_opts->UseSpotColors))
395 return false;
396 if (!readElem(m_root, "doMultiFile", &m_opts->doMultiFile))
397 return false;
398 if (!readLPISettings())
399 return false;
400 if (!readElem(m_root, "solidProf", &m_opts->SolidProf))
401 return false;
402 if (!readElem(m_root, "sComp", &m_opts->SComp))
403 return false;
404 if (!readElem(m_root, "imageProf", &m_opts->ImageProf))
405 return false;
406 if (!readElem(m_root, "embeddedI", &m_opts->EmbeddedI))
407 return false;
408 if (!readElem(m_root, "intent2", &m_opts->Intent2))
409 return false;
410 if (!readElem(m_root, "printProf", &m_opts->PrintProf))
411 return false;
412 if (!readElem(m_root, "info", &m_opts->Info))
413 return false;
414 if (!readElem(m_root, "intent", &m_opts->Intent))
415 return false;
416 double d=0.0;
417 if (!readElem(m_root, "bleedTop", &d))
418 return false;
419 m_opts->bleeds.setTop(d);
420 d=0.0;
421 if (!readElem(m_root, "bleedLeft", &d))
422 return false;
423 m_opts->bleeds.setLeft(d);
424 d=0.0;
425 if (!readElem(m_root, "bleedBottom", &d))
426 return false;
427 m_opts->bleeds.setBottom(d);
428 d=0.0;
429 if (!readElem(m_root, "bleedRight", &d))
430 return false;
431 m_opts->bleeds.setRight(d);
432 if (!readElem(m_root, "encrypt", &m_opts->Encrypt))
433 return false;
434 if (!readElem(m_root, "passOwner", &m_opts->PassOwner))
435 return false;
436 if (!readElem(m_root, "passUser", &m_opts->PassUser))
437 return false;
438 if (!readElem(m_root, "permissions", &m_opts->Permissions))
439 return false;
440 return true;
441 }
442
readPDFVersion()443 bool PDFOptionsIO::readPDFVersion()
444 {
445 QString pdfVersString;
446 if (!readElem(m_root, "pdfVersion", &pdfVersString))
447 return false;
448 if (pdfVersString == "X1a")
449 {
450 m_opts->Version = PDFVersion::PDF_X1a;
451 return true;
452 }
453 if (pdfVersString == "X3")
454 {
455 m_opts->Version = PDFVersion::PDF_X3;
456 return true;
457 }
458 if (pdfVersString == "X4")
459 {
460 m_opts->Version = PDFVersion::PDF_X4;
461 return true;
462 }
463 if (pdfVersString == "13")
464 {
465 m_opts->Version = PDFVersion::PDF_13;
466 return true;
467 }
468 if (pdfVersString == "14")
469 {
470 m_opts->Version = PDFVersion::PDF_14;
471 return true;
472 }
473 if (pdfVersString == "15")
474 {
475 m_opts->Version = PDFVersion::PDF_15;
476 return true;
477 }
478 if (pdfVersString == "16")
479 {
480 m_opts->Version = PDFVersion::PDF_16;
481 return true;
482 }
483 m_error = QObject::tr("Unable to read settings XML: %1").arg(QObject::tr("<pdfVersion> invalid", "Load PDF settings"));
484 return false;
485 }
486
readPDFFontEmbeddingMode()487 bool PDFOptionsIO::readPDFFontEmbeddingMode()
488 {
489 QString embeddingMode;
490 if (!readElem(m_root, "fontEmbedding", &embeddingMode))
491 return false;
492
493 if (embeddingMode == "EmbedFonts")
494 {
495 m_opts->FontEmbedding = PDFOptions::EmbedFonts;
496 return true;
497 }
498 if (embeddingMode == "OutlineFonts")
499 {
500 m_opts->FontEmbedding = PDFOptions::OutlineFonts;
501 return true;
502 }
503 if (embeddingMode == "DontEmbed")
504 {
505 m_opts->FontEmbedding = PDFOptions::DontEmbed;
506 return true;
507 }
508
509 m_opts->FontEmbedding = PDFOptions::EmbedFonts;
510 m_error = QObject::tr("Unable to read settings XML: %1")
511 .arg(QObject::tr("<fontEmbedding> invalid", "Load PDF settings"));
512 return false;
513 }
514
515 // returns a null node on failure
getUniqueNode(QDomElement & parent,const QString & name)516 QDomNode PDFOptionsIO::getUniqueNode(QDomElement& parent, const QString& name)
517 {
518 QDomNodeList nodes = parent.elementsByTagName(name);
519 if (nodes.count() != 1)
520 {
521 m_error = QObject::tr("Unable to read settings XML: %1")
522 .arg(QObject::tr("found %1 <%2> nodes, need 1.", "Load PDF settings")
523 .arg(nodes.count()).arg(name)
524 );
525 return QDomNode();
526 }
527 return nodes.item(0);
528 }
529
530 // Return the node as a QDomElement iff it is a QDomElement with
531 // a `value' attribute; otherwise return a null element.
getValueElement(QDomNode & node,const QString & name,bool isValue)532 QDomElement PDFOptionsIO::getValueElement(QDomNode& node, const QString& name, bool isValue)
533 {
534 if (node.isNull())
535 {
536 m_error = QObject::tr("Unable to read settings XML: %1")
537 .arg(QObject::tr("unexpected null <%1> node", "Load PDF settings")
538 .arg(name)
539 );
540 return QDomNode().toElement();
541 }
542 if (!node.isElement())
543 {
544 m_error = QObject::tr("Unable to read settings XML: %1")
545 .arg(QObject::tr("node <%1> not an element", "Load PDF settings")
546 .arg(name)
547 );
548 return QDomNode().toElement();
549 }
550 QDomElement elem = node.toElement();
551 if (elem.tagName() != name)
552 {
553 m_error = QObject::tr("Unable to read settings XML: %1")
554 .arg(QString("Internal error: element named <%1> not expected <%2>")
555 .arg(elem.tagName(), name)
556 );
557 return QDomNode().toElement();
558 }
559 if (isValue)
560 {
561 // We need to check that it has a `value' attribute
562 if (!elem.hasAttribute("value"))
563 {
564 m_error = QObject::tr("Unable to read settings XML: %1")
565 .arg(QObject::tr("element <%1> lacks `value' attribute", "Load PDF settings")
566 .arg(name)
567 );
568 return QDomNode().toElement();
569 }
570 }
571 return elem;
572 }
573
readElem(QDomElement & parent,const QString & name,bool * value)574 bool PDFOptionsIO::readElem(QDomElement& parent, const QString& name, bool* value)
575 {
576 QDomNode node = getUniqueNode(parent, name);
577 QDomElement elem = getValueElement(node, name);
578 if (elem.isNull())
579 return false;
580 QString elementText = elem.attribute("value");
581 if (elementText == "true")
582 {
583 (*value) = true;
584 return true;
585 }
586 if (elementText == "false")
587 {
588 (*value) = false;
589 return true;
590 }
591 m_error = QObject::tr("Unable to read settings XML: %1").arg(QObject::tr("element <%1> value must be `true' or `false'", "Load PDF settings").arg(name));
592 return false;
593 }
594
readElem(QDomElement & parent,const QString & name,int * value)595 bool PDFOptionsIO::readElem(QDomElement& parent, const QString& name, int* value)
596 {
597 QDomNode node = getUniqueNode(parent, name);
598 QDomElement elem = getValueElement(node, name);
599 if (elem.isNull())
600 return false;
601 bool ok = false;
602 int result = elem.attribute("value").toInt(&ok);
603 if (ok)
604 (*value) = result;
605 else
606 {
607 m_error = QObject::tr("Unable to read settings XML: %1").arg(QObject::tr("element <%1> value must be an integer", "Load PDF settings").arg(name));
608 return false;
609 }
610 return ok;
611 }
612
readElem(QDomElement & parent,const QString & name,double * value)613 bool PDFOptionsIO::readElem(QDomElement& parent, const QString& name, double* value)
614 {
615 QDomNode node = getUniqueNode(parent, name);
616 QDomElement elem = getValueElement(node, name);
617 if (elem.isNull())
618 return false;
619 bool ok = false;
620 double result = ScCLocale::toDoubleC(elem.attribute("value"), &ok);
621 if (ok)
622 (*value) = result;
623 else
624 {
625 m_error = QObject::tr("Unable to read settings XML: %1").arg(QObject::tr("element <%1> value must be a double", "Load PDF settings").arg(name));
626 return false;
627 }
628 return ok;
629 }
630
readElem(QDomElement & parent,const QString & name,QString * value)631 bool PDFOptionsIO::readElem(QDomElement& parent, const QString& name, QString* value)
632 {
633 QDomNode node = getUniqueNode(parent, name);
634 QDomElement elem = getValueElement(node, name);
635 if (elem.isNull())
636 return false;
637 QString result = elem.attribute("value");
638 bool ok = !result.isNull();
639 if (ok)
640 (*value) = result;
641 return ok;
642 }
643
644 // Read a stringlist saved as a list of child <item value=""> elements
readList(QDomElement & parent,const QString & name,QList<QString> * value)645 bool PDFOptionsIO::readList(QDomElement& parent, const QString& name, QList<QString>* value)
646 {
647 QDomNode basenode = getUniqueNode(parent, name);
648 QDomElement listbase = getValueElement(basenode, name, false);
649 if (listbase.isNull())
650 return false;
651 QList<QString> list;
652 for (QDomNode node = listbase.firstChild(); !node.isNull(); node = node.nextSibling())
653 {
654 QDomElement elem = getValueElement(node, "item");
655 if (elem.isNull())
656 return false;
657 list.append(elem.attribute("value"));
658 }
659 (*value) = list;
660 return true;
661 }
662
readPresentationData()663 bool PDFOptionsIO::readPresentationData()
664 {
665 // XML structure will be like this:
666 // <presentationSettings>
667 // <presentationSettingsEntry>
668 // <pageEffectDuration value="0"/>
669 // <pageViewDuration value="0"/>
670 // <effectType value="0"/>
671 // <dm value="0"/>
672 // <m value="0"/>
673 // <di value="0"/>
674 // </presentationSettingsEntry>
675 // <presentationSettingsEntry>
676 // ...
677 // </presentationSettingsEntry>
678 // ...
679 // </presentationSettings>
680 QDomNode basenode = getUniqueNode(m_root, "presentationSettings");
681 QDomElement pSettings = getValueElement(basenode, "presentationSettings", false);
682 if (pSettings.isNull())
683 return false;
684 QList<PDFPresentationData> pList;
685 for (QDomNode node = pSettings.firstChild(); !node.isNull(); node = node.nextSibling())
686 {
687 QDomElement elem = getValueElement(node, "presentationSettingsEntry", false);
688 if (elem.isNull())
689 return false;
690 PDFPresentationData pres;
691 if (!readElem(elem, "pageEffectDuration", &pres.pageEffectDuration))
692 return false;
693 if (!readElem(elem, "pageViewDuration", &pres.pageViewDuration))
694 return false;
695 if (!readElem(elem, "effectType", &pres.effectType))
696 return false;
697 if (!readElem(elem, "dm", &pres.Dm))
698 return false;
699 if (!readElem(elem, "m", &pres.M))
700 return false;
701 if (!readElem(elem, "di", &pres.Di))
702 return false;
703 pList.append(pres);
704 }
705 return true;
706 }
707
readLPISettings()708 bool PDFOptionsIO::readLPISettings()
709 {
710 // XML structure will be like this:
711 // <lpiSettings>
712 // <lpiSettingsEntry name="blah">
713 // <frequency value="0">
714 // <angle value="0">
715 // <spotFunc value="0">
716 // </lpiSettingsEntry>
717 // <lpiSettingsEntry name="blah2">
718 // ...
719 // </lpiSettingsEntry>
720 // ...
721 // </lpiSettings>
722 QDomNode basenode = getUniqueNode(m_root, "lpiSettings");
723 QDomElement lpiSettings = getValueElement(basenode, "lpiSettings", false);
724 if (lpiSettings.isNull())
725 return false;
726 QMap<QString,LPIData> lpiMap;
727 for (QDomNode node = lpiSettings.firstChild(); !node.isNull(); node = node.nextSibling())
728 {
729 QDomElement elem = getValueElement(node, "lpiSettingsEntry", false);
730 if (elem.isNull())
731 return false;
732 QString name (elem.attribute("name"));
733 if (name.isNull())
734 {
735 m_error = QObject::tr("Unable to read settings XML: %1")
736 .arg(QObject::tr("element <lpiSettingsEntry> lacks `name' attribute", "Load PDF settings")
737 .arg(name)
738 );
739 return false;
740 }
741 LPIData lpi;
742 if (!readElem(elem, "frequency", &lpi.Frequency))
743 return false;
744 if (!readElem(elem, "angle", &lpi.Angle))
745 return false;
746 if (!readElem(elem, "spotFunc", &lpi.SpotFunc))
747 return false;
748 lpiMap[name] = lpi;
749 }
750 return true;
751 }
752
lastError() const753 const QString& PDFOptionsIO::lastError() const
754 {
755 return m_error;
756 }
757