/* EntryType::loadEntryTypes * Loads all built-in and custom user entry types *******************************************************************/ bool EntryType::loadEntryTypes() { EntryDataFormat* fmt_any = EntryDataFormat::anyFormat(); // Setup unknown type etype_unknown.format = fmt_any; etype_unknown.icon = "e_unknown"; etype_unknown.detectable = false; etype_unknown.reliability = 0; etype_unknown.addToList(); // Setup folder type etype_folder.format = fmt_any; etype_folder.icon = "e_folder"; etype_folder.name = "Folder"; etype_folder.detectable = false; etype_folder.addToList(); // Setup marker type etype_marker.format = fmt_any; etype_marker.icon = "e_marker"; etype_marker.name = "Marker"; etype_marker.detectable = false; etype_marker.category = ""; // No category, markers only appear when 'All' categories shown etype_marker.addToList(); // Setup map marker type etype_map.format = fmt_any; etype_map.icon = "e_map"; etype_map.name = "Map Marker"; etype_map.category = "Maps"; // Should appear with maps etype_map.detectable = false; etype_map.colour = rgba_t(0, 255, 0); etype_map.addToList(); // -------- READ BUILT-IN TYPES --------- // Get builtin entry types from resource archive Archive* res_archive = theArchiveManager->programResourceArchive(); // Check resource archive exists if (!res_archive) { wxLogMessage("Error: No resource archive open!"); return false; } // Get entry types directory ArchiveTreeNode* et_dir = res_archive->getDir("config/entry_types/"); // Check it exists if (!et_dir) { wxLogMessage("Error: config/entry_types does not exist in slade.pk3"); return false; } // Read in each file in the directory bool etypes_read = false; for (unsigned a = 0; a < et_dir->numEntries(); a++) { if (readEntryTypeDefinition(et_dir->getEntry(a)->getMCData())) etypes_read = true; } // Warn if no types were read (this shouldn't happen unless the resource archive is corrupted) if (!etypes_read) wxLogMessage("Warning: No built-in entry types could be loaded from slade.pk3"); // -------- READ CUSTOM TYPES --------- // If the directory doesn't exist create it if (!wxDirExists(appPath("entry_types", DIR_USER))) wxMkdir(appPath("entry_types", DIR_USER)); // Open the custom palettes directory wxDir res_dir; res_dir.Open(appPath("entry_types", DIR_USER)); // Go through each file in the directory string filename = wxEmptyString; bool files = res_dir.GetFirst(&filename, wxEmptyString, wxDIR_FILES); while (files) { // Load file data MemChunk mc; mc.importFile(res_dir.GetName() + "/" + filename); // Parse file readEntryTypeDefinition(mc); // Next file files = res_dir.GetNext(&filename); } return true; }
/* EntryType::readEntryTypeDefinition * Reads in a block of entry type definitions. Returns false if there * was a parsing error, true otherwise *******************************************************************/ bool EntryType::readEntryTypeDefinition(MemChunk& mc) { // Parse the definition Parser p; p.parseText(mc); // Get entry_types tree ParseTreeNode* pt_etypes = (ParseTreeNode*)(p.parseTreeRoot()->getChild("entry_types")); // Check it exists if (!pt_etypes) return false; // Go through all parsed types for (unsigned a = 0; a < pt_etypes->nChildren(); a++) { // Get child as ParseTreeNode ParseTreeNode* typenode = (ParseTreeNode*)pt_etypes->getChild(a); // Create new entry type EntryType* ntype = new EntryType(typenode->getName().Lower()); // Copy from existing type if inherited if (!typenode->getInherit().IsEmpty()) { EntryType* parent_type = EntryType::getType(typenode->getInherit().Lower()); if (parent_type != EntryType::unknownType()) parent_type->copyToType(ntype); else wxLogMessage("Warning: Entry type %s inherits from unknown type %s", CHR(ntype->getId()), CHR(typenode->getInherit())); } // Go through all parsed fields for (unsigned b = 0; b < typenode->nChildren(); b++) { // Get child as ParseTreeNode ParseTreeNode* fieldnode = (ParseTreeNode*)typenode->getChild(b); // Process it if (S_CMPNOCASE(fieldnode->getName(), "name")) // Name field { ntype->name = fieldnode->getStringValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "detectable")) // Detectable field { ntype->detectable = fieldnode->getBoolValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "export_ext")) // Export Extension field { ntype->extension = fieldnode->getStringValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "format")) // Format field { string format_string = fieldnode->getStringValue(); ntype->format = EntryDataFormat::getFormat(format_string); // Warn if undefined format if (ntype->format == EntryDataFormat::anyFormat()) wxLogMessage("Warning: Entry type %s requires undefined format %s", CHR(ntype->getId()), CHR(format_string)); } else if (S_CMPNOCASE(fieldnode->getName(), "icon")) // Icon field { ntype->icon = fieldnode->getStringValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "editor")) // Editor field (to be removed) { ntype->editor = fieldnode->getStringValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "section")) // Section field { ntype->section = fieldnode->getStringValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "match_ext")) // Match Extension field { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->match_extension.push_back(fieldnode->getStringValue(v).Lower()); } else if (S_CMPNOCASE(fieldnode->getName(), "match_name")) // Match Name field { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->match_name.push_back(fieldnode->getStringValue(v).Lower()); } else if (S_CMPNOCASE(fieldnode->getName(), "match_extorname")) // Match name or extension { ntype->matchextorname = fieldnode->getBoolValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "size")) // Size field { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->match_size.push_back(fieldnode->getIntValue(v)); } else if (S_CMPNOCASE(fieldnode->getName(), "min_size")) // Min Size field { ntype->size_limit[0] = fieldnode->getIntValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "max_size")) // Max Size field { ntype->size_limit[1] = fieldnode->getIntValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "size_multiple")) // Size Multiple field { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->size_multiple.push_back(fieldnode->getIntValue(v)); } else if (S_CMPNOCASE(fieldnode->getName(), "reliability")) // Reliability field { ntype->reliability = fieldnode->getIntValue(); } else if (S_CMPNOCASE(fieldnode->getName(), "match_archive")) // Archive field { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->match_archive.push_back(fieldnode->getStringValue(v).Lower()); } else if (S_CMPNOCASE(fieldnode->getName(), "extra")) // Extra properties { for (unsigned v = 0; v < fieldnode->nValues(); v++) ntype->extra.addFlag(fieldnode->getStringValue(v)); } else if (S_CMPNOCASE(fieldnode->getName(), "category")) // Type category { ntype->category = fieldnode->getStringValue(); // Add to category list if needed bool exists = false; for (unsigned b = 0; b < entry_categories.size(); b++) { if (S_CMPNOCASE(entry_categories[b], ntype->category)) { exists = true; break; } } if (!exists) entry_categories.push_back(ntype->category); } else if (S_CMPNOCASE(fieldnode->getName(), "image_format")) // Image format hint ntype->extra["image_format"] = fieldnode->getStringValue(0); else if (S_CMPNOCASE(fieldnode->getName(), "colour")) // Colour { if (fieldnode->nValues() >= 3) ntype->colour = rgba_t(fieldnode->getIntValue(0), fieldnode->getIntValue(1), fieldnode->getIntValue(2)); else wxLogMessage("Not enough colour components defined for entry type %s", CHR(ntype->getId())); } else { // Unhandled properties can go into 'extra', only their first value is kept ntype->extra[fieldnode->getName()] = fieldnode->getStringValue(); } } //ntype->dump(); ntype->addToList(); } return true; }