1 /*! 2 @file 3 @author George Evmenov 4 @date 01/2010 5 */ 6 7 #include "Precompiled.h" 8 #include "CodeGenerator.h" 9 #include "EditorWidgets.h" 10 #include "UndoManager.h" 11 #include "Localise.h" 12 #include "SettingsManager.h" 13 14 namespace tools 15 { 16 17 // FIXME hardcoded template 18 const std::string TemplateName = "BaseLayoutCPP.xml"; 19 CodeGenerator()20 CodeGenerator::CodeGenerator() : 21 mOpenSaveFileDialog(nullptr) 22 { 23 initialiseByAttributes(this); 24 25 setDialogRoot(mMainWidget); 26 27 mOpenSaveFileDialog = new OpenSaveFileDialog(); 28 mOpenSaveFileDialog->Initialise(SettingsManager::getInstance().getValue("EditorState/OpenSaveFileDialogLayout")); 29 mOpenSaveFileDialog->setDialogInfo(replaceTags("CaptionOpenFolder"), replaceTags("ButtonOpenFolder"), true); 30 mOpenSaveFileDialog->eventEndDialog.connect(this, &CodeGenerator::notifyEndDialogOpenSaveFile); 31 32 mGenerateButton->eventMouseButtonClick += MyGUI::newDelegate(this, &CodeGenerator::notifyGeneratePressed); 33 mCancel->eventMouseButtonClick += MyGUI::newDelegate(this, &CodeGenerator::notifyCancel); 34 mBrowseHeader->eventMouseButtonClick += MyGUI::newDelegate(this, &CodeGenerator::notifyBrowseHeader); 35 mBrowseSource->eventMouseButtonClick += MyGUI::newDelegate(this, &CodeGenerator::notifyBrowseSource); 36 37 MyGUI::Window* window = mMainWidget->castType<MyGUI::Window>(false); 38 if (window != nullptr) 39 window->eventWindowButtonPressed += MyGUI::newDelegate(this, &CodeGenerator::notifyWindowButtonPressed); 40 41 MyGUI::ResourceManager::getInstance().registerLoadXmlDelegate("LECodeTemplate") = MyGUI::newDelegate(this, &CodeGenerator::parseTemplate); 42 MyGUI::ResourceManager::getInstance().load(TemplateName); 43 } 44 ~CodeGenerator()45 CodeGenerator::~CodeGenerator() 46 { 47 delete mOpenSaveFileDialog; 48 mOpenSaveFileDialog = nullptr; 49 } 50 parseTemplate(MyGUI::xml::ElementPtr _node,const std::string & _file,MyGUI::Version _version)51 void CodeGenerator::parseTemplate(MyGUI::xml::ElementPtr _node, const std::string& _file, MyGUI::Version _version) 52 { 53 mTemplateFiles.clear(); 54 mTemplateStrings.clear(); 55 56 MyGUI::xml::ElementEnumerator file = _node->getElementEnumerator(); 57 while (file.next("File")) 58 { 59 std::string templateFile = file->findAttribute("template"); 60 std::string outputFile = file->findAttribute("out_file"); 61 mTemplateFiles.insert(MyGUI::PairString(templateFile, outputFile)); 62 } 63 64 MyGUI::xml::ElementEnumerator string = _node->getElementEnumerator(); 65 while (string.next("String")) 66 { 67 std::string key = string->findAttribute("key"); 68 std::string value = string->findAttribute("value"); 69 mTemplateStrings.insert(MyGUI::PairString(key, value)); 70 } 71 } 72 stringToUpperCase(const std::string & _str)73 std::string CodeGenerator::stringToUpperCase(const std::string& _str) 74 { 75 // replace lower case sharacters with upper case characters and add '_' between words 76 // words is either Word or WORD, for example TestXMLPanelName return TEST_XML_PANEL_NAME 77 if (_str.empty()) return ""; 78 std::string ret; 79 bool previousIsLowerCase = false; 80 for (size_t i = 0; i < _str.length(); i++) 81 { 82 if ((i != 0) && 83 ( 84 (previousIsLowerCase && isupper(_str[i])) || 85 (isupper(_str[i]) && (i + 1 < _str.length()) && islower(_str[i+1])) 86 ) 87 ) 88 { 89 ret.push_back('_'); 90 } 91 ret.push_back((char)toupper(_str[i])); 92 previousIsLowerCase = (islower(_str[i]) != 0); 93 } 94 return ret; 95 } 96 printWidgetDeclaration(WidgetContainer * _container,std::ofstream & _stream)97 void CodeGenerator::printWidgetDeclaration(WidgetContainer* _container, std::ofstream& _stream) 98 { 99 if (!_container->getName().empty() && _container->getName() != "_Main") 100 { 101 MyGUI::LanguageManager& lm = MyGUI::LanguageManager::getInstance(); 102 lm.addUserTag("Widget_Name", _container->getName()); 103 lm.addUserTag("Widget_Type", _container->getType()); 104 for (MyGUI::MapString::iterator iterS = mTemplateStrings.begin(); iterS != mTemplateStrings.end(); ++iterS) 105 { 106 lm.addUserTag(iterS->first, lm.replaceTags(iterS->second)); 107 } 108 std::string declaration = lm.getTag("Widget_Declaration"); 109 while (declaration.find("\\n") != std::string::npos) 110 declaration.replace(declaration.find("\\n"), 2, "\n"); 111 _stream << declaration; 112 } 113 114 for (std::vector<WidgetContainer*>::iterator iter = _container->childContainers.begin(); iter != _container->childContainers.end(); ++iter) 115 { 116 printWidgetDeclaration(*iter, _stream); 117 } 118 } 119 notifyGeneratePressed(MyGUI::Widget * _sender)120 void CodeGenerator::notifyGeneratePressed(MyGUI::Widget* _sender) 121 { 122 MyGUI::LanguageManager& lm = MyGUI::LanguageManager::getInstance(); 123 std::string panelName = mPanelNameEdit->getOnlyText(); 124 std::string panelNamespace = mPanelNamespaceEdit->getOnlyText(); 125 std::string includeDirectory = mIncludeDirectoryEdit->getOnlyText(); 126 std::string sourceDirectory = mSourceDirectoryEdit->getOnlyText(); 127 128 if (panelName.empty() || mPanelNameEdit->getCaption() == ("#FF0000" + replaceTags("Error"))) 129 { 130 mPanelNameEdit->setCaption("#FF0000" + replaceTags("Error")); 131 return; 132 } 133 134 if (panelNamespace.empty() || mPanelNamespaceEdit->getCaption() == ("#FF0000" + replaceTags("Error"))) 135 { 136 mPanelNamespaceEdit->setCaption("#FF0000" + replaceTags("Error")); 137 return; 138 } 139 140 if (includeDirectory.empty()) includeDirectory = "."; 141 if (sourceDirectory.empty()) sourceDirectory = "."; 142 143 lm.addUserTag("Panel_Name", panelName); 144 lm.addUserTag("Panel_Namespace", panelNamespace); 145 lm.addUserTag("Layout_Name", MyGUI::LanguageManager::getInstance().getTag("ResourceName")); 146 lm.addUserTag("Include_Directory", includeDirectory); 147 lm.addUserTag("Source_Directory", sourceDirectory); 148 lm.addUserTag("Uppercase_Panel_Name", stringToUpperCase(panelName)); 149 150 for (MyGUI::MapString::iterator iter = mTemplateFiles.begin(); iter != mTemplateFiles.end(); ++iter) 151 { 152 std::ifstream input_file(MyGUI::DataManager::getInstance().getDataPath(iter->first).c_str()); 153 std::ofstream output_file(lm.replaceTags(iter->second).asUTF8_c_str()); 154 while (!input_file.eof() && !input_file.fail() && !output_file.fail()) 155 { 156 char str[256]; 157 input_file.getline(str, sizeof(str)); 158 if (strstr(str, "//%LE Widget_Declaration list start") != nullptr) 159 { 160 EnumeratorWidgetContainer widget = EditorWidgets::getInstance().getWidgets(); 161 while (widget.next()) 162 printWidgetDeclaration(widget.current(), output_file); 163 } 164 else 165 { 166 output_file << lm.replaceTags(str) << std::endl; 167 } 168 } 169 output_file.close(); 170 input_file.close(); 171 } 172 173 eventEndDialog(this, true); 174 } 175 onDoModal()176 void CodeGenerator::onDoModal() 177 { 178 MyGUI::IntSize windowSize = mMainWidget->getSize(); 179 MyGUI::IntSize parentSize = mMainWidget->getParentSize(); 180 181 mMainWidget->setPosition((parentSize.width - windowSize.width) / 2, (parentSize.height - windowSize.height) / 2); 182 } 183 onEndModal()184 void CodeGenerator::onEndModal() 185 { 186 } 187 notifyCancel(MyGUI::Widget * _sender)188 void CodeGenerator::notifyCancel(MyGUI::Widget* _sender) 189 { 190 eventEndDialog(this, false); 191 } 192 notifyWindowButtonPressed(MyGUI::Window * _sender,const std::string & _name)193 void CodeGenerator::notifyWindowButtonPressed(MyGUI::Window* _sender, const std::string& _name) 194 { 195 if (_name == "close") 196 eventEndDialog(this, false); 197 } 198 loadTemplate()199 void CodeGenerator::loadTemplate() 200 { 201 MyGUI::MapString& codeGeneratorSettings = EditorWidgets::getInstance().getCodeGeneratorSettings(); 202 mPanelNameEdit->setCaption(codeGeneratorSettings["PanelName"]); 203 mPanelNamespaceEdit->setCaption(codeGeneratorSettings["PanelNamespace"]); 204 mIncludeDirectoryEdit->setCaption(codeGeneratorSettings["IncludeDirectory"]); 205 mSourceDirectoryEdit->setCaption(codeGeneratorSettings["SourceDirectory"]); 206 } 207 saveTemplate()208 void CodeGenerator::saveTemplate() 209 { 210 MyGUI::MapString& codeGeneratorSettings = EditorWidgets::getInstance().getCodeGeneratorSettings(); 211 codeGeneratorSettings["PanelName"] = mPanelNameEdit->getOnlyText(); 212 codeGeneratorSettings["PanelNamespace"] = mPanelNamespaceEdit->getOnlyText(); 213 codeGeneratorSettings["IncludeDirectory"] = mIncludeDirectoryEdit->getOnlyText(); 214 codeGeneratorSettings["SourceDirectory"] = mSourceDirectoryEdit->getOnlyText(); 215 216 UndoManager::getInstance().setUnsaved(true); 217 } 218 notifyBrowseHeader(MyGUI::Widget * _sender)219 void CodeGenerator::notifyBrowseHeader(MyGUI::Widget* _sender) 220 { 221 mOpenSaveFileDialog->setCurrentFolder(mIncludeDirectoryEdit->getOnlyText()); 222 mOpenSaveFileDialog->setMode("Header"); 223 mOpenSaveFileDialog->doModal(); 224 } 225 notifyBrowseSource(MyGUI::Widget * _sender)226 void CodeGenerator::notifyBrowseSource(MyGUI::Widget* _sender) 227 { 228 mOpenSaveFileDialog->setCurrentFolder(mSourceDirectoryEdit->getOnlyText()); 229 mOpenSaveFileDialog->setMode("Source"); 230 mOpenSaveFileDialog->doModal(); 231 } 232 notifyEndDialogOpenSaveFile(Dialog * _sender,bool _result)233 void CodeGenerator::notifyEndDialogOpenSaveFile(Dialog* _sender, bool _result) 234 { 235 if (_result) 236 { 237 if (mOpenSaveFileDialog->getMode() == "Header") 238 { 239 mIncludeDirectoryEdit->setCaption(mOpenSaveFileDialog->getCurrentFolder()); 240 } 241 else if (mOpenSaveFileDialog->getMode() == "Source") 242 { 243 mSourceDirectoryEdit->setCaption(mOpenSaveFileDialog->getCurrentFolder()); 244 } 245 } 246 247 mOpenSaveFileDialog->endModal(); 248 } 249 250 } 251