Category dialog draws, moves, deletes - still needs popups to handle deleting items
[shopper.git] / src / xmlList.cc
blob0db3708318786bd43ec663c1556c8a23dd434f2b
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 DEBUG(msg);
40 exit(1); // FIXME
43 ListParser::ListParser(List *list):
44 l(list)
48 void ListParser::start_list_el(const QXmlAttributes & attrs)
50 // zero the id counters
51 Category::id_master = 0;
52 Item::id_master = 0;
53 QString tmp("name");
54 for (int at = 0; at != attrs.count(); at++) {
55 QString at_name = attrs.localName(at);
56 QString at_value = attrs.value(at);
57 if (at_name.toLower() == "name") {
58 l->name = at_value;
59 } else if (at_name.toLower() == "state") { // save as int? or human readable?
60 bool ok;
61 l->state = sState(at_value.toInt(&ok));
62 if (!ok) {
63 abort("Converting state failed\n");
65 // } else if (at_name.toLower() == "active") { // at end we'll need to lookup the id
66 // std::istringstream convert(at_value);
67 // if (!(convert >> active_cat_id)) {
68 // abort("Converting active failed\n");
69 // }
70 } else {
71 DEBUG("<list> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
75 void ListParser::start_cat_el(const QXmlAttributes & attrs)
77 if (l == NULL) {
78 DEBUG("<category> Not inside <list>\n");
79 exit(1); // FIXME throw?
81 // c = new Category(Category::SPARSE); // Not needed at the moment
82 c = new Category();
83 for (int at = 0; at != attrs.count(); at++) {
84 QString at_name = attrs.localName(at);
85 QString at_value = attrs.value(at);
86 if (at_name.toLower() == "name") {
87 c->name = at_value;
88 } else if (at_name.toLower() == "active") { // is this the category active?
89 if (at_value.toLower() == "true" or at_value == "1")
90 l->active_category = c;
91 } else {
92 DEBUG("<category> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
95 l->add(*c);
97 void ListParser::start_item_el(const QXmlAttributes & attrs)
99 if (c == NULL) {
100 DEBUG("<item> Not inside <category>\n");
101 exit(1); // FIXME
103 // i = new Item(Item::SPARSE); // Not needed at the moment
104 i = new Item();
105 i->category=c; // current category
106 for (int at = 0; at != attrs.count(); at++) {
107 QString at_name = attrs.localName(at);
108 QString at_value = attrs.value(at);
109 if (at_name.toLower() == "desc") {
110 i->desc = at_value;
111 // } else if (at_name.toLower() == "id") {
112 // std::istringstream convert(at_value);
113 // if (!(convert >> i->id)) {
114 // abort("Converting pos failed\n");
115 // }
116 // Item::id_master = max(Item::id_master, i->id);
117 } else if (at_name.toLower() == "note") {
118 i->note = at_value;
119 // } else if (at_name.toLower() == "cat_id") {
120 // std::istringstream convert(at_value);
121 // if (!(convert >> cat_id)) {
122 // abort("Converting pos failed\n");
123 // }
124 // i->category = cat_by_id[cat_id]; // cat must be declared before item
125 // if (i->category == NULL) abort("No category for item \n");
126 } else if (at_name.toLower() == "wanted") {
127 i->wanted = (at_value.toLower() == "true" or at_value == "1");
128 } else if (at_name.toLower() == "bought") {
129 i->bought = (at_value.toLower() == "true" or at_value == "1");
130 } else {
131 DEBUG("<item> Unknown attribute : " << at_name << "='" <<at_value<<"'\n");
134 l->add(*i);
137 bool ListParser::startElement (const QString & namespaceURI,
138 const QString & el,
139 const QString & qName,
140 const QXmlAttributes & attrs)
142 DEBUG("adding " << el << "\n");
143 if (el.toLower() == "list") {
144 start_list_el(attrs);
145 } else if (el.toLower() == "category") {
146 start_cat_el(attrs);
147 } else if (el.toLower() == "item") {
148 start_item_el(attrs);
149 } else {
150 throw ;
152 return true;
155 bool ListParser::endElement (const QString & namespaceURI,
156 const QString & el,
157 const QString & qName)
159 DEBUG("done " << el << "\n");
160 if (el.toLower() == "list") {
161 // if (cat_by_id[active_cat_id]) {
162 // l->active_category = cat_by_id[active_cat_id];
163 // DEBUG("Set default category to " << l->active_category->name << "\n");
164 // } else {
165 // DEBUG("Default category " << active_cat_id << " not found in map\n");
166 // }
167 l->resequence(); // Ensure the id's are sensible FIXME : not needed?
168 l = NULL; // No current list
169 } else if (el.toLower() == "category") {
170 // add the created cat to list
171 c->dbg();
172 c=NULL; // No current category
173 } else if (el.toLower() == "item") {
174 // add the created item to list
175 i->dbg();
176 DEBUG("Assigned " << i->desc << " to category " << i->category->name << "\n");
177 i = NULL; // No current item
178 } else {
179 return false;
181 return true;
183 bool ListParser::fatalError ( const QXmlParseException & exception )
185 DEBUG("Markup error\n");
186 return true;
189 void ListParser::from_string(QString xml)
191 QXmlSimpleReader xmlReader;
192 xmlReader.setContentHandler(this);
193 xmlReader.setErrorHandler(this);
194 QXmlInputSource source;
195 source.setData(xml);
196 bool ok = xmlReader.parse(&source);
197 if (!ok)
198 std::cout << "Parsing failed." << std::endl;
199 DEBUG("Parsing EXIT\n");
202 ////////////////////////////////////////////////////////////////
203 XMLWriter::XMLWriter(const Shopper::List *list) :
204 l(list)
208 ostream& XMLWriter::write(ostream &out)
210 DEBUG("in write\n");
211 out << "<list name='"<< qPrintable(l->name)
212 << "' state='" << l->state
213 << "'>\n";
214 for (List::pCategoryIter c = l->categories.begin(); c != l->categories.end(); c++) {
215 out << " <category"
216 << ((l->active_category == *c) ? " active='1' " : "")
217 << " name='" << qPrintable((*c)->name)
218 << "'>\n";
219 for (List::pItemIter i = l->items.begin(); i != l->items.end(); i++) {
220 if ((*i)->category != (*c)) {continue;} // only output items in this category
221 out << " <item"
222 << " wanted='" << (*i)->wanted
223 << "' bought='" << (*i)->bought
224 << "' desc='" << qPrintable((*i)->desc) // FIXME: Escape quotes etc
225 << "' note='" << qPrintable((*i)->note) // FIXME: Escape quotes etc
226 << "'/>\n";
228 out << " </category>\n";
230 out << "</list>\n";
231 DEBUG("done write\n");
232 return (out);