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 "../vpair"
0008 #include "../sg/style_colormap"
0009 #include "../smatch"
0010 #include "../sout"
0011 #include "../forit"
0012 #include "../sbeg"
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 /*
0059 style_t* find_style(const std::string& a_name) {
0060 tools_vforit(named_style_t,m_named_styles,it){
0061 if((*it).first==a_name) return &((*it).second);
0062 }
0063 return 0;
0064 }
0065 void remove_item_in_style(style_t& a_style,const std::string& a_item) {
0066 remove<std::string,std::string>(a_style,a_item);
0067 }
0068 */
0069
0070 void find_styles(const std::string& a_pattern,std::vector<std::string>& a_v) const {
0071 a_v.clear();
0072 tools_vforcit(named_style_t,m_named_styles,it){
0073 if(match((*it).first,a_pattern)) a_v.push_back((*it).first);
0074 }
0075 }
0076
0077 void add_style(const std::string& a_name,const style_t& a_style) {
0078 tools_vforit(named_style_t,m_named_styles,it){
0079 if((*it).first==a_name) { //override
0080 //::printf("debug : styles::add_style : override : \"%s\"\n",a_name.c_str());
0081 (*it).second = a_style;
0082 return;
0083 }
0084 }
0085 //::printf("debug : styles::add_style : push_back \"%s\"\n",a_name.c_str());
0086 m_named_styles.push_back(named_style_t(a_name,a_style));
0087 }
0088
0089 void remove_styles(const std::string& a_pattern) {
0090 std::vector<named_style_t>::iterator it;
0091 for(it=m_named_styles.begin();it!=m_named_styles.end();) {
0092 if(match((*it).first,a_pattern)) {
0093 it = m_named_styles.erase(it);
0094 } else {
0095 it++;
0096 }
0097 }
0098 }
0099
0100 void append(const styles& a_from) {
0101 //::printf("debug : styles::append ...\n");
0102 tools_vforcit(named_style_t,a_from.m_named_styles,it) {
0103 //::printf("debug : styles::append \"%s\"\n",(*it).first.c_str());
0104 m_named_styles.push_back(*it);
0105 }
0106 }
0107
0108 bool is_alias(const std::string& a_wanted,std::string& a_style) const {
0109 if(find(m_aliases,a_wanted,a_style)) return true;
0110 a_style = a_wanted;
0111 return false;
0112 }
0113
0114 /*
0115 bool res_string(const std::string& a_style,
0116 const std::string& a_key,
0117 std::string& a_v) const {
0118 std::map<std::string,style_t>::const_iterator it = m_styles.find(a_style);
0119 if(it==m_styles.end()) {a_v.clear();return false;}
0120 const style_t& sty = (*it).second;
0121 if(!find(sty,a_key,a_v)) {a_v.clear();return false;}
0122 return true;
0123 }
0124 */
0125 template <class T>
0126 bool res_value(const style_t& a_sty,const std::string& a_key,T& a_v,const std::string& a_msg) const {
0127 //NOTE : if ret false, we do not set a_v to something.
0128
0129 std::string _s;
0130 if(!find(a_sty,a_key,_s)) {
0131 if(a_msg.size()) {
0132 m_out << "tools::xml::styles::res_value :"
0133 << " key " << sout(a_key) << " not found"
0134 << " in style " << sout(a_msg) << "."
0135 << std::endl;
0136 }
0137 return false;
0138 }
0139 T v;
0140 if(!to(_s,v)) {
0141 m_out << "tools::xml::styles::res_value :"
0142 << " for key " << sout(a_key) << " not found"
0143 << " in style " << sout(a_msg) << "."
0144 << " can't convert " << sout(_s) << " to value."
0145 << std::endl;
0146 return false;
0147 }
0148 a_v = v;
0149 return true;
0150 }
0151
0152 template <class T>
0153 bool res_value(const std::string& a_style,const std::string& a_key,T& a_v) const {
0154 //NOTE : if ret false, we do not set a_v to something.
0155
0156 //look if a_style is an alias :
0157 std::string style;
0158 is_alias(a_style,style);
0159
0160 const style_t* sty = find_style(style);
0161 if(!sty) {
0162 //m_out << "tools::xml::styles::res_value :"
0163 // << " style " << sout(style) << " not found."
0164 // << std::endl;
0165 return false;
0166 }
0167 T v;
0168 if(!res_value<T>(*sty,a_key,v,style)) return false;
0169 a_v = v;
0170 return true;
0171 }
0172
0173 bool res_color(const style_t& a_sty,const std::string& a_key,colorf& a_color,const std::string& a_msg) const {
0174 //NOTE : if ret false, we do not set a_color to something.
0175 std::string _s;
0176 if(!find(a_sty,a_key,_s)) {
0177 if(a_msg.size()) {
0178 m_out << "tools::xml::styles::res_color :"
0179 << " key " << sout(a_key) << " not found"
0180 << " in style " << sout(a_msg) << "."
0181 << std::endl;
0182 }
0183 return false;
0184 }
0185 if(!sg::find_color(m_cmaps,_s,a_color)) {
0186 m_out << "tools::xml::styles::res_color :"
0187 << " key " << sout(a_key) << " is not a color"
0188 << " in style " << sout(a_msg) << "."
0189 << std::endl;
0190 return false;
0191 }
0192 return true;
0193 }
0194
0195 bool res_color(const std::string& a_style,const std::string& a_key,colorf& a_color) const {
0196 //NOTE : if ret false, we do not set a_color to something.
0197
0198 //look if a_style is an alias :
0199 std::string style;
0200 is_alias(a_style,style);
0201
0202 const style_t* sty = find_style(style);
0203 if(!sty) {
0204 //m_out << "tools::xml::styles::res_color :"
0205 // << " style " << sout(style) << " not found."
0206 // << std::endl;
0207 return false;
0208 }
0209
0210 return res_color(*sty,a_key,a_color,style);
0211 }
0212
0213 bool res_bool(const style_t& a_sty,const std::string& a_key,bool& a_v,const std::string& a_msg) const {
0214 //NOTE : if ret false, we do not set a_v to something.
0215 std::string _s;
0216 if(!find(a_sty,a_key,_s)) {
0217 if(a_msg.size()) {
0218 m_out << "tools::xml::styles::res_bool :"
0219 << " key " << sout(a_key) << " not found"
0220 << " in style " << sout(a_msg) << "."
0221 << std::endl;
0222 }
0223 return false;
0224 }
0225 bool v;
0226 if(!to(_s,v)) {
0227 m_out << "tools::xml::styles::res_bool :"
0228 << " for key " << sout(a_key) << " not found"
0229 << " in style " << sout(a_msg) << "."
0230 << " can't convert " << sout(_s) << " to bool."
0231 << std::endl;
0232 return false;
0233 }
0234 a_v = v;
0235 return true;
0236 }
0237
0238 bool res_bool(const std::string& a_style,const std::string& a_key,bool& a_v) const {
0239 //NOTE : if ret false, we do not set a_color to something.
0240
0241 //look if a_style is an alias :
0242 std::string style;
0243 is_alias(a_style,style);
0244
0245 const style_t* sty = find_style(style);
0246 if(!sty) {
0247 //m_out << "tools::xml::styles::res_color :"
0248 // << " style " << sout(style) << " not found."
0249 // << std::endl;
0250 return false;
0251 }
0252
0253 return res_bool(*sty,a_key,a_v,style);
0254 }
0255
0256 // for plotter :
0257 template <class T> //T = [style,text_style,line_style]
0258 bool res_sg_style(const std::string& a_style,T& a_sg_style) const {
0259 //NOTE : a_sg_style is changed according to what is found.
0260 // Then it is not fully reset by this method.
0261 const style_t* sty = find_style(a_style);
0262 if(!sty) {
0263 //could be ok to not find a plotter sub style.
0264 //m_out << "tools::sg::gui_viewer::res_sg_style :"
0265 // << " style " << sout(a_style) << " not found."
0266 // << std::endl;
0267 return false;
0268 }
0269
0270 std::string _s;
0271 tools_vforcit(style_item_t,*sty,vit) {
0272 if(vit!=(*sty).begin()) _s += "\n";
0273 _s += (*vit).first;
0274 _s += " ";
0275 _s += (*vit).second;
0276 }
0277 return a_sg_style.from_string(m_out,m_cmaps,_s);
0278 }
0279
0280 typedef sg::style_colormap cmap_t;
0281 bool find_colormap(const std::string& a_name,cmap_t& a_cmap) const {
0282 std::map<std::string,cmap_t>::const_iterator it = m_cmaps.find(a_name);
0283 if(it==m_cmaps.end()) return false;
0284 a_cmap = (*it).second;
0285 return true;
0286 }
0287 void add_colormap(const std::string& a_name,const cmap_t& a_cmap) {
0288 m_cmaps[a_name] = a_cmap;
0289 }
0290 //void clear_colormaps() {m_cmaps.clear();/*add default*/}
0291
0292 public:
0293 static bool is_plotter_style(const style_t& a_sty) {
0294 tools_vforcit(style_item_t,a_sty,it) {
0295 const std::string& key = (*it).first;
0296 const std::string& sv = (*it).second;
0297 if((key=="tag")&&(sv=="plotter_style")) return true;
0298 }
0299 return false;
0300 }
0301
0302 public:
0303 void find_plotter_styles(std::vector<std::string>& a_v) const {
0304 a_v.clear();
0305 tools_vforcit(named_style_t,m_named_styles,it) {
0306 if(is_plotter_style((*it).second)) a_v.push_back((*it).first);
0307 }
0308 }
0309
0310 void dump() {
0311 tools_vforcit(named_style_t,m_named_styles,it) {
0312
0313 m_out << "/////////////////////////////////////" << std::endl;
0314 m_out << "/// " << (*it).first << std::endl;
0315 m_out << "/////////////////////////////////////" << std::endl;
0316
0317 const style_t& sty = (*it).second;
0318
0319 tools_vforcit(style_item_t,sty,vit) {
0320 m_out << " " << (*vit).first << " " << (*vit).second << std::endl;
0321 }
0322
0323 }
0324 }
0325
0326 bool print_plotter_style(std::ostream& a_out,const std::string& a_style) {
0327 std::string _beg = a_style+".";
0328 bool found = false;
0329 tools_vforcit(named_style_t,m_named_styles,it) {
0330 const std::string& _name = (*it).first;
0331 if((_name==a_style)||is_beg(_name,_beg)) {
0332 found = true;
0333 a_out << (*it).first << " :" << std::endl;
0334 const style_t& sty = (*it).second;
0335 tools_vforcit(style_item_t,sty,vit) {
0336 if((*vit).first=="tag") continue;
0337 a_out << " " << (*vit).first << " " << (*vit).second << std::endl;
0338 }
0339 }
0340 }
0341 return found;
0342 }
0343
0344 void list_plotter_styles(std::ostream& a_out) {
0345 tools_vforcit(named_style_t,m_named_styles,it) {
0346 const style_t& sty = (*it).second;
0347 if(!styles::is_plotter_style(sty)) continue;
0348 a_out << (*it).first << std::endl;
0349 }
0350 }
0351 protected:
0352 std::ostream& m_out;
0353 //styles :
0354 std::vector<named_style_t> m_named_styles;
0355 std::vector<alias_t> m_aliases;
0356 //cmaps :
0357 sg::cmaps_t m_cmaps;
0358 };
0359
0360 }}
0361
0362 #include "tree"
0363 #include "../vmanip"
0364
0365 namespace tools {
0366 namespace xml {
0367
0368 inline void load_style(styles& a_styles,const tree& a_tree) {
0369 std::string name;
0370 a_tree.attribute_value("name",name);
0371 if(name.empty()) {
0372 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0373 << " <style> without name."
0374 << std::endl;
0375 return;
0376 }
0377
0378 styles::style_t sty;
0379
0380 {looper _for(a_tree);
0381 while(element* _elem = _for.next_element()) {
0382
0383 if(_elem->name()=="copy") {
0384
0385 std::string from;
0386 _elem->attribute_value("from",from); //expect another style name.
0387 if(from.empty()) {
0388 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0389 << " <copy> without from."
0390 << std::endl;
0391 return;
0392 }
0393
0394 const styles::style_t* csty = a_styles.find_style(from);
0395 if(!csty) {
0396 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0397 << " <copy> : from " << sout(from) << " not found."
0398 << std::endl;
0399 return;
0400 }
0401
0402 append(sty,*csty);
0403
0404 } else {
0405 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0406 }
0407
0408 }}
0409
0410 if(sty.size()) a_styles.add_style(name,sty);
0411 }
0412
0413 inline void load_plotter_style(styles& a_styles,const tree& a_tree) {
0414 std::string pname;
0415 a_tree.attribute_value("name",pname);
0416 if(pname.empty()) {
0417 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0418 << " <plotter_style> without name."
0419 << std::endl;
0420 return;
0421 }
0422
0423 {styles::style_t sty;
0424 sty.push_back(styles::style_item_t("tag","plotter_style"));
0425
0426 {looper _for(a_tree);
0427 while(element* _elem = _for.next_element()) {
0428
0429 if(_elem->name()=="copy") {
0430
0431 std::string from;
0432 _elem->attribute_value("from",from); //expect a plotter_style name.
0433 if(from.empty()) {
0434 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0435 << " <copy> without from."
0436 << std::endl;
0437 return;
0438 }
0439
0440 const styles::style_t* csty = a_styles.find_style(from);
0441 if(!csty) {
0442 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0443 << " <copy> : from " << sout(from) << " not found."
0444 << std::endl;
0445 return;
0446 }
0447 if(csty->size()) a_styles.add_style(pname,*csty);
0448
0449 if(styles::is_plotter_style(*csty)) {
0450 //search all <from>.<sub_style> styles :
0451 std::string head = from+".";
0452 std::string::size_type l = head.size();
0453
0454 styles sts(a_styles.out());
0455
0456 const std::vector<styles::named_style_t>& nss = a_styles.named_styles();
0457 tools_vforcit(styles::named_style_t,nss,it){
0458 const std::string& name = (*it).first;
0459 if(name.substr(0,l)==head) {
0460 std::string tail = name.substr(l,name.size()-l);
0461 const styles::style_t& ssty = (*it).second;
0462 if(ssty.size()) sts.add_style(pname+"."+tail,ssty);
0463 }
0464 }
0465
0466 a_styles.append(sts);
0467
0468 }
0469
0470
0471 } else {
0472 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0473 }
0474
0475 }}
0476
0477 if(sty.size()) a_styles.add_style(pname,sty);}
0478
0479 {looper _for(a_tree);
0480 while(tree* _tree = _for.next_tree()) {
0481
0482 const std::string& tag = _tree->tag_name();
0483 if(tag=="style") {
0484
0485 std::string name;
0486 _tree->attribute_value("name",name);
0487 if(name.empty()) {
0488 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0489 << " <style> without name."
0490 << std::endl;
0491 return;
0492 }
0493
0494 {styles::style_t sty;
0495
0496 {looper _for2(*_tree);
0497 while(element* _elem = _for2.next_element()) {
0498 if(_elem->name()=="copy") {
0499 std::string from;
0500 _elem->attribute_value("from",from); //expect another style name.
0501 if(from.empty()) {
0502 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style : (2) :"
0503 << " <copy> without from."
0504 << std::endl;
0505 return;
0506 }
0507 const styles::style_t* csty = a_styles.find_style(from);
0508 if(!csty) {
0509 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style : (2) :"
0510 << " <copy> : from " << sout(from) << " not found."
0511 << std::endl;
0512 return;
0513 }
0514 append(sty,*csty);
0515 } else {
0516 sty.push_back(styles::style_item_t(_elem->name(),_elem->value()));
0517 }
0518 }}
0519
0520 if(sty.size()) {
0521 std::string path = pname+"."+name;
0522 a_styles.add_style(path,sty);
0523 }}
0524
0525 } else {
0526 a_styles.out() << "tools::sg::gui_viewer::load_plotter_style :"
0527 << " unexpected tag " << sout(tag) << "."
0528 << std::endl;
0529 }
0530
0531 }}
0532
0533 }
0534
0535 inline bool scan_style_tree(styles& a_styles,const tree& a_tree) {
0536
0537 if(a_tree.tag_name()!="styles") return false;
0538
0539 // look for aliases :
0540 {looper _for(a_tree);
0541 while(element* _elem = _for.next_element()) {
0542
0543 std::string name;
0544 _elem->attribute_value("name",name);
0545 if(name.empty()) {
0546 a_styles.out() << "tools::sg::gui_viewer::load_style :"
0547 << " <alias> without name."
0548 << std::endl;
0549 continue;
0550 }
0551 add<std::string,std::string>(a_styles.aliases(),name,_elem->value());
0552 }}
0553
0554 // scan children :
0555 {looper _for(a_tree);
0556 while(tree* _tree = _for.next_tree()) {
0557
0558 const std::string& tag = _tree->tag_name();
0559 if(tag=="style") {
0560 load_style(a_styles,*_tree);
0561 } else if(tag=="plotter_style") {
0562 load_plotter_style(a_styles,*_tree);
0563 }
0564
0565 }}
0566
0567 return true;
0568 }
0569 }}
0570
0571 #endif