1 /**
2  * projectM-qt -- Qt4 based projectM GUI
3  * Copyright (C)2003-2004 projectM Team
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library 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 GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  * See 'LICENSE.txt' included within this release
19  *
20  */
21 
22 #ifndef QXML_PLAYLIST_HANDLER_HPP
23 #define QXML_PLAYLIST_HANDLER_HPP
24 #include <QXmlStreamReader>
25 #include <QXmlStreamWriter>
26 
27 class QXmlPlaylistHandler {
28 
29 	public :
30 	template <class ReadFunctor>
31 	static QXmlStreamReader::Error readPlaylist (QIODevice * device, ReadFunctor & readFunc);
32 
33 	template <class WriteFunctor>
34 	static void writePlaylist (QIODevice * device, WriteFunctor & writeFunc);
35 
36 	private:
37 
38 	template <class ReadFunctor>
39 		static QXmlStreamReader::Error readPlaylistItem(QXmlStreamReader & reader, ReadFunctor & functor);
40 
41 
42 };
43 
44 template <class ReadFunctor>
readPlaylist(QIODevice * device,ReadFunctor & readFunc)45 QXmlStreamReader::Error QXmlPlaylistHandler::readPlaylist (QIODevice * device, ReadFunctor & readFunc)
46 {
47 	QXmlStreamReader reader ( device );
48 
49 	QXmlStreamReader::TokenType token;
50 
51 	try {
52 	while ( !reader.atEnd() ) {
53 		token = reader.readNext();
54 	switch ( token )
55 	{
56 		case QXmlStreamReader::StartElement:
57 
58 			if (reader.name() == "presetplaylist") {
59 
60 			}
61 			else if (reader.name() == "description") {
62 				reader.readNext();
63 				readFunc.setPlaylistDesc(reader.text().toString().replace("&amp;", "&"));
64 
65 			}
66 			else if (reader.name() == "item") {
67 				readPlaylistItem<ReadFunctor>(reader, readFunc);
68 				break;
69 			}
70 			break;
71 		case QXmlStreamReader::NoToken:
72 			break;
73 		case QXmlStreamReader::Invalid:
74 			break;
75 		case QXmlStreamReader::StartDocument:
76 			break;
77 		case QXmlStreamReader::EndDocument:
78 			break;
79 		case QXmlStreamReader::EndElement:
80 			break;
81 		case QXmlStreamReader::Characters:
82 		case QXmlStreamReader::Comment:
83 		case QXmlStreamReader::DTD:
84 		case QXmlStreamReader::EntityReference:
85 		case QXmlStreamReader::ProcessingInstruction:
86 		default:
87 			break;
88 	}
89 	}
90 	} catch (const QXmlStreamReader::Error & id) {
91 		return id;
92 
93 	}
94 
95 	if (reader.hasError())
96 		return reader.error();
97 	 else
98 		return QXmlStreamReader::NoError;
99 }
100 
101 
102 template <class ReadFunctor>
readPlaylistItem(QXmlStreamReader & reader,ReadFunctor & readFunctor)103 QXmlStreamReader::Error QXmlPlaylistHandler::readPlaylistItem(QXmlStreamReader & reader, ReadFunctor & readFunctor) {
104 
105 	QString url, name;
106 	int rating = 3;
107 	int breedability = 3;
108 
109 	while (reader.readNext() != QXmlStreamReader::EndElement)
110 		if (reader.name() == "url") {
111 			bool repeat;
112 			int result;
113 
114 			while ((repeat = (result = reader.readNext()) == QXmlStreamReader::Characters))
115 				url += reader.text().toString();
116 
117 		} else if (reader.name() == "rating") {
118 			reader.readNext();
119 			rating = reader.text().toString().toInt();
120 			reader.readNext();
121 		} else if (reader.name() == "breedability") {
122 			reader.readNext();
123 			breedability = reader.text().toString().toInt();
124 			reader.readNext();
125 		} else if (reader.name() == "name") {
126 			bool repeat;
127 			int result;
128 
129 			while ((repeat = (result = reader.readNext()) == QXmlStreamReader::Characters))
130 				name += reader.text().toString();
131 		} else {
132 			if (reader.name() == "")
133 				continue;
134 			else if (reader.hasError())
135 				return reader.error();
136 			else {
137 				try {
138 					reader.raiseError(QString("Unknown element name %1 ").arg(reader.name().toString()));
139 				} catch (...) {
140 					return reader.error();
141 				}
142 			}
143 		}
144 
145 	readFunctor.appendItem(url, QFileInfo(url).fileName(), rating, breedability);
146 
147 	return QXmlStreamReader::NoError;
148 
149 }
150 
151 
152 template <class WriteFunctor>
writePlaylist(QIODevice * device,WriteFunctor & writeFunctor)153 void QXmlPlaylistHandler::writePlaylist (QIODevice * device, WriteFunctor & writeFunctor ) {
154 
155 
156 	QXmlStreamWriter writer(device);
157 
158 	writer.writeStartDocument();
159 
160 	writer.writeStartElement("presetplaylist");
161 
162 
163  	writer.writeStartElement("description");
164 	writer.writeCharacters(writeFunctor.playlistDesc());
165 	writer.writeEndElement();
166 
167 	QString name;
168 	QString url;
169 	int rating;
170 	int breedability;
171 
172 	while (writeFunctor.nextItem(name, url, rating, breedability)) {
173 		writer.writeStartElement("item");
174 
175 
176 		writer.writeStartElement("name");
177 
178 		writer.writeCharacters(name.replace("&amp;", "&"));
179 		writer.writeEndElement();
180 
181 		writer.writeStartElement("url");
182 
183 		writer.writeCharacters(url.replace("&amp;", "&"));
184 		writer.writeEndElement();
185 
186 		writer.writeStartElement("rating");
187 		writer.writeCharacters(QString("%1").arg(rating)+"\n");
188 		writer.writeEndElement();
189 
190 		writer.writeStartElement("breedability");
191 		writer.writeCharacters(QString("%1").arg(breedability)+"\n");
192 		writer.writeEndElement();
193 
194 		writer.writeEndElement();
195 
196 	}
197 
198 	writer.writeEndElement();
199 
200 	writer.writeEndDocument();
201 
202 	return;
203 }
204 
205 
206 /// @idea  Instead of templates, allow subclassing of the playlist handler
207 #if 0
208 virtual void QXmlPlaylistHandler::readPresetItem(const QString & url, int rating) {}
209 
210 
211 virtual bool QXmlPlaylistHandler::nextPresetItem(QString & url, int & rating) {
212 	return false;
213 }
214 #endif
215 
216 #endif
217