9 import "OldIDESettings"
13 enum DirTypes { includes, libraries, executables };
15 define defaultCompilerName = "Default";
17 define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)";
19 char * settingsDirectoryNames[DirTypes] =
26 enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings };
28 char * CopyValidateMakefilePath(char * path)
30 const int map[] = { 0, 1, 2, 3, 4, 0, 1, 7 };
31 const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(PROJECT)", "$(CONFIGURATION)", (char *)0 };
38 copy = CopyString(path);
44 Array<char *> parts { };
51 for(v=0; vars[v]; v++)
53 if(SearchString(&tmp[c], 0, vars[v], false, false) == &tmp[c])
57 parts.Add(vars[map[v]]);
72 for(c=0; c<parts.count; c++) len += strlen(parts[c]);
73 copy = new char[++len];
75 for(c=0; c<parts.count; c++) strcat(copy, parts[c]);
86 CompilerConfig MakeDefaultCompiler(char * name, bool readOnly)
88 CompilerConfig defaultCompiler
103 incref defaultCompiler;
104 return defaultCompiler;
107 class IDESettingsContainer : GlobalSettings
110 settingsName = "ecereIDESettingsTest";
112 settingsName = "ecereIDE";
115 virtual void OnLoad(GlobalSettingsData data);
118 IDESettingsContainer()
120 char path[MAX_LOCATION];
122 LocateModule(null, path);
123 // PortableApps.com directory structure
124 if((start = strstr(path, "\\App\\EcereSDK\\bin\\ide.exe")))
126 char configFilePath[MAX_LOCATION];
127 char defaultConfigFilePath[MAX_LOCATION];
131 strcpy(configFilePath, path);
132 PathCat(configFilePath, "Data");
133 PathCat(configFilePath, "ecereIDE.ini");
135 strcpy(defaultConfigFilePath, path);
136 PathCat(defaultConfigFilePath, "App");
137 PathCat(defaultConfigFilePath, "DefaultData");
138 PathCat(defaultConfigFilePath, "ecereIDE.ini");
140 if(FileExists(defaultConfigFilePath))
142 if(!FileExists(configFilePath))
144 File f = FileOpen(defaultConfigFilePath, read);
145 f.CopyTo(configFilePath);
149 PathCat(path, "Data");
150 // the forced settings location will only be
151 // used if the running ide's path matches
152 // the PortableApps.com directory structure
153 // and the default ini file is found in
154 // the DefaultData directory
155 settingsLocation = path;
161 void OnAskReloadSettings()
163 /*if(MessageBox { type = YesNo, master = this,
164 text = "Global Settings Modified Externally",
165 contents = "The global settings were modified by another instance.\n"
166 "Would you like to reload them?" }.Modal() == Yes)*/
174 SettingsIOResult result = GlobalSettings::Load();
175 IDESettings data = (IDESettings)this.data;
176 //if(result == success)
179 this.data = IDESettings { };
181 *dataOwner = this.data;
183 if(result == fileNotCompatibleWithDriver)
186 OldIDESettings oldSettings { };
188 loaded = oldSettings.Load();
192 data = (IDESettings)this.data;
194 for(c : oldSettings.compilerConfigs)
195 data.compilerConfigs.Add(c.Copy());
197 for(s : oldSettings.recentFiles) data.recentFiles.Add(CopyString(s));
198 for(s : oldSettings.recentProjects) data.recentProjects.Add(CopyString(s));
200 data.docDir = oldSettings.docDir;
201 data.ideFileDialogLocation = oldSettings.ideFileDialogLocation;
202 data.ideProjectFileDialogLocation = oldSettings.ideProjectFileDialogLocation;
203 data.useFreeCaret = oldSettings.useFreeCaret;
204 data.showLineNumbers = oldSettings.showLineNumbers;
205 data.caretFollowsScrolling = oldSettings.caretFollowsScrolling;
206 delete data.displayDriver;
207 data.displayDriver = oldSettings.displayDriver;
208 data.projectDefaultTargetDir = oldSettings.projectDefaultTargetDir;
209 data.projectDefaultIntermediateObjDir = oldSettings.projectDefaultIntermediateObjDir;
216 if(result == fileNotFound || !data)
218 CompilerConfig defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
219 data = (IDESettings)this.data;
220 data.compilerConfigs = { };
221 data.compilerConfigs.Add(defaultCompiler);
222 data.useFreeCaret = true;
223 data.showLineNumbers = true;
224 data.caretFollowsScrolling = true;
228 if(data.compilerConfigs)
230 for(c : data.compilerConfigs)
232 CompilerConfig compiler = c;
238 char location[MAX_LOCATION];
239 LocateModule(null, location);
240 StripLastDirectory(location, location);
241 if(location[0] && FileExists(location).isDirectory)
243 if(data.portableLocation && data.portableLocation[0] && strcmp(data.portableLocation, location))
245 data.UpdatePortablePaths(data.portableLocation, location);
246 data.portableLocation = location;
251 data.ForcePathSeparatorStyle(true);
257 IDESettings data = (IDESettings)this.data;
258 Platform runtimePlatform = GetRuntimePlatform();
259 data.ForcePathSeparatorStyle(runtimePlatform != win32);
260 if(!GlobalSettings::Save())
261 PrintLn("Error saving IDE settings");
262 if(runtimePlatform == win32)
263 data.ForcePathSeparatorStyle(true);
268 class IDESettings : GlobalSettingsData
271 List<CompilerConfig> compilerConfigs { };
272 Array<String> recentFiles { };
273 Array<String> recentProjects { };
274 property char * docDir
276 set { delete docDir; if(value && value[0]) docDir = CopyString(value); }
277 get { return docDir ? docDir : ""; }
278 isset { return docDir && docDir[0]; }
280 property char * ideFileDialogLocation
282 set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); }
283 get { return ideFileDialogLocation ? ideFileDialogLocation : ""; }
284 isset { return ideFileDialogLocation && ideFileDialogLocation[0]; }
286 property char * ideProjectFileDialogLocation
288 set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); }
289 get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; }
290 isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; }
293 bool showLineNumbers;
294 bool caretFollowsScrolling;
295 char * displayDriver;
297 // TODO: Classify settings
298 //EditorSettings editor { };
300 property char * projectDefaultTargetDir
302 set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); }
303 get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; }
304 isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; }
306 property char * projectDefaultIntermediateObjDir
308 set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); }
309 get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; }
310 isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
313 property char * portableLocation
315 set { delete portableLocation; if(value && value[0]) portableLocation = CopyString(value); }
316 get { return portableLocation ? portableLocation : ""; }
317 isset { return portableLocation && portableLocation[0]; }
320 property char * defaultCompiler
322 set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); }
323 get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; }
324 isset { return defaultCompiler && defaultCompiler[0]; }
329 char * ideFileDialogLocation;
330 char * ideProjectFileDialogLocation;
331 char * projectDefaultTargetDir;
332 char * projectDefaultIntermediateObjDir;
333 char * portableLocation;
334 char * defaultCompiler;
336 CompilerConfig GetCompilerConfig(String compilerName)
338 char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName;
339 CompilerConfig compilerConfig = null;
340 for(compiler : compilerConfigs)
342 if(!strcmp(compiler.name, name))
344 compilerConfig = compiler;
348 if(!compilerConfig && compilerConfigs.count)
349 compilerConfig = compilerConfigs.firstIterator.data;
351 incref compilerConfig;
352 return compilerConfig;
357 compilerConfigs.Free();
358 delete compilerConfigs;
361 recentProjects.Free();
362 delete recentProjects;
365 delete projectDefaultTargetDir;
366 delete projectDefaultIntermediateObjDir;
367 delete portableLocation;
368 delete defaultCompiler;
370 delete ideFileDialogLocation;
371 delete ideProjectFileDialogLocation;
372 delete displayDriver;
375 void ForcePathSeparatorStyle(bool unixStyle)
379 from = '\\', to = '/';
381 from = '/', to = '\\';
382 if(compilerConfigs && compilerConfigs.count)
385 for(config : compilerConfigs)
387 if(config.includeDirs && config.includeDirs.count)
389 for(i = 0; i < config.includeDirs.count; i++)
391 if(config.includeDirs[i] && config.includeDirs[i][0])
392 ChangeCh(config.includeDirs[i], from, to);
395 if(config.libraryDirs && config.libraryDirs.count)
397 for(i = 0; i < config.libraryDirs.count; i++)
399 if(config.libraryDirs[i] && config.libraryDirs[i][0])
400 ChangeCh(config.libraryDirs[i], from, to);
403 if(config.executableDirs && config.executableDirs.count)
405 for(i = 0; i < config.executableDirs.count; i++)
407 if(config.executableDirs[i] && config.executableDirs[i][0])
408 ChangeCh(config.executableDirs[i], from, to);
413 if(recentFiles && recentFiles.count)
416 for(c = 0; c < recentFiles.count; c++)
418 if(recentFiles[c] && recentFiles[c][0])
419 ChangeCh(recentFiles[c], from, to);
422 if(recentProjects && recentProjects.count)
425 for(c = 0; c < recentProjects.count; c++)
427 if(recentProjects[c] && recentProjects[c][0])
428 ChangeCh(recentProjects[c], from, to);
431 if(docDir && docDir[0])
432 ChangeCh(docDir, from, to);
433 if(ideFileDialogLocation && ideFileDialogLocation[0])
434 ChangeCh(ideFileDialogLocation, from, to);
435 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
436 ChangeCh(ideProjectFileDialogLocation, from, to);
438 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
439 ChangeCh(projectDefaultTargetDir, from, to);
440 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
441 ChangeCh(projectDefaultIntermediateObjDir, from, to);
443 if(portableLocation && portableLocation[0])
444 ChangeCh(portableLocation, from, to);
447 bool UpdatePortablePaths(char * oldPath, char * newPath)
449 int oldLen = strlen(oldPath);
450 int newLen = strlen(newPath);
451 if(compilerConfigs && compilerConfigs.count)
453 for(config : compilerConfigs)
456 for(c = 0; c < DirTypes::enumSize; c++)
459 if(c == executables) dirs = config.executableDirs;
460 else if(c == includes) dirs = config.includeDirs;
461 else if(c == libraries) dirs = config.libraryDirs;
462 if(dirs && dirs.count)
465 for(i = 0; i < dirs.count; i++)
467 if(dirs[i] && dirs[i][0])
468 dirs[i] = ReplaceInCopyString(dirs[i], oldPath, oldLen, newPath, newLen);
474 if(recentFiles && recentFiles.count)
477 for(c = 0; c < recentFiles.count; c++)
479 if(recentFiles[c] && recentFiles[c][0])
480 recentFiles[c] = ReplaceInCopyString(recentFiles[c], oldPath, oldLen, newPath, newLen);
483 if(recentProjects && recentProjects.count)
486 for(c = 0; c < recentProjects.count; c++)
488 if(recentProjects[c] && recentProjects[c][0])
489 recentProjects[c] = ReplaceInCopyString(recentProjects[c], oldPath, oldLen, newPath, newLen);
492 if(docDir && docDir[0])
493 docDir = ReplaceInCopyString(docDir, oldPath, oldLen, newPath, newLen);
494 if(ideFileDialogLocation && ideFileDialogLocation[0])
495 ideFileDialogLocation = ReplaceInCopyString(ideFileDialogLocation, oldPath, oldLen, newPath, newLen);
496 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
497 ideProjectFileDialogLocation = ReplaceInCopyString(ideProjectFileDialogLocation, oldPath, oldLen, newPath, newLen);
499 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
500 projectDefaultTargetDir = ReplaceInCopyString(projectDefaultTargetDir, oldPath, oldLen, newPath, newLen);
501 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
502 projectDefaultIntermediateObjDir = ReplaceInCopyString(projectDefaultIntermediateObjDir, oldPath, oldLen, newPath, newLen);
505 char * ReplaceInCopyString(char * string, char * find, int lenFind, char * replace, int lenReplace)
507 char * output = string;
509 if(/*string && string[0] && */(start = strstr(string, find)))
511 if(lenFind == lenReplace)
512 strncpy(start, replace, lenReplace);
515 int newLen = strlen(string) + lenReplace - lenFind + 1;
516 char * newString = new char[newLen];
518 strcpy(newString, string);
520 strcat(newString, replace);
521 strcat(newString, start);
529 void AddRecentFile(char * fileName)
532 char * filePath = CopyString(fileName);
533 ChangeCh(filePath, '\\', '/');
534 for(c = 0; c<recentFiles.count; c++)
536 if(recentFiles[c] && !fstrcmp(recentFiles[c], filePath))
538 recentFiles.Delete((void *)&recentFiles[c]);
542 while(recentFiles.count >= MaxRecent)
543 recentFiles.Delete(recentFiles.GetLast());
544 recentFiles.Insert(null, filePath);
545 //UpdateRecentMenus(owner);
548 void AddRecentProject(char * projectName)
551 char * filePath = CopyString(projectName);
552 ChangeCh(filePath, '\\', '/');
553 for(c = 0; c<recentProjects.count; c++)
555 if(recentProjects[c] && !fstrcmp(recentProjects[c], filePath))
557 recentProjects.Delete((void *)&recentProjects[c]);
561 while(recentProjects.count >= MaxRecent)
562 recentProjects.Delete(recentProjects.GetLast());
563 recentProjects.Insert(null, filePath);
564 //UpdateRecentMenus(owner);
568 static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" };
569 static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" };
570 static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" };
571 static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
572 static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
573 static const char * compilerTypeLongNames[CompilerType] =
575 "GNU Compiler Collection (GCC) / GNU Make",
576 "Tiny C Compiler / GNU Make",
577 "Portable C Compiler / GNU Make",
578 "Microsoft Visual Studio 2005 (8.0) Compiler",
579 "Microsoft Visual Studio 2008 (9.0) Compiler",
580 "Microsoft Visual Studio 2010 (10.0) Compiler"
582 const CompilerType firstCompilerType = gcc;
583 const CompilerType lastCompilerType = vs10;
584 public enum CompilerType
586 gcc, tcc, pcc, vs8, vs9, vs10;
590 get { return this == vs8 || this == vs9 || this == vs10; }
595 get { return OnGetString(null, null, null); }
601 for(c = firstCompilerType; c <= lastCompilerType; c++)
602 if(!strcmpi(value, compilerTypeNames[c]))
609 property char * longName { get { return OnGetString(null, (void*)1, null); } };
610 property char * versionString { get { return OnGetString(null, (void*)2, null); } };
611 property char * yearString { get { return OnGetString(null, (void*)3, null); } };
612 property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } };
613 property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } };
615 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
617 if(this >= firstCompilerType && this <= lastCompilerType)
620 strcpy(tempString, compilerTypeNames[this]);
621 if(fieldData == null)
622 return compilerTypeNames[this];
623 else if(fieldData == (void*)1)
624 return compilerTypeLongNames[this];
625 else if(fieldData == (void*)2)
626 return compilerTypeVersionString[this];
627 else if(fieldData == (void*)3)
628 return compilerTypeYearString[this];
629 else if(fieldData == (void*)4)
630 return compilerTypeProjectFileExtension[this];
631 else if(fieldData == (void*)5)
632 return compilerTypeSolutionFileVersionString[this];
650 name = CopyString(value);
656 Platform targetPlatform;
658 property char * makeCommand
660 set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); }
661 get { return makeCommand; }
662 isset { return makeCommand && makeCommand[0]; }
664 property char * ecpCommand
666 set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); }
667 get { return ecpCommand; }
668 isset { return ecpCommand && ecpCommand[0]; }
670 property char * eccCommand
672 set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); }
673 get { return eccCommand; }
674 isset { return eccCommand && eccCommand[0]; }
676 property char * ecsCommand
678 set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); }
679 get { return ecsCommand; }
680 isset { return ecsCommand && ecsCommand[0]; }
682 property char * earCommand
684 set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); }
685 get { return earCommand; }
686 isset { return earCommand && earCommand[0]; }
688 property char * cppCommand
690 set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); }
691 get { return cppCommand; }
692 isset { return cppCommand && cppCommand[0]; }
694 property char * ccCommand
696 set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); }
697 get { return ccCommand; }
698 isset { return ccCommand && ccCommand[0]; }
700 property char * execPrefixCommand
702 set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); }
703 get { return execPrefixCommand; }
704 isset { return execPrefixCommand && execPrefixCommand[0]; }
706 Array<String> includeDirs { };
707 Array<String> libraryDirs { };
708 Array<String> executableDirs { };
709 // TODO: Can JSON parse and serialize maps?
710 //EnvironmentVariables { };
711 Array<NamedString> environmentVars { };
721 char * execPrefixCommand;
724 struct { Array<String> includes, libraries, executables; };
725 Array<String> dirs[DirTypes];
738 delete execPrefixCommand;
739 if(includeDirs) { includeDirs.Free(); delete includeDirs; }
740 if(libraryDirs) { libraryDirs.Free(); delete libraryDirs; }
741 if(executableDirs) { executableDirs.Free(); delete executableDirs; }
743 CompilerConfig Copy()
761 for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
762 for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
763 for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
764 for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = CopyString(ns.name), string = CopyString(ns.string) });