CE Editor IO.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /******************************************************************************/
  2. #include "stdafx.h"
  3. namespace EE{
  4. namespace Edit{
  5. /******************************************************************************/
  6. #define CC4_CDES CC4('C','D','E','S') // code editor symbols
  7. #define CDES_VER 3
  8. /******************************************************************************/
  9. // SYMBOLS
  10. /******************************************************************************/
  11. Bool CodeEditor::saveSymbols(C Str &file)
  12. {
  13. File f; if(f.writeTry(file))
  14. {
  15. f.putUInt (CC4_CDES);
  16. f.cmpUIntV(CDES_VER); // version
  17. Memc<Str> strings;
  18. FREPA(Symbols)strings.add(Symbols.lockedDesc(i).file()); // add symbols to strings
  19. FREPA(sources)strings.add(sources[i].loc.file_name ); // add sources to strings
  20. StrLibrary sl(strings, true, true); sl.save(f);
  21. f.putUInt(items .elms()); FREPAO(items ).save(f, sl);
  22. f.putUInt(Symbols .elms()); FREPA (Symbols )sl.putStr(f, Symbols.lockedDesc(i).file());
  23. f.putUInt(sources .elms()); FREPAO(sources ).save(f, sl);
  24. f.putUInt(EEUsings.elms()); FREPA (EEUsings)sl.putStr(f, EEUsings[i].name());
  25. f.putUInt(EEMacros.elms()); FREPAO(EEMacros).save(f, sl);
  26. if(f.flushOK())return true;
  27. f.del(); FDelFile(file);
  28. }
  29. return false;
  30. }
  31. /******************************************************************************/
  32. Bool CodeEditor::loadSymbols(C Str &file, Bool all)
  33. {
  34. File f; if(f.readTry(file))if(f.getUInt()==CC4_CDES)if(f.decUIntV()==CDES_VER) // version
  35. {
  36. StrLibrary sl; if(sl.load(f))
  37. {
  38. EEUsings.del();
  39. EEMacros.del();
  40. //sources .del(); don't delete sources because in the Editor we can preview sources before loading symbols
  41. items .del();
  42. REP(f.getUInt())items.New().load(f, sl);
  43. if(all)
  44. {
  45. Str temp;
  46. REP(f.getUInt()){sl.getStr(f, temp); Symbols(temp);} // create all symbols up-front in sorted order so they are created quickly (this speeds up loading time), ignore counted references because they won't be unloaded anyway, load this before sources
  47. REP(f.getUInt())sources .New().load(f, sl, temp);
  48. REP(f.getUInt())EEUsings.New().require(sl.getStr(f));
  49. REP(f.getUInt())EEMacros.New().load(f, sl, temp);
  50. }
  51. Time.skipUpdate(); // this can take some time
  52. return f.ok();
  53. }
  54. }
  55. return false;
  56. }
  57. /******************************************************************************/
  58. // SETTINGS
  59. /******************************************************************************/
  60. void CodeEditor::saveSettings(TextNode &code)
  61. {
  62. TextNode &paths=code.nodes.New().setName("Paths");
  63. paths.nodes.New().set("VisualStudio" , vs_path);
  64. paths.nodes.New().set("NetBeans" , netbeans_path);
  65. paths.nodes.New().set("AndroidSDK" , android_sdk);
  66. paths.nodes.New().set("AndroidNDK" , android_ndk);
  67. paths.nodes.New().set("JavaDevelopmentKit", jdk_path);
  68. TextNode &certs=code.nodes.New().setName("Certificates");
  69. TextNode &win_cert=certs.nodes.New().setName("Windows");
  70. win_cert.nodes.New().set("Use", options.authenticode());
  71. TextNode &and_cert=certs.nodes.New().setName("Android");
  72. and_cert.nodes.New().set("File" , cert_file);
  73. and_cert.nodes.New().set("Password", cert_pass);
  74. TextNode &theme=code.nodes.New().setName("Theme");
  75. TextNode &font=theme.nodes.New().setName("Font");
  76. if(InRange(options.font_size(), options.font_sizes))font.nodes.New().set("Size", options.font_sizes[options.font_size()].size);
  77. options.font_editor.params.save(font.nodes.New().setName("Custom"));
  78. theme.nodes.New().set("Color", options.color_theme());
  79. ThemeCustom.save(theme.nodes.New().setName("Custom"));
  80. TextNode &view=code.nodes.New().setName("View");
  81. view.nodes.New().set("OpenedFiles", visibleOpenedFiles());
  82. TextNode &edit=code.nodes.New().setName("Edit");
  83. edit.nodes.New().set("AutocompleteOnEnterOnly", options.ac_on_enter ());
  84. edit.nodes.New().set("SimpleMode" , options.simple ());
  85. edit.nodes.New().set("ImmediateScroll" , options.imm_scroll ());
  86. edit.nodes.New().set("EndOfLineClip" , options.eol_clip ());
  87. edit.nodes.New().set("ShowLineNumbers" , options.line_numbers ());
  88. edit.nodes.New().set("HideHorizontalSlidebar" , options.hide_horizontal_slidebar());
  89. edit.nodes.New().set("AutoHideMenuBar" , options.auto_hide_menu ());
  90. edit.nodes.New().set("ExportPathMode" , options.export_path_mode ());
  91. TextNode &conf=code.nodes.New().setName("Configuration");
  92. conf.nodes.New().set("Debug", config_debug );
  93. conf.nodes.New().set("32Bit", config_32_bit);
  94. conf.nodes.New().set("DX9" , config_dx9 );
  95. conf.nodes.New().set("EXE" , (config_exe==EXE_EXE) ? "exe" : (config_exe==EXE_DLL) ? "dll" : (config_exe==EXE_LIB) ? "lib" : (config_exe==EXE_NEW) ? "new" : (config_exe==EXE_APK) ? "apk" : (config_exe==EXE_MAC) ? "mac" : (config_exe==EXE_IOS) ? "ios" : (config_exe==EXE_LINUX) ? "linux" : (config_exe==EXE_WEB) ? "web" : "");
  96. TextNode &sugg=code.nodes.New().setName("SuggestionHistory");
  97. FREPA(Suggestions)sugg.nodes.New().value=Suggestions[i];
  98. TextNode &import=code.nodes.New().setName("Importing");
  99. import.nodes.New().set("AssetPathMode", options.import_path_mode ());
  100. import.nodes.New().set("ImageMipMaps" , options.import_image_mip_maps());
  101. }
  102. /******************************************************************************/
  103. void CodeEditor::loadSettings(C TextNode &code)
  104. {
  105. if(C TextNode *theme=code.findNode("Theme")) // load theme settings at start
  106. {
  107. if(C TextNode *font=theme->findNode("Font"))
  108. {
  109. if(C TextNode *p=font->findNode("Size")){Int size=p->asInt(); REPA(options.font_sizes)if(options.font_sizes[i].size==size){options.font_size.set(i); break;}}
  110. if(C TextNode *custom=font->findNode("Custom"))
  111. {
  112. options.font_editor.params.load(*custom);
  113. REPAO(options.font_editor.props).toGui();
  114. }
  115. }
  116. if(C TextNode *p=theme->findNode("Color"))options.color_theme.set(p->asInt());
  117. if(C TextNode *custom=theme->findNode("Custom"))
  118. {
  119. ThemeCustom.load(*custom);
  120. REPAO(options.color_theme_editor.props).toGui();
  121. }
  122. }
  123. if(C TextNode *edit=code.findNode("Edit")) // editing settings
  124. {
  125. if(C TextNode *p=edit->findNode("AutocompleteOnEnterOnly"))options.ac_on_enter .set(p->asBool());
  126. if(C TextNode *p=edit->findNode("SimpleMode" ))options.simple .set(p->asBool());
  127. if(C TextNode *p=edit->findNode("ImmediateScroll" ))options.imm_scroll .set(p->asBool());
  128. if(C TextNode *p=edit->findNode("EndOfLineClip" ))options.eol_clip .set(p->asBool());
  129. if(C TextNode *p=edit->findNode("ShowLineNumbers" ))options.line_numbers .set(p->asBool());
  130. if(C TextNode *p=edit->findNode("HideHorizontalSlidebar" ))options.hide_horizontal_slidebar.set(p->asBool());
  131. if(C TextNode *p=edit->findNode("AutoHideMenuBar" ))options.auto_hide_menu .set(p->asBool());
  132. if(C TextNode *p=edit->findNode("ExportPathMode" ))options.export_path_mode .set(p->asBool());
  133. }
  134. if(C TextNode *paths=code.findNode("Paths"))
  135. {
  136. if(C TextNode *p=paths->findNode("VisualStudio" ))setVSPath (p->value); // load VS path before loading project (and parsing 3rd party headers)
  137. if(C TextNode *p=paths->findNode("NetBeans" ))setNBPath (p->value);
  138. if(C TextNode *p=paths->findNode("AndroidSDK" ))setASPath (p->value);
  139. if(C TextNode *p=paths->findNode("AndroidNDK" ))setANPath (p->value);
  140. if(C TextNode *p=paths->findNode("JavaDevelopmentKit"))setJDKPath(p->value);
  141. }
  142. if(C TextNode *certificates=code.findNode("Certificates"))
  143. {
  144. if(C TextNode *windows=certificates->findNode("Windows"))
  145. {
  146. if(C TextNode *p=windows->findNode("Use"))options.authenticode.set(p->asBool());
  147. }
  148. if(C TextNode *android=certificates->findNode("Android"))
  149. {
  150. if(C TextNode *p=android->findNode("File" ))setCertPath(p->value);
  151. if(C TextNode *p=android->findNode("Password"))setCertPass(p->value);
  152. }
  153. }
  154. if(C TextNode *proj=code.findNode("View"))
  155. {
  156. if(C TextNode *p=proj->findNode("OpenedFiles"))visibleOpenedFiles(p->asBool());
  157. }
  158. if(C TextNode *conf=code.findNode("Configuration"))
  159. {
  160. if(C TextNode *p=conf->findNode("Debug"))configDebug(p->asBool());
  161. if(C TextNode *p=conf->findNode("32Bit"))config32Bit(p->asBool());
  162. if(C TextNode *p=conf->findNode("DX9" ))configDX9 (p->asBool());
  163. if(C TextNode *p=conf->findNode("EXE" ))
  164. {
  165. if(p->value=="exe" )configEXE(EXE_EXE );else
  166. if(p->value=="dll" )configEXE(EXE_DLL );else
  167. if(p->value=="lib" )configEXE(EXE_LIB );else
  168. if(p->value=="new" )configEXE(EXE_NEW );else
  169. if(p->value=="apk" )configEXE(EXE_APK );else
  170. if(p->value=="mac" )configEXE(EXE_MAC );else
  171. if(p->value=="ios" )configEXE(EXE_IOS );else
  172. if(p->value=="linux")configEXE(EXE_LINUX);else
  173. if(p->value=="web" || p->value=="html" || p->value=="js")configEXE(EXE_WEB);
  174. }
  175. }
  176. if(C TextNode *sugg=code.findNode("SuggestionHistory"))
  177. {
  178. Suggestions.clear();
  179. FREPA(sugg->nodes)Suggestions.add(sugg->nodes[i].value);
  180. }
  181. if(C TextNode *import=code.findNode("Importing"))
  182. {
  183. if(C TextNode *p=import->findNode("AssetPathMode"))options.import_path_mode .set(p->asBool());
  184. if(C TextNode *p=import->findNode("ImageMipMaps" ))options.import_image_mip_maps.set(p->asBool());
  185. }
  186. }
  187. /******************************************************************************/
  188. // SOURCES
  189. /******************************************************************************/
  190. static void LoadSource(C Str &name, CodeEditor &ce) {ce.load(name);}
  191. /******************************************************************************/
  192. Bool CodeEditor::load(C SourceLoc &loc, Bool quiet, Bool Const)
  193. {
  194. if(loc.is()) // if location is specified
  195. {
  196. if(loc.file && !TextExt(GetExt(loc.file_name)))return false; // skip files which are not text files
  197. ERROR_TYPE error; if(Source *s=getSource(loc, &error)){s->Const|=Const; cur(s); return true;}
  198. if(!quiet)
  199. {
  200. Str msg;
  201. switch(error)
  202. {
  203. case EE_ERR_ELM_NOT_FOUND : msg=S+"Element \""+loc.asText()+"\" was not found"; break;
  204. case EE_ERR_ELM_NOT_CODE : msg=S+"Element \""+loc.asText()+"\" is not a Code"; break;
  205. case EE_ERR_ELM_NOT_DOWNLOADED: msg=S+"Element \""+loc.asText()+"\" was not yet downloaded, please first:\n1. Upload Code using \"Synchronize Codes\" option on the source machine.\n2. Download Code using \"Synchronize Codes\" option on this machine."; break;
  206. case EE_ERR_FILE_NOT_FOUND : msg=S+"Element \""+loc.asText()+"\" file data was not found"; break;
  207. case EE_ERR_FILE_INVALID : msg=S+"Element \""+loc.asText()+"\" file data is invalid, you can try the following:\n-Update Esenthel Editor to a newer version\n-Use \"Synchronize Codes\" option to update your codes\n-Use a backup version of your project"; break;
  208. case EE_ERR_FILE_READ_ERROR : msg=S+"Element \""+loc.asText()+"\" file reading failed"; break;
  209. }
  210. Gui.msgBox(S, msg);
  211. }
  212. }
  213. return false;
  214. }
  215. /******************************************************************************/
  216. void CodeEditor::save(Source *source, C SourceLoc &loc)
  217. {
  218. if(source)
  219. {
  220. Bool header=source->header, used=source->used();
  221. if(Source *dest=findSource(loc)) // find destination source
  222. if(source!=dest) // if overwriting existing but different file
  223. {
  224. header|=dest->header;
  225. used |=dest->used();
  226. if(dest->opened){Gui.msgBox(S, "Destination file is currently being edited in another source and cannot be overwritten."); return;}
  227. sources.removeData(dest, true); // remove 'dest' source
  228. }
  229. Bool different=(source->loc!=loc);
  230. source->save(loc);
  231. if((different && used) || header)validateActiveSources(header); // if saved to different location and one of the files is used, or one of the files is a header then validate active sources
  232. }
  233. }
  234. /******************************************************************************/
  235. void CodeEditor::overwrite()
  236. {
  237. if(cur() && !cur()->Const)
  238. {
  239. if(cur()->loc.is())save(cur(), cur()->loc);
  240. else cur()->save();
  241. }
  242. }
  243. void CodeEditor::save() {if(cur())cur()->save();}
  244. void CodeEditor::load()
  245. {
  246. if(!load_source.is())load_source.create(S, S, S, LoadSource, LoadSource, T).ext(CODE_EXT, "source");
  247. load_source.load();
  248. }
  249. /******************************************************************************/
  250. }}
  251. /******************************************************************************/