GUI.cpp

00001 #include "GUI.h"
00002 
00003 #include "WidgetCreator.h"
00004 
00005 #include "utils.h"
00006 
00007 #include <fstream>
00008 #include <stack>
00009 #include <sstream>
00010 
00011 namespace xfltk {
00012 
00013 struct ParserInfo {
00014         
00015         GUI& gui;
00016         
00017         XML_Parser& parser;
00018         
00019         std::stack<WidgetCreator*> creators_stack;
00020         
00024         unsigned errors_len;
00025         
00026         unsigned skip_tag;
00027         
00028         ParserInfo(GUI& gui, XML_Parser& parser): gui(gui), parser(parser), errors_len(0u), skip_tag(0u) {};
00029         
00033         bool tag_begin() {
00034                 if (skip_tag == 0u) return true;
00035                 ++skip_tag;
00036                 return false;
00037         };
00038         
00042         bool tag_end() {
00043                 if (skip_tag != 0u) {
00044                         --skip_tag;
00045                         return false;
00046                 }
00047                 return true;
00048         };
00049         
00053         void tag_skip() {
00054                 ++skip_tag;
00055         };
00056         
00057 };
00058 
00059 void XMLCALL
00060 startElement(void *userData, const char *name, const char **atts) {
00061         ParserInfo* p = (ParserInfo*)userData;
00062         if (!p->tag_begin()) return;
00063         WidgetCreator* wc = WidgetFactory::getCreator(name, p->gui);
00064         if (!wc) {      //error creating tag
00065                 p->gui.errors.append(new InvalidTagError(name, XML_GetCurrentLineNumber(p->parser), Error::skip_tag));
00066                 p->tag_skip();
00067                 return;
00068         }
00069         const char* id = utils::find_pair(atts, "id");
00070         p->creators_stack.push(wc);
00071         fltk::Widget* w = wc->create_begin(atts);
00072         if (!p->gui.root())
00073                 p->gui._root = w;
00074         if (id)
00075                 p->gui.setWidget(utils::strcopy(id), w);
00076 }
00077 
00078 static void XMLCALL
00079 endElement(void *userData, const char *name) {
00080         ParserInfo* p = (ParserInfo*)userData;
00081         if (!p->tag_end()) return;
00082         p->creators_stack.top()->create_end();
00083         delete p->creators_stack.top();
00084         p->creators_stack.pop();
00085 }
00086 
00087 GUI::GUI(std::istream& in_stream): _root(0) {
00088         in_stream >> *this;
00089 }
00090 
00091 GUI::GUI(const char* file_name): _root(0) {
00092         readFromFile(file_name);
00093 }
00094 
00095 void GUI::clear() {
00096         for (widget_map_type::iterator i = widget_map.begin(); i != widget_map.end(); ++i)
00097                 delete[] i->first;
00098         widget_map.clear();
00099         delete _root;
00100         _root = 0;
00101 }
00102 
00103 GUI::~GUI() {
00104         clear();
00105 }
00106 
00107 fltk::Widget* GUI::operator[](const char* name) {
00108         widget_map_type::iterator res = widget_map.find(name);
00109         return (res == widget_map.end()) ? 0 : res->second;
00110 }
00111 
00112 std::istream& operator>>(std::istream& in_stream, GUI& g) {
00113         g.clear();
00114         g.errors.clear();
00115 //      std::stack<WidgetCreator*> creators_stack;
00116 //      std::pair<GUI*, std::stack<WidgetCreator*>*> p(&g, &creators_stack);
00117         XML_Parser parser = XML_ParserCreate(NULL);
00118         ParserInfo parser_info(g, parser);
00119 
00120         void *buff = XML_GetBuffer(parser, BUFSIZ);
00121         if (buff == NULL) {
00122         /* TODO handle error */
00123         }       
00124         int done;
00125         XML_SetUserData(parser, &parser_info);
00126         XML_SetElementHandler(parser, startElement, endElement);
00127         
00128         do {
00129         size_t len = in_stream.read((char*)buff, BUFSIZ).gcount();
00130         
00131         done = len < sizeof(buff);
00132         if (XML_ParseBuffer(parser, len, done) == XML_STATUS_ERROR) {
00133                 g.errors.append(
00134                    new GeneralStaticError( XML_ErrorString(XML_GetErrorCode(parser)),
00135                                                                    XML_GetCurrentLineNumber(parser), Error::skip_all)
00136                 );
00137                 return in_stream;
00138                 }
00139         } while (!done);
00140         
00141         XML_ParserFree(parser);
00142         return in_stream;
00143 }
00144 
00145 void GUI::readFromFile(const char* file_name) {
00146         std::ifstream file(file_name);
00147         /*if (!file.is_open()) {
00148                 errors.clear();
00149                 errors.append();
00150         }*/
00151         file >> *this;
00152 }
00153 
00154 } //namespace xfltk

Generated on Tue Jan 3 14:32:36 2006 for xfltk by  doxygen 1.4.6-NO