1 /***************************************************************************
2 * This file is part of KWorship. *
3 * Copyright 2008 James Hogan <james@albanarts.com> *
5 * KWorship is free software: you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation, either version 2 of the License, or *
8 * (at your option) any later version. *
10 * KWorship is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with KWorship. If not, write to the Free Software Foundation, *
17 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
18 ***************************************************************************/
21 * @file KwZionworxFilter.cpp
22 * @brief Main Zionworx load and save filter.
23 * @author James Hogan <james@albanarts.com>
26 #include "KwZionworxFilter.h"
27 #include "KwPascalStream.h"
28 #include <KwDocument.h>
29 #include <KwArchive.h>
30 #include <KwPlaylistList.h>
31 #include <KwPlaylistText.h>
32 #include <KwPlaylistSong.h>
33 #include <KwBiblePlaylistItem.h>
34 #include <KwPlaylistPresentation.h>
35 #include <KwCssStyleRule.h>
36 #include <KwDisplayStyles.h>
41 #include <KMessageBox>
46 #include <QDomDocument>
47 #include <QDomElement>
53 * Constructors + destructor
56 /// Primary constructor.
57 KwZionworxFilter::KwZionworxFilter()
60 m_importMimeTypes
+= "application/x-zionworx+xml";
61 m_exportMimeTypes
+= "application/x-zionworx+xml";
65 KwZionworxFilter::~KwZionworxFilter()
73 KwDocument
* KwZionworxFilter::load(const KUrl
& url
, const QString
& mimeType
)
75 /// @todo Handle non-local files
76 if (!url
.isLocalFile())
79 i18n("Non-local loads not yet supported"),
86 if (mimeType
== "application/x-zionworx+xml")
88 QFile
file(url
.toLocalFile());
89 if (file
.open(QIODevice::ReadOnly
))
92 if (domDoc
.setContent(&file
))
94 QDomElement root
= domDoc
.documentElement();
95 QDomElement versionEl
= root
.firstChildElement("ZionWorx");
96 if (root
.tagName() != "Root" || versionEl
.isNull())
99 i18n("Doesn't look like a ZionWorx playlist"),
104 bool versionOk
= false;
105 double version
= versionEl
.attribute("Version").toDouble(&versionOk
);
106 if (!versionOk
|| version
!= 2.6)
108 KMessageBox::error(0,
109 i18n("Only version 2.6 is supported (version is %1)").arg(versionEl
.attribute("Version", "unspecified")),
114 doc
= new KwDocument(this, mimeType
, url
);
115 KwPlaylistList
* list
= new KwPlaylistList();
116 doc
->setPlaylist(list
);
118 QDomNodeList playlistNodes
= root
.elementsByTagName("TPlayListNode");
119 for (int i
= 0; i
< playlistNodes
.count(); ++i
)
121 QDomElement playlistNode
= playlistNodes
.at(i
).toElement();
122 QDomElement item
= playlistNode
.firstChildElement("PlayListItem");
125 KwPlaylistItem
* newItem
= 0;
126 QString biDiText
= item
.firstChildElement("BiDiMode").text();
127 bool rightToLeft
= (biDiText
== "bdRightToLeft");
128 QString itemType
= item
.firstChildElement("ItemType").text();
129 if (itemType
== "siPowerPoint")
131 KwPlaylistPresentation
* powerpoint
= new KwPlaylistPresentation(QUrl(item
.firstChildElement("FilenameRelative").text()));
132 powerpoint
->setTitle(item
.firstChildElement("Title").text());
133 newItem
= powerpoint
;
135 else if (itemType
== "siSong")
137 KwPlaylistText
* song
= new KwPlaylistText(item
.firstChildElement("Title").text(),
138 item
.firstChildElement("Lyrics").text().split("\n\n"));
141 else if (itemType
== "siQuickNote")
143 KwPlaylistText
* note
= new KwPlaylistText(item
.firstChildElement("Title").text(),
144 readStringList(item
.firstChildElement("QuickNote")));
147 else if (itemType
== "siBible")
150 QStringList verses
= readStringList(item
.firstChildElement("Verses"));
151 // Try and understand the passage referred to on the first line.
152 static QRegExp
rePassage("^(.*)\\s+(\\d+)(:(\\d+)(-(\\d+))?)?\\s+\\(([^\\)]*)\\).*");
153 if (verses
.size() >= 1 && rePassage
.exactMatch(verses
[0]))
156 QString bookName
= rePassage
.cap(1);
157 QString moduleName
= rePassage
.cap(7);
158 /// @todo Try and get a more accurate set of book ids
160 int chapterNum
= rePassage
.cap(2).toInt();
162 int firstVerse
= rePassage
.cap(4).toInt(&validVerse
);
167 int nextVerse
= firstVerse
;
168 QStringList verseHeadings
;
169 QStringList verseContents
;
170 QStringList tempHeadings
;
171 for (int i
= 1; i
< verses
.size(); ++i
)
173 const QString
& verse
= verses
[i
];
174 // See if it starts with a number, otherwise its a heading
175 static QRegExp
reVerseLine("^(\\d+)\\.\\s*(\\S.*)$");
176 if (reVerseLine
.exactMatch(verse
))
178 int verseNum
= reVerseLine
.cap(1).toInt();
179 if (verseNum
!= nextVerse
)
185 if (!tempHeadings
.isEmpty())
187 verseHeadings
+= QString("<h4>%1</h4>").arg(tempHeadings
.join("<br />\n"));
191 verseHeadings
+= QString();
193 verseContents
+= reVerseLine
.cap(2);
194 tempHeadings
= QStringList();
198 tempHeadings
+= verse
;
203 KMessageBox::error(0,
204 i18n("Problems were encountered reading numbered verses in bible passage %1").arg(item
.firstChildElement("Title").text()),
209 KwBiblePlaylistItem
* bible
= new KwBiblePlaylistItem();
210 KwBiblePassage
& passage
= bible
->passage();
211 passage
.setSource(QString(), moduleName
, rightToLeft
);
212 passage
.initBooks(bookNum
,1);
213 passage
.initBook(bookNum
, bookName
, chapterNum
, 1);
214 passage
.initChapter(bookNum
, chapterNum
, firstVerse
, verseContents
.size());
215 for (int i
= 0; i
< verseContents
.size(); ++i
)
217 passage
.initVerse(bookNum
, chapterNum
, firstVerse
+i
, verseHeadings
[i
], verseContents
[i
]);
224 KwPlaylistText
* bible
= new KwPlaylistText(item
.firstChildElement("Title").text(),
232 QDomElement overlayStyleEl
= playlistNode
.firstChildElement("OverlayStyle");
233 if (!overlayStyleEl
.isNull())
235 KwCssStyleSheet
* styleRules
= new KwCssStyleSheet
;
236 KwCssStyleRule overlayStyle
;
239 QDomElement fontEl
= overlayStyleEl
.firstChildElement("Font");
240 if (!fontEl
.isNull())
243 QDomElement fontHeightEl
= fontEl
.firstChildElement("Height");
244 if (!fontHeightEl
.isNull())
247 int height
= fontHeightEl
.text().toInt(&ok
);
250 font
.setPointSize(abs(height
));
253 QDomElement fontNameEl
= fontEl
.firstChildElement("Name");
254 /// @todo Remember font name
255 /// @todo Use font names
256 QDomElement fontStyleEl
= fontEl
.firstChildElement("Style");
257 if (!fontStyleEl
.isNull())
259 static QRegExp
reFontStyleList("^\\s*\\[(.*)\\]\\s*$");
260 if (reFontStyleList
.exactMatch(fontStyleEl
.text()))
262 QStringList styles
= reFontStyleList
.cap(1).split(",");
263 foreach (QString style
, styles
)
265 style
= style
.trimmed();
266 if (style
== "fsBold")
268 font
.setWeight(QFont::Bold
);
270 else if (style
== "fsItalic")
272 font
.setStyle(QFont::StyleItalic
);
278 overlayStyle
.setStyle
<QFont
>("text.character.font", font
);
280 QDomElement fontColorEl
= fontEl
.firstChildElement("Color");
281 if (!fontColorEl
.isNull())
284 QColor colour
= readColour(fontColorEl
, &ok
);
287 overlayStyle
.setStyle
<QBrush
>("text.character.brush", QBrush(colour
));
291 QDomElement textStyleEl
= overlayStyleEl
.firstChildElement("TextStyle");
292 if (!textStyleEl
.isNull())
294 QString style
= textStyleEl
.text();
295 if (style
== "tsShadow")
297 overlayStyle
.setStyle
<bool>("text.character.shadow.enabled", true);
299 else if (style
== "tsOutline")
301 overlayStyle
.setStyle
<bool>("text.character.outline.enabled", true);
304 QDomElement textAlignmentEl
= overlayStyleEl
.firstChildElement("TextAlignment");
307 QDomElement shadowWidthEl
= overlayStyleEl
.firstChildElement("ShadowWidth");
308 if (!shadowWidthEl
.isNull())
311 int offset
= shadowWidthEl
.text().toInt(&ok
);
314 overlayStyle
.setStyle
<int>("text.character.shadow.offset", offset
);
317 QDomElement shadowColorEl
= overlayStyleEl
.firstChildElement("ShadowColor");
318 if (!shadowColorEl
.isNull())
321 QColor colour
= readColour(shadowColorEl
, &ok
);
324 overlayStyle
.setStyle
<QBrush
>("text.character.shadow.brush", QBrush(colour
));
329 QDomElement outlineWidthEl
= overlayStyleEl
.firstChildElement("OutlineWidth");
330 int outlineWidth
= 1;
331 if (!outlineWidthEl
.isNull())
334 int width
= outlineWidthEl
.text().toInt(&ok
);
337 outlineWidth
= width
;
340 QDomElement outlineColorEl
= overlayStyleEl
.firstChildElement("OutlineColor");
341 QColor outlineColour
= Qt::black
;
342 if (!outlineColorEl
.isNull())
345 QColor colour
= readColour(outlineColorEl
, &ok
);
348 outlineColour
= colour
;
351 overlayStyle
.setStyle
<QPen
>("text.character.outline.pen", QPen(outlineColour
, outlineWidth
));
353 QDomElement fillColorEl
= overlayStyleEl
.firstChildElement("FillColor");
354 if (!fillColorEl
.isNull())
357 QColor colour
= readColour(fillColorEl
, &ok
);
360 overlayStyle
.setStyle
<QBrush
>("background.brush", QBrush(colour
));
363 QDomElement imageFilenameEl
= overlayStyleEl
.firstChildElement("ImageFilename");
364 //overlayStyle.setStyle<KwResourceLink>("background.image.src", KUrl("file:///home/james/media/images/projector/misc/bible.jpg"));
365 QDomElement imageAlignmentEl
= overlayStyleEl
.firstChildElement("ImageAlignment");
368 QDomElement marginRightEl
= overlayStyleEl
.firstChildElement("MarginRight");
369 if (!marginRightEl
.isNull())
372 float margin
= marginRightEl
.text().toFloat(&ok
);
375 overlayStyle
.setStyle
<float>("text.layout.margins.right", margin
);
378 QDomElement marginLeftEl
= overlayStyleEl
.firstChildElement("MarginLeft");
379 if (!marginLeftEl
.isNull())
382 float margin
= marginLeftEl
.text().toFloat(&ok
);
385 overlayStyle
.setStyle
<float>("text.layout.margins.left", margin
);
388 QDomElement marginTopEl
= overlayStyleEl
.firstChildElement("MarginTop");
389 if (!marginTopEl
.isNull())
392 float margin
= marginTopEl
.text().toFloat(&ok
);
395 overlayStyle
.setStyle
<float>("text.layout.margins.top", margin
);
398 QDomElement marginBottomEl
= overlayStyleEl
.firstChildElement("MarginBottom");
399 if (!marginBottomEl
.isNull())
402 float margin
= marginBottomEl
.text().toFloat(&ok
);
405 overlayStyle
.setStyle
<float>("text.layout.margins.bottom", margin
);
409 styleRules
->addRule(overlayStyle
);
410 newItem
->addStyleSheet(styleRules
);
413 list
->addItem(newItem
);
417 KMessageBox::error(0,
418 i18n("Unrecognised item type \"%1\"").arg(itemType
),
424 doc
->setModified(false);
430 KMessageBox::error(0,
438 Q_ASSERT(!"Unsupported mime type");
444 /// Contains implementations of export functions.
445 class KwZionworxFilter::ExportToDom
449 /// Write a colour to a string.
450 static QString
writeColour(const QColor
& colour
, bool wierd
)
452 /// @todo Use symbolic colours when possible
455 return QString::number((int32_t)((colour
.red() << 16) | (colour
.green() << 8) | colour
.blue() | 0xFF000000));
459 return QString::number((int32_t)(colour
.red() | (colour
.green() << 8) | (colour
.blue() << 16)));
462 static QDomElement
createPlaylistNode(QDomDocument
& document
, QDomElement
& element
)
464 QDomElement node
= document
.createElement("TPlayListNode");
465 element
.appendChild(node
);
468 static QDomElement
createOverlayStyle(QDomDocument
& document
, QDomElement
& element
, const KwPlaylistItem
* item
)
470 QDomElement style
= document
.createElement("OverlayStyle");
472 style
.appendChild(document
.createTextNode("(TOverlayStyle)"));
474 QDomElement fontEl
= document
.createElement("Font");
476 fontEl
.appendChild(document
.createTextNode("(TFont)"));
478 QFont font
= KwDisplayStyles::text::character::font(item
);
479 QStringList textStyles
;
482 textStyles
+= "fsItalic";
486 textStyles
+= "fsBold";
489 /// @todo find out what this element does, restore from saved
490 QDomElement charsetEl
= document
.createElement("Charset");
491 charsetEl
.appendChild(document
.createTextNode("ANSI_CHARSET"));
492 fontEl
.appendChild(charsetEl
);
494 QDomElement colorEl
= document
.createElement("Color");
495 colorEl
.appendChild(document
.createTextNode(writeColour(KwDisplayStyles::text::character::brush(item
).color(), false)));
496 fontEl
.appendChild(colorEl
);
498 /// @todo Handle if font is specified in pixels
499 QDomElement heightEl
= document
.createElement("Height");
500 heightEl
.appendChild(document
.createTextNode(QString::number(-font
.pointSize())));
501 fontEl
.appendChild(heightEl
);
503 /// @todo Get a sensible font name here
504 QDomElement nameEl
= document
.createElement("Name");
505 nameEl
.appendChild(document
.createTextNode("Tahoma"));
506 fontEl
.appendChild(nameEl
);
508 QDomElement StyleEl
= document
.createElement("Style");
509 StyleEl
.appendChild(document
.createTextNode(QString("[%1]").arg(textStyles
.join(","))));
510 fontEl
.appendChild(StyleEl
);
512 style
.appendChild(fontEl
);
514 bool outline
= KwDisplayStyles::text::character::outline::enabled(item
);
515 bool shadow
= KwDisplayStyles::text::character::shadow::enabled(item
);
516 QDomElement textStyleEl
= document
.createElement("TextStyle");
517 textStyleEl
.appendChild(document
.createTextNode(outline
? "tsOutline" : shadow
? "tsShadow" : "tsPlain"));
518 style
.appendChild(textStyleEl
);
520 /// @todo Implement text alignment saving
521 QDomElement textAlignmentEl
= document
.createElement("TextAlignment");
522 textAlignmentEl
.appendChild(document
.createTextNode("taLeft"));
523 style
.appendChild(textAlignmentEl
);
525 QDomElement shadowWidthEl
= document
.createElement("ShadowWidth");
526 shadowWidthEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::character::shadow::offset(item
))));
527 style
.appendChild(shadowWidthEl
);
529 QDomElement shadowColorEl
= document
.createElement("ShadowColor");
530 shadowColorEl
.appendChild(document
.createTextNode(writeColour(KwDisplayStyles::text::character::shadow::brush(item
).color(), true)));
531 style
.appendChild(shadowColorEl
);
533 QDomElement outlineWidthEl
= document
.createElement("OutlineWidth");
534 outlineWidthEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::character::outline::pen(item
).width())));
535 style
.appendChild(outlineWidthEl
);
537 QDomElement outlineColorEl
= document
.createElement("OutlineColor");
538 outlineColorEl
.appendChild(document
.createTextNode(writeColour(KwDisplayStyles::text::character::outline::pen(item
).color(), true)));
539 style
.appendChild(outlineColorEl
);
541 QDomElement fillColorEl
= document
.createElement("FillColor");
542 fillColorEl
.appendChild(document
.createTextNode(writeColour(KwDisplayStyles::background::brush(item
).color(), false)));
543 style
.appendChild(fillColorEl
);
545 /// @todo Implement image filename saving
548 QDomElement imageFilenameEl
= document
.createElement("ImageFilename");
549 imageFilenameEl
.appendChild(document
.createTextNode(""));
550 style
.appendChild(imageFilenameEl
);
553 /// @todo Implement image alignment saving
554 QDomElement imageAlignmentEl
= document
.createElement("ImageAlignment");
555 imageAlignmentEl
.appendChild(document
.createTextNode("iaStretch"));
556 style
.appendChild(imageAlignmentEl
);
558 QDomElement marginRightEl
= document
.createElement("MarginRight");
559 marginRightEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::layout::margins::right(item
))));
560 style
.appendChild(marginRightEl
);
562 QDomElement marginLeftEl
= document
.createElement("MarginLeft");
563 marginLeftEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::layout::margins::left(item
))));
564 style
.appendChild(marginLeftEl
);
566 QDomElement marginTopEl
= document
.createElement("MarginTop");
567 marginTopEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::layout::margins::top(item
))));
568 style
.appendChild(marginTopEl
);
570 QDomElement marginBottomEl
= document
.createElement("MarginBottom");
571 marginBottomEl
.appendChild(document
.createTextNode(QString::number(KwDisplayStyles::text::layout::margins::bottom(item
))));
572 style
.appendChild(marginBottomEl
);
574 element
.appendChild(style
);
577 static QDomElement
createPlaylistItem(QDomDocument
& document
, QDomElement
& element
,
578 const QString
& type
, const QString
& title
, bool rightToLeft
)
580 QDomElement item
= document
.createElement("PlayListItem");
582 QDomElement typeEl
= document
.createElement("ItemType");
583 typeEl
.appendChild(document
.createTextNode(type
));
584 item
.appendChild(typeEl
);
587 QDomElement titleEl
= document
.createElement("Title");
588 titleEl
.appendChild(document
.createTextNode(title
));
589 item
.appendChild(titleEl
);
592 QDomElement biDiEl
= document
.createElement("BiDiMode");
593 biDiEl
.appendChild(document
.createTextNode(rightToLeft
? "bdRightToLeft" : "bdLeftToRight"));
594 item
.appendChild(biDiEl
);
596 element
.appendChild(item
);
599 static int list(const KwPlaylistList
* self
, QDomDocument
& document
, QDomElement
& element
)
601 for (int i
= 0; i
< self
->getItemCount(); ++i
)
603 call(self
->getItem(i
), document
, element
);
607 static int song(const KwPlaylistSong
* self
, QDomDocument
& document
, QDomElement
& element
)
609 QDomElement node
= createPlaylistNode(document
, element
);
610 QDomElement style
= createOverlayStyle(document
, node
, self
);
613 static int note(const KwPlaylistText
* self
, QDomDocument
& document
, QDomElement
& element
)
615 QDomElement node
= createPlaylistNode(document
, element
);
616 QDomElement style
= createOverlayStyle(document
, node
, self
);
619 static int bible(const KwBiblePlaylistItem
* self
, QDomDocument
& document
, QDomElement
& element
)
621 QDomElement node
= createPlaylistNode(document
, element
);
622 QDomElement style
= createOverlayStyle(document
, node
, self
);
623 const KwBiblePassage
& passage
= self
->passage();
624 QDomElement item
= createPlaylistItem(document
, node
,
625 "siBible", passage
.textualKey(),
626 passage
.isRightToLeft());
628 QDomElement versesEl
= document
.createElement("Verses");
629 versesEl
.appendChild(document
.createTextNode("(TTntStringList)"));
631 QDomElement definedPropsEl
= document
.createElement("DefinedProperties");
632 QByteArray propsData
;
633 KwPascalStream
data(&propsData
, QIODevice::WriteOnly
);
636 verses
<< passage
.textualKey();
637 for (int book
= passage
.firstBookNumber(); book
<= passage
.lastBookNumber(); ++book
)
639 for (int chap
= passage
.firstChapterNumber(book
); chap
<= passage
.lastChapterNumber(book
); ++chap
)
641 for (int verse
= passage
.firstVerseNumber(book
, chap
); verse
<= passage
.lastVerseNumber(book
, chap
); ++verse
)
643 const QString
& headings
= passage
.verseHeadings(book
, chap
, verse
, true);
644 if (!headings
.isEmpty())
648 const QString
& content
= passage
.verseContent(book
, chap
, verse
, true);
649 if (!content
.isEmpty())
651 verses
+= i18nc("Verse number, bible verse, for zionworx export", "%1. %2").arg(verse
).arg(content
);
656 data
.writeProperty("Strings", verses
);
658 propsData
= propsData
.toBase64();
659 definedPropsEl
.appendChild(document
.createTextNode(propsData
));
660 versesEl
.appendChild(definedPropsEl
);
662 item
.appendChild(versesEl
);
665 static int presentation(const KwPlaylistPresentation
* self
, QDomDocument
& document
, QDomElement
& element
)
667 QDomElement node
= createPlaylistNode(document
, element
);
668 QDomElement item
= createPlaylistItem(document
, node
,
669 "siPowerPoint", self
->title(),
677 static bool done
= false;
680 call
.addImplementation(&list
);
681 call
.addImplementation(&song
);
682 call
.addImplementation(¬e
);
683 call
.addImplementation(&bible
);
684 call
.addImplementation(&presentation
);
689 typedef VTable
<const KwPlaylistItem
, int (*)(QDomDocument
& document
, QDomElement
& element
)> ExportVTable
;
690 static ExportVTable call
;
692 KwZionworxFilter::ExportToDom::ExportVTable
KwZionworxFilter::ExportToDom::call
;
694 bool KwZionworxFilter::save(KwDocument
* doc
, const KUrl
& url
, const QString
& mimeType
)
696 /// @todo Handle non-local files
697 if (!url
.isLocalFile())
699 KMessageBox::error(0,
700 i18n("Non-local loads not yet supported"),
705 file
.setFileName(url
.toLocalFile());
706 if (!file
.open(QFile::WriteOnly
))
708 KMessageBox::error(0,
709 i18n("Cannot write file %1:\n%2.")
710 .arg(file
.fileName())
711 .arg(file
.errorString()),
718 QDomElement root
= domDoc
.createElement("Root");
719 domDoc
.appendChild(root
);
722 QDomElement version
= domDoc
.createElement("ZionWorx");
723 version
.setAttribute("Version", 2.6);
724 version
.setAttribute("FullFilename", url
.toLocalFile());
725 root
.appendChild(version
);
727 // Playlist nodes element
728 QDomElement playlist
= domDoc
.createElement("PlayListNodes");
730 ExportToDom::call(doc
->playlist(), domDoc
, playlist
);
731 root
.appendChild(playlist
);
733 // Write document to file
734 QByteArray xml
= domDoc
.toByteArray(2);
735 file
.write(xml
, xml
.size());
737 if (!file
.finalize())
739 KMessageBox::error(0,
740 i18n("Cannot finalize file %1:\n%2.")
741 .arg(file
.fileName())
742 .arg(file
.errorString()),
747 doc
->setModified(false);
756 void KwZionworxFilter::v_saveLimitations(KwDocument
* doc
, const QString
& mimeType
, Limitations
* o_limitations
)
758 /// @todo Implement KwZionworxFilter::v_saveLimitations
766 /// Read a TTntStringList from DOM.
767 QStringList
KwZionworxFilter::readStringList(const QDomElement
& el
) const
769 // Go straight to the <DefinedProperties>
770 QDomElement definedProperties
= el
.firstChildElement("DefinedProperties");
771 if (!definedProperties
.isNull())
773 const QByteArray buf
= QByteArray::fromBase64(definedProperties
.text().toAscii());
775 KwPascalStream
stream(&buf
);
778 while (!stream
.atEnd())
780 stream
.readProperty(name
, value
);
781 if (name
== "Strings")
783 // Turn into a QStringList
785 foreach (QVariant item
, value
.toList())
787 result
+= item
.toString();
793 return QStringList();
796 /// Read a colour from DOM.
797 QColor
KwZionworxFilter::readColour(const QDomElement
& el
, bool* ok
) const
801 static QHash
<QString
, QColor
> colours
;
802 static bool inited
= false;
805 colours
["clWhite"] = Qt::white
;
806 colours
["clBlack"] = Qt::black
;
807 colours
["clRed"] = Qt::red
;
808 colours
["clDarkRed"] = Qt::darkRed
;
809 colours
["clGreen"] = Qt::green
;
810 colours
["clDarkGreen"] = Qt::darkGreen
;
811 colours
["clBlue"] = Qt::blue
;
812 colours
["clDarkBlue"] = Qt::darkBlue
;
813 colours
["clCyan"] = Qt::cyan
;
814 colours
["clDarkCyan"] = Qt::darkCyan
;
815 colours
["clMagenta"] = Qt::magenta
;
816 colours
["clDarkMagenta"] = Qt::darkMagenta
;
817 colours
["clYellow"] = Qt::yellow
;
818 colours
["clDarkGray"] = Qt::darkYellow
;
819 colours
["clGray"] = Qt::gray
;
820 colours
["clDarkGray"] = Qt::darkGray
;
821 colours
["clLightGray"] = Qt::lightGray
;
825 QString colourName
= el
.text();
827 uint32_t colourNum
= colourName
.toInt(&isOk
);
830 // 0xff in msb apparently changes byte order
831 if (((colourNum
>> 24) & 0xFF) == 0xFF)
833 // least significant byte is blue, followed by green and red
834 result
.setRgb((colourNum
>> 16) & 0xFF,
835 (colourNum
>> 8) & 0xFF,
840 // least significant byte is red, followed by green and blue
841 result
.setRgb( colourNum
& 0xFF,
842 (colourNum
>> 8) & 0xFF,
843 (colourNum
>> 16) & 0xFF);
846 else if (colours
.contains(colourName
))
848 result
= colours
[colourName
];