Back to home page

EIC code displayed by LXR

 
 

    


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