Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

CEGUIGUILayout_xmlHandler.cpp

Go to the documentation of this file.
00001 /************************************************************************
00002         filename:       CEGUIGUILayout_xmlHandler.cpp
00003         created:        5/7/2004
00004         author:         Paul D Turner
00005         
00006         purpose:        Implements XML parser for GUILayout files
00007 *************************************************************************/
00008 /*************************************************************************
00009     Crazy Eddie's GUI System (http://www.cegui.org.uk)
00010     Copyright (C)2004 - 2005 Paul D Turner (paul@cegui.org.uk)
00011 
00012     This library is free software; you can redistribute it and/or
00013     modify it under the terms of the GNU Lesser General Public
00014     License as published by the Free Software Foundation; either
00015     version 2.1 of the License, or (at your option) any later version.
00016 
00017     This library is distributed in the hope that it will be useful,
00018     but WITHOUT ANY WARRANTY; without even the implied warranty of
00019     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00020     Lesser General Public License for more details.
00021 
00022     You should have received a copy of the GNU Lesser General Public
00023     License along with this library; if not, write to the Free Software
00024     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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 // Start of CEGUI namespace section
00037 namespace CEGUI
00038 {
00039 /*************************************************************************
00040         Implementation Constants
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         // handle root GUILayoutElement element
00065         if (element == GUILayoutElement)
00066         {
00067                 d_layoutParent = XmlHandlerHelper::getAttributeValueAsString(attrs, LayoutParentAttribute);
00068 
00069                 // before we go to the trouble of creating the layout, see if this parent exists
00070                 if (!d_layoutParent.empty())
00071                 {
00072                         if (!WindowManager::getSingleton().isWindowPresent(d_layoutParent))
00073                         {
00074                                 // signal error - with more info about what we have done.
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         // handle Window element (create window and make an entry on our "window stack")
00082         else if (element == WindowElement)
00083         {
00084                 // get type of window to create
00085                 String windowType(XmlHandlerHelper::getAttributeValueAsString(attrs, WindowTypeAttribute));
00086 
00087                 // get name for new window
00088                 String windowName(XmlHandlerHelper::getAttributeValueAsString(attrs, WindowNameAttribute));
00089 
00090                 // attempt to create window
00091                 try
00092                 {
00093                         Window* wnd = WindowManager::getSingleton().createWindow(windowType, d_namingPrefix + windowName);
00094 
00095                         // add this window to the current parent (if any)
00096                         if (!d_stack.empty())
00097                         {
00098                                 d_stack.back()->addChildWindow(wnd);
00099                         }
00100                         else
00101                         {
00102                                 d_root = wnd;
00103                         }
00104 
00105                         // make this window the top of the stack
00106                         d_stack.push_back(wnd);
00107                 }
00108                 catch (AlreadyExistsException exc)
00109                 {
00110                         // delete all windows created
00111                         cleanupLoadedWindows();
00112 
00113                         // signal error - with more info about what we have done.
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                         // delete all windows created
00119                         cleanupLoadedWindows();
00120 
00121                         // signal error - with more info about what we have done.
00122                         throw InvalidRequestException((utf8*)"GUILayout_xmlHandler::startElement - layout loading has been aborted since no WindowFactory is available for '" + windowType + "' objects.");
00123                 }
00124 
00125         }
00126         // handle Property element (set property for window at top of stack)
00127         else if (element == PropertyElement)
00128         {
00129                 // get property name
00130                 String propertyName(XmlHandlerHelper::getAttributeValueAsString(attrs, PropertyNameAttribute));
00131 
00132                 // get property value string
00133                 String propertyValue(XmlHandlerHelper::getAttributeValueAsString(attrs, PropertyValueAttribute));
00134 
00135                 // attempt to set property on window
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                         // Don't do anything here, but the error will have been logged.
00155                 }
00156 
00157         }
00158         // handle layout import element (attach a layout to the window at the top of the stack)
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         // handle event subscription element
00178         else if (element == EventElement)
00179         {
00180                 String eventName(XmlHandlerHelper::getAttributeValueAsString(attrs, EventNameAttribute));
00181                 String functionName(XmlHandlerHelper::getAttributeValueAsString(attrs, EventFunctionAttribute));
00182 
00183                 // attempt to subscribe property on window
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                         // Don't do anything here, but the error will have been logged.
00194                 }
00195 
00196         }
00197         // anything else is an error which *should* have already been caught by XML validation
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         // handle root GUILayoutElement element
00211         if (element == GUILayoutElement)
00212         {
00213                 // attach to named parent if needed
00214                 if (!d_layoutParent.empty() && (d_root != NULL))
00215                 {
00216                         WindowManager::getSingleton().getWindow(d_layoutParent)->addChildWindow(d_root);
00217                 }
00218 
00219         }
00220         // handle Window element
00221         else if (element == WindowElement)
00222         {
00223                 // pop a window from the window stack
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         Destroy all windows created so far.     
00252 *************************************************************************/
00253 void GUILayout_xmlHandler::cleanupLoadedWindows(void)
00254 {
00255         // Notes: We could just destroy the root window of the layout, which normally would also destroy
00256         // all attached windows.  Since the client may have specified that certain windows are not auto-destroyed
00257         // we can't rely on this, so we work backwards detaching and deleting windows instead.
00258         while (!d_stack.empty())
00259         {
00260                 Window* wnd = d_stack.back();
00261 
00262                 // detach from parent
00263                 if (wnd->getParent() != NULL)
00264                 {
00265                         wnd->getParent()->removeChildWindow(wnd);
00266                 }
00267 
00268                 // destroy the window
00269                 WindowManager::getSingleton().destroyWindow(wnd);
00270 
00271                 // pop window from stack
00272                 d_stack.pop_back();
00273         }
00274 
00275         d_root = NULL;
00276 }
00277 
00278 
00279 /*************************************************************************
00280         Return a pointer to the 'root' window created.
00281 *************************************************************************/
00282 Window* GUILayout_xmlHandler::getLayoutRootWindow(void) const
00283 {
00284         return d_root;
00285 }
00286 
00287 } // End of  CEGUI namespace section

Generated on Wed Feb 16 12:41:06 2005 for Crazy Eddies GUI System by  doxygen 1.3.9.1