]> git.tdb.fi Git - poefilter.git/blob - source/filter.cpp
02f8c3f6ccf278b1ab974e894f7aa2f09ff1304f
[poefilter.git] / source / filter.cpp
1 #include <msp/core/algorithm.h>
2 #include <msp/core/maputils.h>
3 #include <msp/io/print.h>
4 #include "category.h"
5 #include "filter.h"
6 #include "poefilter.h"
7
8 using namespace std;
9 using namespace Msp;
10
11 FilterStatement::FilterStatement():
12         show(true)
13 { }
14
15 void FilterStatement::set_show(bool s)
16 {
17         show = s;
18 }
19
20 void FilterStatement::add_line(const string &l)
21 {
22         lines.push_back(l);
23 }
24
25 void FilterStatement::add_line(list<FilterStatement> &st, const string &line)
26 {
27         for(list<FilterStatement>::iterator i=st.begin(); i!=st.end(); ++i)
28                 i->add_line(line);
29 }
30
31 void FilterStatement::write(IO::Base &out) const
32 {
33         if(show)
34                 out.write("Show\n");
35         else
36                 out.write("Hide\n");
37
38         for(list<string>::const_iterator i=lines.begin(); i!=lines.end(); ++i)
39                 IO::print(out, "\t%s\n", *i);
40 }
41
42
43 Filter::Filter():
44         abstract(false)
45 { }
46
47 void Filter::write(IO::Base &out) const
48 {
49         for(list<Block>::const_iterator i=blocks.begin(); i!=blocks.end(); ++i)
50         {
51                 list<FilterStatement> st;
52                 st.push_back(FilterStatement());
53                 st.back().set_show(i->show);
54                 i->appearance.add_lines(st.back());
55                 i->category->create_statements(st);
56
57                 IO::print(out, "# %s\n", i->category->get_name());
58                 for(list<FilterStatement>::const_iterator j=st.begin(); j!=st.end(); ++j)
59                         j->write(out);
60         }
61 }
62
63
64 Filter::Loader::Loader(Filter &f, const PoeFilter &p):
65         DataFile::ObjectLoader<Filter>(f),
66         poe(p)
67 {
68         add("abstract", &Filter::abstract);
69         add("hide", &Loader::hide);
70         add("include", &Loader::include);
71         add("show", &Loader::show);
72 }
73
74 string Filter::Loader::glob_to_re(const string &glob)
75 {
76         string result = "^";
77         for(string::const_iterator i=glob.begin(); i!=glob.end(); ++i)
78         {
79                 if(*i=='*')
80                         result += '.';
81                 else if(!isalnum(*i))
82                         result += '\\';
83                 result += *i;
84         }
85         result += '$';
86
87         return result;
88 }
89
90 bool Filter::Loader::category_order(const Category *c1, const Category *c2)
91 {
92         return c1->get_order()<c2->get_order();
93 }
94
95 void Filter::Loader::add_categories(const string &name, bool show)
96 {
97         vector<const Category *> categs;
98         if(name.find('*')!=string::npos)
99         {
100                 poe.find_categories(glob_to_re(name), categs);
101
102                 if(categs.empty())
103                         throw key_error(name);
104
105                 sort(categs, &category_order);
106         }
107         else
108                 categs.push_back(&poe.get_category(name));
109
110         for(vector<const Category *>::const_iterator i=categs.begin(); i!=categs.end(); ++i)
111         {
112                 bool found = false;
113                 for(list<Block>::const_iterator j=obj.blocks.begin(); (!found && j!=obj.blocks.end()); ++j)
114                         found = (j->category==*i);
115
116                 if(!found)
117                 {
118                         Block blk;
119                         blk.show = show;
120                         blk.category = *i;
121                         blk.appearance = (*i)->get_appearance();
122                         if(const Appearance *app = poe.get_theme().find_appearance((*i)->get_name()))
123                                 blk.appearance.merge_from(*app);
124                         obj.blocks.push_back(blk);
125                 }
126         }
127 }
128
129 void Filter::Loader::cancel(const string &name)
130 {
131         vector<const Category *> categs;
132         if(name.find('*')!=string::npos)
133         {
134                 poe.find_categories(glob_to_re(name), categs);
135
136                 if(categs.empty())
137                         throw key_error(name);
138         }
139         else
140                 categs.push_back(&poe.get_category(name));
141
142         for(vector<const Category *>::const_iterator i=categs.begin(); i!=categs.end(); ++i)
143                 for(list<Block>::iterator j=obj.blocks.begin(); j!=obj.blocks.end(); ++j)
144                         if(j->category==*i)
145                         {
146                                 obj.blocks.erase(j);
147                                 break;
148                         }
149 }
150
151 void Filter::Loader::hide(const string &name)
152 {
153         add_categories(name, false);
154 }
155
156 void Filter::Loader::include(const string &name)
157 {
158         const Filter &base = poe.get_filter(name);
159         obj.blocks.insert(obj.blocks.end(), base.blocks.begin(), base.blocks.end());
160 }
161
162 void Filter::Loader::show(const string &name)
163 {
164         add_categories(name, true);
165 }