The class declaration should be the first header in the cc file for
[shopper.git] / src / xmlList.cc
blob85f47c308c61a71ae7078941e2970c52e74a029d
1 /* Shopper
2 * Copyright (C) 2008 David Greaves
4 * This software is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public License
6 * as published by the Free Software Foundation; either version 2.1 of
7 * the License, or (at your option) any later version.
9 * This software is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this software; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17 * 02110-1301 USA
21 //#define DEBUG_SHOPPER 1
22 #include "shopper.h" // automake, i8n, gettext
23 #include <QtXml>
24 #include <iostream>
25 #include <sstream>
26 #include <string>
27 #include <stdexcept>
28 #include <list>
29 #include <set>
30 #include <signal.h>
31 #include "shopperList.h"
34 using namespace std;
36 namespace Shopper
38 void abort (QString msg){
39 #ifndef DEBUG_SHOPPER
40 Q_UNUSED(msg)
41 #endif
42 DEBUG(msg);
43 exit(1); // FIXME
46 ListParser::ListParser(List *list):
47 l(list),
48 active_cat_id(0)
52 void ListParser::start_list_el(const QXmlAttributes & attrs)
54 // zero the id counters
55 Category::id_master = 0;
56 Item::id_master = 0;
57 QString tmp("name");
58 for (int at = 0; at != attrs.count(); at++) {
59 QString at_name = attrs.localName(at);
60 QString at_value = attrs.value(at);
61 if (at_name.toLower() == "name") {
62 l->name = at_value;
63 } else if (at_name.toLower() == "state") { // save as int? or human readable?
64 bool ok;
65 l->state = sState(at_value.toInt(&ok));
66 if (!ok) {
67 abort("Converting state failed\n");
69 } else {
70 DEBUG("<list> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
74 void ListParser::start_cat_el(const QXmlAttributes & attrs)
76 if (l == NULL) {
77 DEBUG("<category> Not inside <list>\n");
78 exit(1); // FIXME throw?
80 c = new Category();
81 for (int at = 0; at != attrs.count(); at++) {
82 QString at_name = attrs.localName(at);
83 QString at_value = attrs.value(at);
84 if (at_name.toLower() == "name") {
85 c->name = at_value;
86 } else if (at_name.toLower() == "active") { // is this the category active?
87 if (at_value.toLower() == "true" or at_value == "1")
88 l->active_category = c;
89 } else {
90 DEBUG("<category> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
93 l->add(*c);
95 void ListParser::start_item_el(const QXmlAttributes & attrs)
97 if (c == NULL) {
98 DEBUG("<item> Not inside <category>\n");
99 exit(1); // FIXME
102 i = new Item();
103 i->category=c; // current category
104 for (int at = 0; at != attrs.count(); at++) {
105 QString at_name = attrs.localName(at);
106 QString at_value = attrs.value(at);
107 if (at_name.toLower() == "desc") {
108 i->desc = at_value;
109 } else if (at_name.toLower() == "note") {
110 i->note = at_value;
111 } else if (at_name.toLower() == "wanted") {
112 i->set_wanted(at_value.toLower() == "true" or at_value == "1");
113 } else if (at_name.toLower() == "bought") {
114 i->set_bought(at_value.toLower() == "true" or at_value == "1");
115 } else {
116 DEBUG("<item> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
119 l->add(*i);
122 bool ListParser::startElement (const QString & namespaceURI,
123 const QString & el,
124 const QString & qName,
125 const QXmlAttributes & attrs)
127 Q_UNUSED(namespaceURI)
128 Q_UNUSED(qName)
129 DEBUG("adding " << el << "\n");
130 if (el.toLower() == "list") {
131 start_list_el(attrs);
132 } else if (el.toLower() == "category") {
133 start_cat_el(attrs);
134 } else if (el.toLower() == "item") {
135 start_item_el(attrs);
136 } else {
137 throw ;
139 return true;
142 bool ListParser::endElement (const QString & namespaceURI,
143 const QString & el,
144 const QString & qName)
146 Q_UNUSED(namespaceURI)
147 Q_UNUSED(qName)
148 DEBUG("done " << el << "\n");
149 if (el.toLower() == "list") {
150 l->resequence(); // Ensure the id's are sensible FIXME : not needed?
151 l = NULL; // No current list
152 } else if (el.toLower() == "category") {
153 // add the created cat to list
154 c->dbg();
155 c=NULL; // No current category
156 } else if (el.toLower() == "item") {
157 // add the created item to list
158 i->dbg();
159 DEBUG("Assigned " << i->desc << " to category " << i->category->name << "\n");
160 i = NULL; // No current item
161 } else {
162 return false;
164 return true;
166 bool ListParser::fatalError ( const QXmlParseException & exception )
168 Q_UNUSED(exception)
169 DEBUG("Markup error\n");
170 return true;
173 void ListParser::from_string(QString xml)
175 QXmlSimpleReader xmlReader;
176 xmlReader.setContentHandler(this);
177 xmlReader.setErrorHandler(this);
178 QXmlInputSource source;
179 source.setData(xml);
180 bool ok = xmlReader.parse(&source);
181 if (!ok)
182 std::cout << "Parsing failed." << std::endl;
183 DEBUG("Parsing EXIT\n");
186 ////////////////////////////////////////////////////////////////
187 XMLWriter::XMLWriter(const Shopper::List *list) :
188 l(list)
192 ostream& XMLWriter::write(ostream &out)
194 DEBUG("in write\n");
195 out << "<list name='"<< qPrintable(l->name)
196 << "' state='" << l->state
197 << "'>\n";
198 for (List::pCategoryIter c = l->categories.begin(); c != l->categories.end(); c++) {
199 out << " <category"
200 << ((l->active_category == *c) ? " active='1' " : "")
201 << " name='" << qPrintable((*c)->name)
202 << "' id='" << QString::number((*c)->id)
203 << "'>\n";
204 for (Category::pItemIter i = (*c)->items.begin(); i != (*c)->items.end(); i++) {
205 out << " <item"
206 << " wanted='" << (*i)->wanted
207 << "' bought='" << (*i)->bought
208 << "' desc='" << qPrintable((*i)->desc) // FIXME: Escape quotes etc
209 << "' note='" << qPrintable((*i)->note) // FIXME: Escape quotes etc
210 << "'/>\n";
212 out << " </category>\n";
214 out << "</list>\n";
215 DEBUG("done write\n");
216 return (out);