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
21 #define DEBUG_SHOPPER 1
33 #include "shopperList.h"
44 // No items, no categories
45 DEBUG("\n\n\nMAKING NEW LIST\n\n\n");
47 List::List(QString dump
)
49 DEBUG("\n\n\nMAKING NEW LIST FROM STRING\n\n\n");
50 ListParser
parse(this);
51 parse
.from_string(dump
);
52 } // initiate from a dump
56 for(list
<Category
*>::iterator catI
= categories
.begin();
57 catI
!= categories
.end(); ++catI
) {
62 List
* List::from_file(QString filename
)
65 std::ifstream
file(filename
.toAscii());
69 // Read xml as a stream
70 std::stringstream xml
;
72 std::string
sxml(xml
.str());
73 QString
qxml(sxml
.c_str());
74 DEBUG("read from : " <<filename
<<"\n"<<qxml
);
75 // Create new list and return it
76 return new Shopper::List(qxml
); // FIXME: may not succeed.
79 void List::to_file(QString filename
)
81 std::ofstream
outf(filename
.toAscii());
83 DEBUG("Couldn't open " << filename
<< " for writing\n");
89 List::operator QString() {return QString("XML here");} // a ustring representation of a List (XML)
91 // an ostream representation of a List (XML)
92 std::ostream
& operator <<(std::ostream
&out
, const List
&l
)
94 DEBUG("in << operator\n");
96 DEBUG("written XML\n");
100 // These are now just helper functions
101 void List::add(Item
&it
)
103 it
.get_category()->add(it
);
105 void List::rm(Item
&it
)
107 it
.get_category()->rm(it
);
110 void List::add(Category
&cat
)
112 DEBUG("Add category " << cat
.get_name());
113 if (categories
.empty())
115 DEBUG(" made active\n");
116 categories
.push_back(&cat
);
117 make_category_active(cat
);
119 list
<Category
*>::iterator low
= lower_bound(categories
.begin(),categories
.end(), &cat
, &cat_cmp
);
120 categories
.insert(low
, &cat
);
123 // Allows the list to emit signals when Items are added/removed
124 connect (&cat
, SIGNAL(item_added(Item
*)),
125 this, SIGNAL(item_added(Item
*)));
126 connect (&cat
, SIGNAL(item_removed(Item
*)),
127 this, SIGNAL(item_removed(Item
*)));
128 emit
category_list_changed();
129 emit
category_added(&cat
);
131 void List::rm(Category
&cat
)
133 if (categories
.size() == 1) return;
134 DEBUG("Removing category\n");
135 if (is_category_active(cat
)) cycle_active_category(true);
136 categories
.remove(&cat
);
138 emit
category_removed(&cat
);
139 emit
category_list_changed();
144 QString
List::get_name() const {return name
;}
145 void List::set_name(QString
)
149 sState
List::get_state() const {
152 void List::set_state(sState s
)
154 if (state
== s
) return;
157 state
= s
; // Set the state
158 emit
state_changed();
160 if (s
== Shopper::MAKING_LIST
) { // And go to category '1'
161 if (active_category
== NULL
) { // show category 1 rather than 'Everything'
162 make_category_active(*(categories
.front()));
165 // And go to category 'Everything' if switching to an 'out shopping' state.
166 if (s
== Shopper::WHATS_LEFT
|| s
== Shopper::OUT_SHOPPING
) {
167 if (old
== Shopper::MAKING_LIST
) no_category_active();
171 // Category filtering
172 Category
* List::get_active_category()
174 return(active_category
);
176 bool List::is_category_active(Category
&c
) const // empty set = all active
178 return (active_category
== NULL
|| active_category
== &c
);
179 // If using a set for multiple active categories
180 // return (active_categories.empty() || ( active_categories.find(c) != active_categories.end() ));;
182 void List::cycle_active_category(bool f
)
184 List::pCategoryIter begin
= categories
.begin();
185 List::pCategoryIter end
= categories
.end();
186 if (active_category
== NULL
) { // use first or last element as 'next'
187 active_category
= f
? *(begin
) : *(categories
.rbegin());
189 List::pCategoryIter c
=
190 find(begin
, end
, active_category
);
192 DEBUG("Not found - shouldn't happen\n");
196 active_category
= (++c
== end
)?NULL
:*c
;
198 active_category
= (c
== begin
)?NULL
:*--c
;
203 void List::make_next_category_active()
205 cycle_active_category(true);
206 emit
active_category_changed();
208 void List::make_prev_category_active()
210 cycle_active_category(false);
211 emit
active_category_changed();
213 void List::make_category_active(Category
&c
)
215 if (active_category
!= &c
) {
216 active_category
= &c
;
217 // If using a set for multiple active categories
218 // active_categories.insert(c);
219 emit
active_category_changed();
222 void List::make_category_inactive(Category
&c
)
224 if (active_category
!= NULL
) {
225 active_category
= NULL
;
226 // If using a set for multiple active categories
227 // active_categories.erase(c);
228 emit
active_category_changed();
231 void List::no_category_active()
233 if (active_category
!= NULL
) {
234 active_category
= NULL
;
235 emit
active_category_changed();
239 void List::resequence()
242 for(list
<Category
*>::iterator catI
= categories
.begin();
243 catI
!= categories
.end(); ++catI
) {
244 (*catI
)->set_id(id
++);
249 categories
.sort(&cat_cmp
);
252 void List::swap_categories(Category
*a
, Category
*b
)
254 int a_id
= a
->get_id();
255 DEBUG("a id is : " << a
->get_id()
256 << " b id is : " << b
->get_id()
258 a
->set_id(b
->get_id());
259 DEBUG("Now set b\n");
261 DEBUG("a id is : " << a
->get_id()
262 << " b id is : " << b
->get_id()
265 DEBUG("Reorder done\n");
267 void List::swap_categories(int a
, int b
)
269 /*Category *c1 = cat_by_id[a];
270 Category *c2 = cat_by_id[b];
278 QString
List::modeText()
280 return modeText(state
);
282 QString
List::modeText(sState s
)
286 return(QString("What's Left"));
288 return(QString("Full List"));
290 return(QString("Making List"));
292 return(QString("BAD State"));
295 // List::pItemIter List::itemsI() { return items.begin(); }
296 List::pCategoryIter
List::categoriesI(){ return categories
.begin(); }
297 // List::pItemIter List::itemsEnd() { return items.end(); }
298 List::pCategoryIter
List::categoriesEnd(){ return categories
.end(); }
300 void List::boughtNothing(){} // marks all items as not bought
301 void List::newList(){} // marks all items as not wanted
303 void List::clear(clear_list_mode m
)
305 for (List::pCategoryIter c
= categories
.begin(); c
!= categories
.end(); c
++) {
306 DEBUG("Clearing : "<<(*c
)->get_name());
307 for (Category::pItemIter it
= (*c
)->items
.begin(); it
!= (*c
)->items
.end(); it
++) {
308 (*it
)->set_bought(false); // Always clear bought
309 if (m
== CLEAR_WANTED
) {
310 (*it
)->set_wanted(false);
312 DEBUG("Cleared : "<<(*it
)->get_desc());
315 if (m
== CLEAR_WANTED
) {
316 set_state(Shopper::MAKING_LIST
);