bool ReadBool (const char *propName, bool &result, xmlNodePtr xmlNode, const char *filename, CLigoConfig &config) { string str; if (CIXml::getPropertyString (str, xmlNode, propName)) { if (str == "true") result = true; else if (str == "false") result = false; else { config.syntaxError (filename, xmlNode, "Unknown (%s) parameter (%s), should be false or true", propName, str.c_str ()); return false; } return true; } return false; }
bool CPrimitiveClass::read (xmlNodePtr primitiveNode, const char *filename, const char *className, std::set<std::string> &contextStrings, std::map<std::string, std::string> &contextFilesLookup, CLigoConfig &config, bool parsePrimitiveComboContent) { // init default parameters AutoInit = false; Deletable = true; FileExtension = ""; FileType = ""; Collision = false; LinkBrothers = false; ShowArrow = true; Numberize = true; Visible = true; // read parent class properties string parentClass; if (CIXml::getPropertyString (parentClass, primitiveNode, "PARENT_CLASS")) { const CPrimitiveClass *parent = config.getPrimitiveClass(parentClass.c_str()); if (parent == NULL) { config.syntaxError (filename, primitiveNode, "Can't find parent class (%s) for class (%s)", parentClass.c_str (), className); return false; } // copy all the properties *this = *parent; } // The name Name = className; // Read the type std::string type; if (!config.getPropertyString (type, filename, primitiveNode, "TYPE")) goto failed; // Good type ? if (type == "node") Type = Node; else if (type == "point") Type = Point; else if (type == "path") Type = Path; else if (type == "zone") Type = Zone; else if (type == "bitmap") Type = Bitmap; else if (type == "alias") Type = Alias; else { config.syntaxError (filename, primitiveNode, "Unknown primitive type (%s)", type.c_str ()); goto failed; } // Read the color ReadColor (Color, primitiveNode); // Autoinit ReadBool ("AUTO_INIT", AutoInit, primitiveNode, filename, config); // Deletable ReadBool ("DELETABLE", Deletable, primitiveNode, filename, config); // File extension CIXml::getPropertyString (FileExtension, primitiveNode, "FILE_EXTENSION"); // File type CIXml::getPropertyString (FileType, primitiveNode, "FILE_TYPE"); // Collision ReadBool ("COLLISION", Collision, primitiveNode, filename, config); // LinkBrothers ReadBool ("LINK_BROTHERS", LinkBrothers, primitiveNode, filename, config); // ShowArrow ReadBool ("SHOW_ARROW", ShowArrow, primitiveNode, filename, config); // Numberize when copy the primitive ReadBool ("NUMBERIZE", Numberize, primitiveNode, filename, config); // Visible ? ReadBool ("VISIBLE", Visible, primitiveNode, filename, config); // Read the parameters for ( xmlNodePtr paramNode = CIXml::getFirstChildNode (primitiveNode, "PARAMETER"); paramNode != NULL; paramNode = CIXml::getNextChildNode (paramNode, "PARAMETER")) { // Read the property name if (!config.getPropertyString (type, filename, paramNode, "NAME")) goto failed; // look if the parameter is not already defined by the parent class uint i=0; while (i<Parameters.size()) { if (Parameters[i].Name == type) { // the param already exist, remove parent param Parameters.erase(Parameters.begin() + i); continue; } ++i; } // Add a parameter Parameters.push_back (CParameter ()); // The parameter ref CParameter ¶meter = Parameters.back (); // Set the name parameter.Name = type; // Read the type if (!config.getPropertyString (type, filename, paramNode, "TYPE")) goto failed; // Good type ? if (type == "boolean") parameter.Type = CParameter::Boolean; else if (type == "const_string") parameter.Type = CParameter::ConstString; else if (type == "string") parameter.Type = CParameter::String; else if (type == "string_array") parameter.Type = CParameter::StringArray; else if (type == "const_string_array") parameter.Type = CParameter::ConstStringArray; else { config.syntaxError (filename, paramNode, "Unknown primitive parameter type (%s)", type.c_str ()); goto failed; } // Visible parameter.Visible = true; ReadBool ("VISIBLE", parameter.Visible, paramNode, filename, config); // Filename parameter.Filename = false; ReadBool ("FILENAME", parameter.Filename, paramNode, filename, config); // Lookup parameter.Lookup = false; ReadBool ("LOOKUP", parameter.Lookup, paramNode, filename, config); // Read only primitive parameter.ReadOnly = false; ReadBool ("READ_ONLY", parameter.ReadOnly, paramNode, filename, config); // Deletable parameter.Editable = false; ReadBool ("EDITABLE", parameter.Editable, paramNode, filename, config); // sort combo box entries parameter.SortEntries = false; ReadBool ("SORT_ENTRIES", parameter.SortEntries, paramNode, filename, config); // Display horizontal scroller in multi-line edit box parameter.DisplayHS = false; ReadBool ("SHOW_HS", parameter.DisplayHS, paramNode, filename, config); // Lookup parameter.WidgetHeight = 100; int temp; if (ReadInt ("WIDGET_HEIGHT", temp, paramNode)) parameter.WidgetHeight = (uint)temp; // Read the file extension parameter.FileExtension = ""; CIXml::getPropertyString (parameter.FileExtension, paramNode, "FILE_EXTENSION"); parameter.FileExtension = toLower(parameter.FileExtension); // Autonaming preference parameter.Autoname = ""; CIXml::getPropertyString (parameter.Autoname, paramNode, "AUTONAME"); // Read the file extension parameter.Folder = ""; CIXml::getPropertyString (parameter.Folder, paramNode, "FOLDER"); parameter.Folder = toLower(parameter.Folder); // Read the combo values for ( xmlNodePtr comboValueNode = CIXml::getFirstChildNode (paramNode, "COMBO_VALUES"); comboValueNode != NULL; comboValueNode = CIXml::getNextChildNode (comboValueNode, "COMBO_VALUES")) { // Read the context if (!config.getPropertyString (type, filename, comboValueNode, "CONTEXT_NAME")) goto failed; // Add this context contextStrings.insert (type); // Add a combo value pair<std::map<std::string, CParameter::CConstStringValue>::iterator, bool> insertResult = parameter.ComboValues.insert (std::map<std::string, CParameter::CConstStringValue>::value_type (type, CParameter::CConstStringValue ())); // The combo value ref CParameter::CConstStringValue &comboValue = insertResult.first->second; // Read the values for ( xmlNodePtr comboValueValueNode = CIXml::getFirstChildNode (comboValueNode, "CONTEXT_VALUE"); comboValueValueNode != NULL; comboValueValueNode = CIXml::getNextChildNode (comboValueValueNode, "CONTEXT_VALUE")) { // Read the value if (!config.getPropertyString (type, filename, comboValueValueNode, "VALUE")) goto failed; comboValue.Values.push_back (type); } } // Read the combo files for ( xmlNodePtr comboValueNode = CIXml::getFirstChildNode (paramNode, "COMBO_FILES"); comboValueNode != NULL; comboValueNode = CIXml::getNextChildNode (comboValueNode, "COMBO_FILES")) { // Read the context if (!config.getPropertyString (type, filename, comboValueNode, "CONTEXT_NAME")) goto failed; // Read the path to search string path; if (CIXml::getPropertyString (path, comboValueNode, "PATH")) { if (!parsePrimitiveComboContent) continue; // Look for files in the path std::vector<std::string> files; CPath::getPathContent (path, true, false, true, files); // Not empty ? if (files.empty ()) continue; // Add this context contextStrings.insert (type); // For each file for (uint i=0; i<files.size (); i++) { // Good extension ? if (toLower(NLMISC::CFile::getExtension (files[i])) != parameter.FileExtension) continue; // Add a combo value pair<std::map<std::string, CParameter::CConstStringValue>::iterator, bool> insertResult = parameter.ComboValues.insert (std::map<std::string, CParameter::CConstStringValue>::value_type (type, CParameter::CConstStringValue ())); // The combo value ref CParameter::CConstStringValue &comboValue = insertResult.first->second; // Get the filename without extension string nameWithoutExt = toLower(NLMISC::CFile::getFilenameWithoutExtension (files[i])); // Add the values comboValue.Values.push_back (nameWithoutExt); // Add the value for lookup contextFilesLookup.insert (map<string, string>::value_type (nameWithoutExt, files[i])); } } else { string primpath; if (!config.getPropertyString (primpath, filename, comboValueNode, "PRIM_PATH")) goto failed; // Add this context contextStrings.insert (type); // Add a combo value pair<std::map<std::string, CParameter::CConstStringValue>::iterator, bool> insertResult = parameter.ComboValues.insert (std::map<std::string, CParameter::CConstStringValue>::value_type (type, CParameter::CConstStringValue ())); // The combo value ref CParameter::CConstStringValue &comboValue = insertResult.first->second; comboValue.PrimitivePath.push_back(primpath); } } // Read parameters default values uint defaultId = 0; parameter.DefaultValue.resize (CIXml::countChildren (paramNode, "DEFAULT_VALUE")); for ( xmlNodePtr defaultValueNode = CIXml::getFirstChildNode (paramNode, "DEFAULT_VALUE"); defaultValueNode != NULL; defaultValueNode = CIXml::getNextChildNode (defaultValueNode, "DEFAULT_VALUE")) { // Gen id flag parameter.DefaultValue[defaultId].GenID = false; // Read the gen id flag string value; if (CIXml::getPropertyString (value, defaultValueNode, "GEN_ID") && (value != "false")) { parameter.DefaultValue[defaultId].GenID = true; } else { if (!config.getPropertyString (value, filename, defaultValueNode, "VALUE")) goto failed; parameter.DefaultValue[defaultId].Name = value; } defaultId++; } } // Read static children StaticChildren.reserve (StaticChildren.size() + CIXml::countChildren (primitiveNode, "STATIC_CHILD")); for ( xmlNodePtr childrenNode = CIXml::getFirstChildNode (primitiveNode, "STATIC_CHILD"); childrenNode != NULL; childrenNode = CIXml::getNextChildNode (childrenNode, "STATIC_CHILD")) { // Add a static child StaticChildren.push_back (CChild ()); // Child ref CChild &child = StaticChildren.back (); // Read the child if (!ReadChild (child, childrenNode, filename, true, config)) goto failed; } // Read dynamic children DynamicChildren.reserve (DynamicChildren.size() + CIXml::countChildren (primitiveNode, "DYNAMIC_CHILD")); for ( xmlNodePtr childrenNode = CIXml::getFirstChildNode (primitiveNode, "DYNAMIC_CHILD"); childrenNode != NULL; childrenNode = CIXml::getNextChildNode (childrenNode, "DYNAMIC_CHILD")) { // Add a static child DynamicChildren.push_back (CChild ()); // Child ref CChild &child = DynamicChildren.back (); // Read the child if (!ReadChild (child, childrenNode, filename, false, config)) goto failed; } // Read generated children GeneratedChildren.reserve (GeneratedChildren.size() + CIXml::countChildren (primitiveNode, "GENERATED_CHILD")); for ( xmlNodePtr childrenNode = CIXml::getFirstChildNode (primitiveNode, "GENERATED_CHILD"); childrenNode != NULL; childrenNode = CIXml::getNextChildNode (childrenNode, "GENERATED_CHILD")) { // Add a static child GeneratedChildren.push_back (CChild ()); // Child ref CChild &child = GeneratedChildren.back (); // Read the child if (!ReadChild (child, childrenNode, filename, false, config)) goto failed; } return true; failed: return false; }