Kitlist  1.1.0
kitmodel.cpp
Go to the documentation of this file.
1 /*
2 
3  This file is part of Kitlist, a program to maintain a simple list
4  of items and assign items to one or more categories.
5 
6  Copyright (C) 2008,2009 Frank Dean
7 
8  Kitlist is free software: you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation, either version 3 of the License, or
11  (at your option) any later version.
12 
13  Kitlist is distributed in the hope that it will be useful,
14  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  GNU General Public License for more details.
17 
18  You should have received a copy of the GNU General Public License
19  along with Kitlist. If not, see <http://www.gnu.org/licenses/>.
20 
21 */
22 
23 #include "kitmodel.hpp"
24 #include <algorithm>
25 #include <cassert>
26 #include <glib.h>
27 #include <iostream>
28 #include <iterator>
29 
30 
37  m_dirty = false;
38  m_deleted = false;
39  m_new = false;
40 }
41 
42 
46 }
47 
48 
50  delete m_removed_children;
51  delete m_added_children;
52 }
53 
54 
63  m_removed_children->clear();
64  m_added_children->clear();
65 }
66 
67 
69  ItemIter i = m_items.begin();
70  while (i != m_items.end()) {
71  Item* item = *i;
72  if (((ModelItem*) item)->is_deleted()) {
73  ItemIter iterTemp = i;
74  m_items.erase(i);
75  i = iterTemp++;
76  } else {
77  i++;
78  }
79  }
80 }
81 
82 
89  Category::add_item(item);
90  // If the item was previously removed, just remove it from the removed list, so
91  // it just won't be deleted. Don't add it to the inserted list, as it must have
92  // previously belonged.
93  ItemMap::size_type n = m_removed_children->erase(item->get_id());
94  if (n == 0) {
95  /* std::pair<ItemMapIter, bool> r =*/
96  m_added_children->insert(std::make_pair(item->get_id(), (ModelItem*) item));
97  }
98 }
99 
100 
107  Category::remove_item(item);
108  // Much like adding an item, if the item has previously been added,
109  // just remove that fact.
110  ItemMap::size_type n = m_added_children->erase(item->get_id());
111  if (n == 0) {
112  m_removed_children->insert(std::make_pair(item->get_id(), (ModelItem*) item));
113  }
114 }
115 
116 
123  for (ModelItemIter i = items->begin(); i != items->end(); ++i) {
124  remove_item(*i);
125  }
126 }
127 
128 
136  for (ItemIter i = m_items.begin(); i != m_items.end(); ++i) {
137  ModelItem* mi = (ModelItem*)*i;
138  if (!mi->is_deleted())
139  retval->push_back(mi);
140  }
141  return retval;
142 }
143 
144 
152  ItemContainer* retval = new ItemContainer;
153  for (ItemIter i = m_items.begin(); i != m_items.end(); ++i) {
154  ModelItem* mi = (ModelItem*)*i;
155  if (!mi->is_deleted()) {
156  retval->push_back(mi);
157  }
158  }
159  return retval;
160 }
161 
162 
173  ItemContainer* retval = new ItemContainer;
174  for (ItemIter i = m_items.begin(); i != m_items.end(); ++i) {
175  ModelItem* mi = (ModelItem*)*i;
176  if (!mi->is_deleted() && functor(**i)) {
177  retval->push_back(mi);
178  }
179  }
180  return retval;
181 }
182 
183 
187 KitModel::KitModel() : m_dirty(false), m_item_filter(ALL) {
188  m_item_map = new ItemMap;
190 }
191 
192 
199  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
200  delete (*i).second;
201  (*i).second = 0;
202  }
203  m_item_map->clear();
204  for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
205  delete (*i).second;
206  (*i).second = 0;
207  }
208  m_category_map->clear();
209  delete m_item_map;
210  delete m_category_map;
211 }
212 
213 
219  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
220  if (slot(i))
221  break;
222  }
223 }
224 
225 
231  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
232  if (slot(*(*i).second))
233  break;
234  }
235 }
236 
237 
243  for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
244  if (slot(i))
245  break;
246  }
247 }
248 
249 
255  for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
256  if (slot(*(*i).second))
257  break;
258  }
259 }
260 
261 
266  ModelCategory* retval = NULL;
267  CategoryMapIter i = m_category_map->find(id);
268  if (i != m_category_map->end()) {
269  retval = (*i).second;
270  }
271  return retval;
272 }
273 
274 
279  ModelItem* retval = NULL;
280  ItemMapIter i = m_item_map->find(id);
281  if (i != m_item_map->end()) {
282  retval = (*i).second;
283  }
284  return retval;
285 }
286 
287 
288 // ModelCategoryContainer* KitModel::getCategories() {
289 // ModelCategoryContainer* retval = new ModelCategoryContainer;
290 // for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
291 // retval->push_back((*i).second);
292 // }
293 // return retval;
294 // }
295 
296 
301  CategoryContainer* retval = new CategoryContainer;
302  for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
303  ModelCategory* cat = (*i).second;
304  if (!cat->is_deleted()) {
305  retval->push_back(cat);
306  }
307  }
308  return retval;
309 }
310 
311 
312 // ModelItemContainer* KitModel::getAllItems() {
313 // ModelItemContainer* retval = new ModelItemContainer;
314 // for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
315 // retval->push_back((*i).second);
316 // }
317 // return retval;
318 // }
319 
320 
328  ItemContainer* retval = new ItemContainer;
329  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
330  if (!((*i).second)->is_deleted()) {
331  retval->push_back((*i).second);
332  }
333  }
334  return retval;
335 }
336 
337 
346  ItemContainer* retval = new ItemContainer;
347  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
348  if (!((*i).second)->is_deleted() && functor(*(*i).second)) {
349  retval->push_back((*i).second);
350  }
351  }
352  return retval;
353 }
354 
355 
362  m_category_map->insert(std::make_pair(category->get_id(), category));
363 }
364 
365 
372  m_item_map->insert(std::make_pair(item->get_id(), item));
373 }
374 
375 
382 void KitModel::add_item(ModelItem* item, long cat_id) {
383  std::pair<long, ModelItem*> pair = std::make_pair(item->get_id(), item);
384  m_item_map->insert(pair);
385  ModelCategory* c = find_category(cat_id);
386  if (c) {
387  c->add_item(item);
388  } else
389  g_warning("category id %ld was not found - unable to associate item", cat_id);
390 }
391 
392 
399 void KitModel::copy_items(const ModelItemContainer& items, long cat_id) {
400  assert(cat_id != -1);
401  ModelCategory* c = find_category(cat_id);
402  if (c) {
403  c->set_dirty(true);
404  // Make a copy of the list of source items requested for insertion
405  // so that we can sort them
406  ModelItemContainer sourceItems(items);
407  // Create a list of ModelItems rather than Items
408  // The Category class should be holding ModelItems
409  ModelItemContainer targetItems;
410  for (ItemIter i = c->m_items.begin(); i != c->m_items.end(); ++i) {
411  targetItems.push_back((ModelItem*) (*i));
412  }
413  // Each list sorted by pointer references - duplicate items will have the same
414  // pointer references
415  sort(sourceItems.begin(), sourceItems.end()/*, ModelItemCompareId()*/);
416  // To hold the unique list of non-duplicate items
417  ModelItemContainer newItems;
418  sort(targetItems.begin(), targetItems.end()/*, ModelItemCompareId()*/);
419  std::set_difference(
420  sourceItems.begin(),
421  sourceItems.end(),
422  targetItems.begin(),
423  targetItems.end(),
424  std::back_insert_iterator<ModelItemContainer>(newItems)
425  );
426  // newItems now contains only those items to be inserted that do not already exist
427  // Don't just add them, need to use category's add_item method to update list of added and removed
428  // c->m_items.insert(c->m_items.end(), newItems.begin(), newItems.end());
429  // Also add these to ModelCategory's map of added items
430  for (ModelItemIter i = newItems.begin(); i != newItems.end(); ++i) {
431  c->add_item(*i);
432  }
433  } else {
434  g_error("Warning: category id %ld was not found - unable to copy items",
435  cat_id);
436  }
437 }
438 
439 
446 bool KitModel::filter(bool checked) {
447  switch (m_item_filter) {
448  case ALL : return true;
449  case CHECKED : return checked;
450  case UNCHECKED : return !checked;
451  }
452  return true;
453 }
454 
455 
467  for (CategoryMapIter i = m_category_map->begin(); i != m_category_map->end(); ++i) {
468  ModelCategory* cat = (*i).second;
469  if (!cat->is_deleted())
470  cat->reset();
471  }
472  for (ItemMapIter i = m_item_map->begin(); i != m_item_map->end(); ++i) {
473  ModelItem* item = (*i).second;
474  if (!item->is_deleted())
475  item->reset();
476  }
477  m_dirty = false;
478 }
479 
487  CategoryMapIter c = m_category_map->begin();
488  while (c != m_category_map->end()) {
489  ModelCategory* cat = (*c).second;
490  if (cat->is_deleted()) {
491  CategoryMapIter iterTemp = c;
492  iterTemp++;
493  m_category_map->erase(c);
494  c = iterTemp;
495  delete cat;
496  } else {
497  cat->purge();
498  c++;
499  }
500  }
501  ItemMapIter i = m_item_map->begin();
502  while (i != m_item_map->end()) {
503  ModelItem* item = (*i).second;
504  if (item->is_deleted()) {
505  ItemMapIter iterTemp = i;
506  iterTemp++;
507  m_item_map->erase(i);
508  i = iterTemp;
509  delete item;
510  } else {
511  i++;
512  }
513  }
514 }
~KitModel()
Destructor.
Definition: kitmodel.cpp:198
virtual bool filter(bool checked)
Applies the current filter.
Definition: kitmodel.cpp:446
long get_id()
Definition: item.hpp:46
ModelItemContainer::iterator ModelItemIter
Definition: kitmodel.hpp:82
Class encapsulating state of an object in the data model.
Definition: kitmodel.hpp:38
sigc::slot< bool, ModelItem & > SlotForeachModelItem
Definition: kitmodel.hpp:88
void foreach_category_iter(const SlotForeachCategoryIter &slot)
Calls the provided slot for each category in the map.
Definition: kitmodel.cpp:242
Represents a Category combined with GuiState attributes.
Definition: kitmodel.hpp:94
ItemMap * m_removed_children
List of items removed from the Category.
Definition: kitmodel.hpp:97
CategoryMap * m_category_map
Map allowing categories to be located by ID.
Definition: kitmodel.hpp:145
ItemContainer m_items
List of associated items.
Definition: category.hpp:41
bool m_deleted
Definition: kitmodel.hpp:41
ItemContainer::iterator ItemIter
Definition: item.hpp:92
virtual void add_item(Item *item)
Associates the passed item with this Category.
Definition: category.cpp:29
sigc::slot< bool, ModelCategory & > SlotForeachCategory
Definition: kitmodel.hpp:126
void set_dirty(bool dirty=true)
Definition: kitmodel.hpp:46
void foreach_item_iter(const SlotForeachModelItemIter &slot)
Calls the provided slot for each item in the map.
Definition: kitmodel.cpp:218
void foreach_category(const SlotForeachCategory &slot)
Calls the provided slot for each category in the map.
Definition: kitmodel.cpp:254
KitModel()
Creates an empty data model.
Definition: kitmodel.cpp:187
ItemMap::iterator ItemMapIter
Definition: kitmodel.hpp:85
virtual void add_category(ModelCategory *category)
Add a category to the model.
Definition: kitmodel.cpp:361
virtual ModelItem * find_item(long id)
Finds an item by it&#39;s unique ID.
Definition: kitmodel.cpp:278
std::vector< Item * > ItemContainer
Definition: item.hpp:91
virtual ModelCategory * find_category(long id)
Finds a Category by it&#39;s unique ID.
Definition: kitmodel.cpp:265
virtual void remove_items(ModelItemContainer *items)
Removes all the passed items from this ModelCategory.
Definition: kitmodel.cpp:122
virtual ItemContainer * get_items()
Returns the list of items belonging to the Category.
Definition: kitmodel.cpp:151
bool m_dirty
Definition: kitmodel.hpp:40
sigc::slot< bool, const ItemMap::iterator & > SlotForeachModelItemIter
Definition: kitmodel.hpp:87
std::vector< ModelItem * > ModelItemContainer
Definition: kitmodel.hpp:81
enum item_filter_types m_item_filter
Indicates whether and how items are currently filtered.
Definition: kitmodel.hpp:158
virtual ItemContainer * get_all_items()
Returns a list of all items.
Definition: kitmodel.cpp:327
bool m_new
Definition: kitmodel.hpp:42
ItemMap * m_item_map
Map allowing items to be located by ID.
Definition: kitmodel.hpp:152
Represents an Item.
Definition: item.hpp:37
virtual ModelItemContainer * get_model_items()
Definition: kitmodel.cpp:134
virtual void reset()
resets the state of each flag to it&#39;s default.
Definition: kitmodel.cpp:36
CategoryMap::iterator CategoryMapIter
Definition: kitmodel.hpp:123
bool is_deleted()
Definition: kitmodel.hpp:47
Represents a Category.
Definition: category.hpp:37
virtual void remove_item(Item *item)
Removes the association of the passed item from this Category.
Definition: category.cpp:40
Represents an Item combined with GuiState attributes.
Definition: kitmodel.hpp:60
virtual CategoryContainer * get_categories()
Returns a list of all categories.
Definition: kitmodel.cpp:300
long get_id()
Definition: category.hpp:45
ItemMap * m_added_children
List of items added to the Category.
Definition: kitmodel.hpp:99
bool m_dirty
Indicates whether the model needs saving. I.e it&#39;s state has changed.
Definition: kitmodel.hpp:138
void foreach_item(const SlotForeachModelItem &slot)
Calls the provided slot for each item in the map.
Definition: kitmodel.cpp:230
virtual void add_item(Item *)
Adds the passed item to this ModelCategory.
Definition: kitmodel.cpp:88
std::vector< Category * > CategoryContainer
Definition: category.hpp:84
virtual void add_item(ModelItem *item)
Adds an item to the model.
Definition: kitmodel.cpp:371
virtual void purge()
Purges deleted categories and items from the model.
Definition: kitmodel.cpp:486
virtual void reset()
Resets all contained objects to their default states.
Definition: kitmodel.cpp:466
std::map< long, ModelCategory * > CategoryMap
Definition: kitmodel.hpp:122
Functor for processing items.
Definition: item.hpp:85
virtual void purge()
Definition: kitmodel.cpp:68
std::map< long, ModelItem * > ItemMap
Definition: kitmodel.hpp:84
sigc::slot< bool, const CategoryMap::iterator & > SlotForeachCategoryIter
Definition: kitmodel.hpp:125
virtual void reset()
Resets the Category state.
Definition: kitmodel.cpp:61
virtual void remove_item(Item *item)
Removes the passed item from this ModelCategory.
Definition: kitmodel.cpp:106
virtual void copy_items(const ModelItemContainer &items, long cat_id=-1)
Copies items to the specified category.
Definition: kitmodel.cpp:399

Copyright 2008-2021 Frank Dean