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