Warning, /include/Geant4/tools/xml/styles is written in an unsupported language. File is not indexed.
0001 // Copyright (C) 2010, Guy Barrand. All rights reserved.
0002 // See the file tools.license for terms.
0003
0004 #ifndef tools_xml_styles
0005 #define tools_xml_styles
0006
0007 #include "../sg/style_colormap"
0008 #include "../sout"
0009 #include "../forit"
0010
0011 #include <utility>
0012 #include <vector>
0013
0014 namespace tools {
0015 namespace xml {
0016
0017 class styles {
0018 public:
0019 styles(std::ostream& a_out):m_out(a_out){}
0020 virtual ~styles(){}
0021 public:
0022 styles(const styles& a_from)
0023 :m_out(a_from.m_out)
0024 ,m_named_styles(a_from.m_named_styles)
0025 ,m_aliases(a_from.m_aliases)
0026 ,m_cmaps(a_from.m_cmaps)
0027 {}
0028 styles& operator=(const styles& a_from){
0029 m_named_styles = a_from.m_named_styles;
0030 m_aliases = a_from.m_aliases;
0031 m_cmaps = a_from.m_cmaps;
0032 return *this;
0033 }
0034 public:
0035 std::ostream& out() const {return m_out;}
0036
0037 const sg::cmaps_t& cmaps() const {return m_cmaps;}
0038 sg::cmaps_t& cmaps() {return m_cmaps;}
0039
0040 typedef std::pair<std::string,std::string> style_item_t;
0041 typedef std::vector<style_item_t> style_t;
0042 typedef std::pair<std::string,style_t> named_style_t;
0043
0044 const std::vector<named_style_t>& named_styles() const {return m_named_styles;}
0045 std::vector<named_style_t>& named_styles() {return m_named_styles;}
0046
0047 typedef std::pair<std::string,std::string> alias_t;
0048 const std::vector<alias_t>& aliases() const {return m_aliases;}
0049 std::vector<alias_t>& aliases() {return m_aliases;}
0050
0051 const style_t* find_style(const std::string& a_name) const {
0052 tools_vforcit(named_style_t,m_named_styles,it){
0053 if((*it).first==a_name) return &((*it).second);
0054 }
0055 return 0;
0056 }
0057
0058 void add_style(const std::string& a_name,const style_t& a_style) {
0059 tools_vforit(named_style_t,m_named_styles,it){
0060 if((*it).first==a_name) { //override
0061 (*it).second = a_style;
0062 return;
0063 }
0064 }
0065 m_named_styles.push_back(named_style_t(a_name,a_style));
0066 }
0067
0068 void append(const styles& a_from) {
0069 tools_vforcit(named_style_t,a_from.m_named_styles,it) {
0070 m_named_styles.push_back(*it);
0071 }
0072 }
0073
0074 // for plotter :
0075 template <class T> //T = [style,text_style,line_style]
0076 bool res_sg_style(const std::string& a_style,T& a_sg_style) const {
0077 //NOTE : a_sg_style is changed according to what is found.
0078 // Then it is not fully reset by this method.
0079 const style_t* sty = find_style(a_style);
0080 if(!sty) {
0081 //could be ok to not find a plotter sub style.
0082 return false;
0083 }
0084
0085 std::string _s;
0086 tools_vforcit(style_item_t,*sty,vit) {
0087 if(vit!=(*sty).begin()) _s += "\n";
0088 _s += (*vit).first;
0089 _s += " ";
0090 _s += (*vit).second;
0091 }
0092 return a_sg_style.from_string(m_out,m_cmaps,_s);
0093 }
0094
0095 typedef sg::style_colormap cmap_t;
0096
0097 void add_colormap(const std::string& a_name,const cmap_t& a_cmap) {
0098 m_cmaps[a_name] = a_cmap;
0099 }
0100
0101 protected:
0102 std::ostream& m_out;
0103 //styles :
0104 std::vector<named_style_t> m_named_styles;
0105 std::vector<alias_t> m_aliases;
0106 //cmaps :
0107 sg::cmaps_t m_cmaps;
0108 };
0109
0110 }}
0111
0112 #include "tree"
0113 #include "../vmanip"
0114
0115 namespace tools {
0116 namespace xml {
0117
0118 template <class K,class V>
0119 inline void add_alias(std::vector< std::pair<K,V> >& a_vec,const K& a_key,const V& a_value) {
0120 for(auto it = a_vec.begin(); it != a_vec.end(); ++it) {
0121 if((*it).first==a_key) {
0122 (*it).second = a_value; //override.
0123 return;
0124 }
0125 }
0126 //not found, add a new pair:
0127 a_vec.emplace_back(a_key, a_value);
0128 }
0129
0130 inline bool is_plotter_style(const styles::style_t& a_sty) {
0131 tools_vforcit(style_item_t,a_sty,it) {
0132 const std::string& key = (*it).first;
0133 const std::string& sv = (*it).second;
0134 if((key=="tag")&&(sv=="plotter_style")) return true;
0135 }
0136 return false;
0137 }
0138
0139 inline void load_style(styles& a_styles,const tree& a_tree) {
0140 std::string name;
0141 a_tree.attribute_value("name",name);
0142 if(name.empty()) {
0143 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0144 << " <style> without name."
0145 << std::endl;
0146 return;
0147 }
0148
0149 styles::style_t sty;
0150
0151 {looper _for(a_tree);
0152 while(element* _elem = _for.next_element()) {
0153
0154 if(_elem->name()=="copy") {
0155
0156 std::string from;
0157 _elem->attribute_value("from",from); //expect another style name.
0158 if(from.empty()) {
0159 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0160 << " <copy> without from."
0161 << std::endl;
0162 return;
0163 }
0164
0165 const styles::style_t* csty = a_styles.find_style(from);
0166 if(!csty) {
0167 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0168 << " <copy> : from " << sout(from) << " not found."
0169 << std::endl;
0170 return;
0171 }
0172
0173 append(sty,*csty);
0174
0175 } else {
0176 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0177 }
0178
0179 }}
0180
0181 if(sty.size()) a_styles.add_style(name,sty);
0182 }
0183
0184 inline void load_plotter_style(styles& a_styles,const tree& a_tree) {
0185 std::string pname;
0186 a_tree.attribute_value("name",pname);
0187 if(pname.empty()) {
0188 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0189 << " <plotter_style> without name."
0190 << std::endl;
0191 return;
0192 }
0193
0194 {styles::style_t sty;
0195 sty.push_back(styles::style_item_t("tag","plotter_style"));
0196
0197 {looper _for(a_tree);
0198 while(element* _elem = _for.next_element()) {
0199
0200 if(_elem->name()=="copy") {
0201
0202 std::string from;
0203 _elem->attribute_value("from",from); //expect a plotter_style name.
0204 if(from.empty()) {
0205 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0206 << " <copy> without from."
0207 << std::endl;
0208 return;
0209 }
0210
0211 const styles::style_t* csty = a_styles.find_style(from);
0212 if(!csty) {
0213 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0214 << " <copy> : from " << sout(from) << " not found."
0215 << std::endl;
0216 return;
0217 }
0218 if(csty->size()) a_styles.add_style(pname,*csty);
0219
0220 if(is_plotter_style(*csty)) {
0221 //search all <from>.<sub_style> styles :
0222 std::string head = from+".";
0223 std::string::size_type l = head.size();
0224
0225 styles sts(a_styles.out());
0226
0227 const std::vector<styles::named_style_t>& nss = a_styles.named_styles();
0228 tools_vforcit(styles::named_style_t,nss,it){
0229 const std::string& name = (*it).first;
0230 if(name.substr(0,l)==head) {
0231 std::string tail = name.substr(l,name.size()-l);
0232 const styles::style_t& ssty = (*it).second;
0233 if(ssty.size()) sts.add_style(pname+"."+tail,ssty);
0234 }
0235 }
0236
0237 a_styles.append(sts);
0238
0239 }
0240
0241
0242 } else {
0243 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0244 }
0245
0246 }}
0247
0248 if(sty.size()) a_styles.add_style(pname,sty);}
0249
0250 {looper _for(a_tree);
0251 while(tree* _tree = _for.next_tree()) {
0252
0253 const std::string& tag = _tree->tag_name();
0254 if(tag=="style") {
0255
0256 std::string name;
0257 _tree->attribute_value("name",name);
0258 if(name.empty()) {
0259 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0260 << " <style> without name."
0261 << std::endl;
0262 return;
0263 }
0264
0265 {styles::style_t sty;
0266
0267 {looper _for2(*_tree);
0268 while(element* _elem = _for2.next_element()) {
0269 if(_elem->name()=="copy") {
0270 std::string from;
0271 _elem->attribute_value("from",from); //expect another style name.
0272 if(from.empty()) {
0273 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style : (2) :"
0274 << " <copy> without from."
0275 << std::endl;
0276 return;
0277 }
0278 const styles::style_t* csty = a_styles.find_style(from);
0279 if(!csty) {
0280 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style : (2) :"
0281 << " <copy> : from " << sout(from) << " not found."
0282 << std::endl;
0283 return;
0284 }
0285 append(sty,*csty);
0286 } else {
0287 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0288 }
0289 }}
0290
0291 if(sty.size()) {
0292 std::string path = pname+"."+name;
0293 a_styles.add_style(path,sty);
0294 }}
0295
0296 } else {
0297 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0298 << " unexpected tag " << sout(tag) << "."
0299 << std::endl;
0300 }
0301
0302 }}
0303
0304 }
0305
0306 inline bool scan_style_tree(styles& a_styles,const tree& a_tree) {
0307
0308 if(a_tree.tag_name()!="styles") return false;
0309
0310 // look for aliases :
0311 {looper _for(a_tree);
0312 while(element* _elem = _for.next_element()) {
0313
0314 std::string name;
0315 _elem->attribute_value("name",name);
0316 if(name.empty()) {
0317 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0318 << " <alias> without name."
0319 << std::endl;
0320 continue;
0321 }
0322
0323 add_alias<std::string,std::string>(a_styles.aliases(),name,_elem->value());
0324 }}
0325
0326 // scan children :
0327 {looper _for(a_tree);
0328 while(tree* _tree = _for.next_tree()) {
0329
0330 const std::string& tag = _tree->tag_name();
0331 if(tag=="style") {
0332 load_style(a_styles,*_tree);
0333 } else if(tag=="plotter_style") {
0334 load_plotter_style(a_styles,*_tree);
0335 }
0336
0337 }}
0338
0339 return true;
0340 }
0341 }}
0342
0343 #endif