00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026 #include "CEGUIGUILayout_xmlHandler.h"
00027 #include "CEGUIExceptions.h"
00028 #include "CEGUISystem.h"
00029 #include "CEGUIXmlHandlerHelper.h"
00030 #include "CEGUIScriptModule.h"
00031
00032 #include "xercesc/sax2/SAX2XMLReader.hpp"
00033 #include "xercesc/sax2/XMLReaderFactory.hpp"
00034
00035
00036
00037 namespace CEGUI
00038 {
00039
00040
00041
00042 const String GUILayout_xmlHandler::GUILayoutElement( (utf8*)"GUILayout" );
00043 const String GUILayout_xmlHandler::WindowElement( (utf8*)"Window" );
00044 const String GUILayout_xmlHandler::PropertyElement( (utf8*)"Property" );
00045 const String GUILayout_xmlHandler::LayoutImportElement( (utf8*)"LayoutImport" );
00046 const String GUILayout_xmlHandler::EventElement( (utf8*)"Event" );
00047 const char GUILayout_xmlHandler::WindowTypeAttribute[] = "Type";
00048 const char GUILayout_xmlHandler::WindowNameAttribute[] = "Name";
00049 const char GUILayout_xmlHandler::PropertyNameAttribute[] = "Name";
00050 const char GUILayout_xmlHandler::PropertyValueAttribute[] = "Value";
00051 const char GUILayout_xmlHandler::LayoutParentAttribute[] = "Parent";
00052 const char GUILayout_xmlHandler::LayoutImportFilenameAttribute[] = "Filename";
00053 const char GUILayout_xmlHandler::LayoutImportPrefixAttribute[] = "Prefix";
00054 const char GUILayout_xmlHandler::LayoutImportResourceGroupAttribute[] = "ResourceGroup";
00055 const char GUILayout_xmlHandler::EventNameAttribute[] = "Name";
00056 const char GUILayout_xmlHandler::EventFunctionAttribute[] = "Function";
00057
00058
00059 void GUILayout_xmlHandler::startElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname, const XERCES_CPP_NAMESPACE::Attributes& attrs)
00060 {
00061 XERCES_CPP_NAMESPACE_USE
00062 String element(XmlHandlerHelper::transcodeXmlCharToString(localname));
00063
00064
00065 if (element == GUILayoutElement)
00066 {
00067 d_layoutParent = XmlHandlerHelper::getAttributeValueAsString(attrs, LayoutParentAttribute);
00068
00069
00070 if (!d_layoutParent.empty())
00071 {
00072 if (!WindowManager::getSingleton().isWindowPresent(d_layoutParent))
00073 {
00074
00075 throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since the specified parent Window ('" + d_layoutParent + "') does not exist.");
00076 }
00077
00078 }
00079
00080 }
00081
00082 else if (element == WindowElement)
00083 {
00084
00085 String windowType(XmlHandlerHelper::getAttributeValueAsString(attrs, WindowTypeAttribute));
00086
00087
00088 String windowName(XmlHandlerHelper::getAttributeValueAsString(attrs, WindowNameAttribute));
00089
00090
00091 try
00092 {
00093 Window* wnd = WindowManager::getSingleton().createWindow(windowType, d_namingPrefix + windowName);
00094
00095
00096 if (!d_stack.empty())
00097 {
00098 d_stack.back()->addChildWindow(wnd);
00099 }
00100 else
00101 {
00102 d_root = wnd;
00103 }
00104
00105
00106 d_stack.push_back(wnd);
00107 }
00108 catch (AlreadyExistsException exc)
00109 {
00110
00111 cleanupLoadedWindows();
00112
00113
00114 throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since Window named '" + windowName + "' already exists.");
00115 }
00116 catch (UnknownObjectException exc)
00117 {
00118
00119 cleanupLoadedWindows();
00120
00121
00122 throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since no WindowFactory is available for '" + windowType + "' objects.");
00123 }
00124
00125 }
00126
00127 else if (element == PropertyElement)
00128 {
00129
00130 String propertyName(XmlHandlerHelper::getAttributeValueAsString(attrs, PropertyNameAttribute));
00131
00132
00133 String propertyValue(XmlHandlerHelper::getAttributeValueAsString(attrs, PropertyValueAttribute));
00134
00135
00136 try
00137 {
00138 if (!d_stack.empty())
00139 {
00140 Window* curwindow = d_stack.back();
00141 bool useit = true;
00142 if (NULL != d_propertyCallback)
00143 {
00144 useit = (*d_propertyCallback)(curwindow, propertyName, propertyValue, d_userData);
00145 }
00146 if (useit)
00147 {
00148 curwindow->setProperty(propertyName, propertyValue);
00149 }
00150 }
00151 }
00152 catch (Exception exc)
00153 {
00154
00155 }
00156
00157 }
00158
00159 else if (element == LayoutImportElement)
00160 {
00161 String prefixName(d_namingPrefix);
00162 prefixName += XmlHandlerHelper::getAttributeValueAsString(attrs, LayoutImportPrefixAttribute);
00163
00164 Window* subLayout = WindowManager::getSingleton().loadWindowLayout(
00165 XmlHandlerHelper::getAttributeValueAsString(attrs, LayoutImportFilenameAttribute),
00166 prefixName,
00167 XmlHandlerHelper::getAttributeValueAsString(attrs, LayoutImportResourceGroupAttribute),
00168 d_propertyCallback,
00169 d_userData);
00170
00171 if ((subLayout != NULL) && (!d_stack.empty()))
00172 {
00173 d_stack.back()->addChildWindow(subLayout);
00174 }
00175
00176 }
00177
00178 else if (element == EventElement)
00179 {
00180 String eventName(XmlHandlerHelper::getAttributeValueAsString(attrs, EventNameAttribute));
00181 String functionName(XmlHandlerHelper::getAttributeValueAsString(attrs, EventFunctionAttribute));
00182
00183
00184 try
00185 {
00186 if (!d_stack.empty())
00187 {
00188 d_stack.back()->subscribeEvent(eventName, ScriptFunctor(functionName));
00189 }
00190 }
00191 catch (Exception exc)
00192 {
00193
00194 }
00195
00196 }
00197
00198 else
00199 {
00200 throw FileIOException("GUILayout_xmlHandler::startElement - Unexpected data was found while parsing the gui-layout file: '" + element + "' is unknown.");
00201 }
00202
00203 }
00204
00205 void GUILayout_xmlHandler::endElement(const XMLCh* const uri, const XMLCh* const localname, const XMLCh* const qname)
00206 {
00207 XERCES_CPP_NAMESPACE_USE
00208 String element(XmlHandlerHelper::transcodeXmlCharToString(localname));
00209
00210
00211 if (element == GUILayoutElement)
00212 {
00213
00214 if (!d_layoutParent.empty() && (d_root != NULL))
00215 {
00216 WindowManager::getSingleton().getWindow(d_layoutParent)->addChildWindow(d_root);
00217 }
00218
00219 }
00220
00221 else if (element == WindowElement)
00222 {
00223
00224 if (!d_stack.empty())
00225 {
00226 d_stack.pop_back();
00227 }
00228
00229 }
00230
00231 }
00232
00233
00234 void GUILayout_xmlHandler::warning(const XERCES_CPP_NAMESPACE::SAXParseException &exc)
00235 {
00236 throw(exc);
00237 }
00238
00239 void GUILayout_xmlHandler::error(const XERCES_CPP_NAMESPACE::SAXParseException &exc)
00240 {
00241 throw(exc);
00242 }
00243
00244 void GUILayout_xmlHandler::fatalError(const XERCES_CPP_NAMESPACE::SAXParseException &exc)
00245 {
00246 throw(exc);
00247 }
00248
00249
00250
00251
00252
00253 void GUILayout_xmlHandler::cleanupLoadedWindows(void)
00254 {
00255
00256
00257
00258 while (!d_stack.empty())
00259 {
00260 Window* wnd = d_stack.back();
00261
00262
00263 if (wnd->getParent() != NULL)
00264 {
00265 wnd->getParent()->removeChildWindow(wnd);
00266 }
00267
00268
00269 WindowManager::getSingleton().destroyWindow(wnd);
00270
00271
00272 d_stack.pop_back();
00273 }
00274
00275 d_root = NULL;
00276 }
00277
00278
00279
00280
00281
00282 Window* GUILayout_xmlHandler::getLayoutRootWindow(void) const
00283 {
00284 return d_root;
00285 }
00286
00287 }