1 // Copyright (C) 2008, 2009 Ben Asselstine
3 // This program is free software; you can redistribute it and/or modify
4 // it under the terms of the GNU General Public License as published by
5 // the Free Software Foundation; either version 3 of the License, or
6 // (at your option) any later version.
8 // This program is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 // GNU Library General Public License for more details.
13 // You should have received a copy of the GNU General Public License
14 // along with this program; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
20 #include "rectangle.h"
21 #include <sigc++/functors/mem_fun.h>
23 #include "shieldsetlist.h"
24 #include "shieldset.h"
27 #include "ucompose.hpp"
31 #define debug(x) {cerr<<__FILE__<<": "<<__LINE__<<": "<<x<<endl<<flush;}
34 Shieldsetlist* Shieldsetlist::s_instance = 0;
36 Shieldsetlist* Shieldsetlist::getInstance()
39 s_instance = new Shieldsetlist();
44 void Shieldsetlist::deleteInstance()
53 void Shieldsetlist::loadShieldsets(std::list<std::string> shieldsets)
55 for (std::list<std::string>::const_iterator i = shieldsets.begin();
56 i != shieldsets.end(); i++)
58 Shieldset *shieldset = loadShieldset(*i);
65 Shieldsetlist::Shieldsetlist()
67 // load all shieldsets
68 std::list<std::string> shieldsets = Shieldset::scanSystemCollection();
69 loadShieldsets(shieldsets);
70 shieldsets = Shieldset::scanUserCollection();
71 loadShieldsets(shieldsets);
75 Shieldsetlist::~Shieldsetlist()
77 for (iterator it = begin(); it != end(); it++)
81 std::list<std::string> Shieldsetlist::getNames() const
83 std::list<std::string> names;
84 for (const_iterator it = begin(); it != end(); it++)
85 names.push_back((*it)->getName());
88 std::string Shieldsetlist::getShieldsetDir(std::string name) const
90 DirMap::const_iterator it = d_dirs.find(name);
91 if (it == d_dirs.end())
97 Shieldset* Shieldsetlist::loadShieldset(std::string name)
99 debug("Loading shieldset " <<File::get_basename(File::get_dirname(name)));
101 Shieldset *shieldset = Shieldset::create(name);
105 if (shieldset->validate() == false)
107 cerr << "Error! shieldset: `" << shieldset->getName() <<
108 "' is invalid. Skipping." << endl;
113 if (d_shieldsetids.find(shieldset->getId()) != d_shieldsetids.end())
115 Shieldset *s = (*d_shieldsetids.find(shieldset->getId())).second;
116 cerr << "Error! shieldset: `" << shieldset->getName() <<
117 "' shares a duplicate shieldset id with `" << s->getConfigurationFile()
118 << "'. Skipping." << endl;
126 void Shieldsetlist::add(Shieldset *shieldset)
128 std::string subdir = File::get_basename(shieldset->getDirectory());
129 push_back(shieldset);
130 shieldset->setSubDir(subdir);
131 d_dirs[shieldset->getName()] = subdir;
132 d_shieldsets[subdir] = shieldset;
133 d_shieldsetids[shieldset->getId()] = shieldset;
136 Gdk::Color Shieldsetlist::getColor(guint32 shieldset, guint32 owner) const
138 Shieldset *s = getShieldset(shieldset);
140 return Gdk::Color("black");
141 return s->getColor(owner);
144 ShieldStyle *Shieldsetlist::getShield(guint32 shieldset, guint32 type, guint32 colour) const
146 Shieldset *s = getShieldset(shieldset);
149 return s->lookupShieldByTypeAndColour(type, colour);
152 void Shieldsetlist::instantiateImages()
154 for (iterator it = begin(); it != end(); it++)
155 (*it)->instantiateImages();
158 void Shieldsetlist::uninstantiateImages()
160 for (iterator it = begin(); it != end(); it++)
161 (*it)->uninstantiateImages();
164 Shieldset *Shieldsetlist::getShieldset(guint32 id) const
166 ShieldsetIdMap::const_iterator it = d_shieldsetids.find(id);
167 if (it == d_shieldsetids.end())
172 Shieldset *Shieldsetlist::getShieldset(std::string dir) const
174 ShieldsetMap::const_iterator it = d_shieldsets.find(dir);
175 if (it == d_shieldsets.end())
180 bool Shieldsetlist::addToPersonalCollection(Shieldset *shieldset, std::string &new_subdir, guint32 &new_id)
182 //do we already have this one?
184 if (getShieldset(shieldset->getSubDir()) == getShieldset(shieldset->getId())
185 && getShieldset(shieldset->getSubDir()) != NULL)
187 shieldset->setDirectory(getShieldset(shieldset->getId())->getDirectory());
191 //if the subdir conflicts with any other subdir, then change it.
192 if (getShieldset(shieldset->getSubDir()) != NULL)
195 for (int count = 0; count < 100; count++)
197 new_subdir = String::ucompose("%1%2", shieldset->getSubDir(), count);
198 if (getShieldset(new_subdir) == NULL)
206 shieldset->setSubDir(new_subdir);
209 new_subdir = shieldset->getSubDir();
211 //if the id conflicts with any other id, then change it
212 if (getShieldset(shieldset->getId()) != NULL)
214 new_id = Shieldsetlist::getNextAvailableId(shieldset->getId());
215 shieldset->setId(new_id);
218 new_id = shieldset->getId();
220 //make the directory where the shieldset is going to live.
221 std::string directory =
222 File::getUserShieldsetDir() + shieldset->getSubDir() + "/";
224 if (File::create_dir(directory) == false)
227 //okay now we copy the image files into the new directory
228 std::list<std::string> files;
229 shieldset->getFilenames(files);
230 for (std::list<std::string>::iterator it = files.begin(); it != files.end();
232 File::copy(shieldset->getFile(*it), directory + *it);
234 //save out the shieldset file
235 shieldset->setDirectory(directory);
236 XML_Helper helper(shieldset->getConfigurationFile(), std::ios::out, false);
237 shieldset->save(&helper);
242 int Shieldsetlist::getNextAvailableId(int after)
244 std::list<guint32> ids;
245 std::list<std::string> shieldsets = Shieldset::scanSystemCollection();
246 for (std::list<std::string>::const_iterator i = shieldsets.begin();
247 i != shieldsets.end(); i++)
249 Shieldset *shieldset = Shieldset::create(*i);
250 if (shieldset != NULL)
252 ids.push_back(shieldset->getId());
256 shieldsets = Shieldset::scanUserCollection();
257 for (std::list<std::string>::const_iterator i = shieldsets.begin();
258 i != shieldsets.end(); i++)
260 Shieldset *shieldset = Shieldset::create(*i);
261 if (shieldset != NULL)
263 ids.push_back(shieldset->getId());
267 for (guint32 i = after + 1; i < 1000000; i++)
269 if (find(ids.begin(), ids.end(), i) == ids.end())