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 CompilerConfig defaultCompiler = null;
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; data.displayDriver = CopyString(oldSettings.displayDriver);
207 data.projectDefaultTargetDir = oldSettings.projectDefaultTargetDir;
208 data.projectDefaultIntermediateObjDir = oldSettings.projectDefaultIntermediateObjDir;
215 if(result == fileNotFound || !data)
217 data = (IDESettings)this.data;
218 data.useFreeCaret = true;
219 data.showLineNumbers = true;
220 data.caretFollowsScrolling = true;
223 // Ensure we have a default compiler
224 defaultCompiler = data.GetCompilerConfig(defaultCompilerName);
227 defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
228 data.compilerConfigs.Add(defaultCompiler);
231 // We incref the compilers below, so reset refCount to 0
232 defaultCompiler._refCount = 0;
235 if(data.compilerConfigs)
237 for(c : data.compilerConfigs)
239 CompilerConfig compiler = c;
245 char location[MAX_LOCATION];
246 LocateModule(null, location);
247 StripLastDirectory(location, location);
248 if(location[0] && FileExists(location).isDirectory)
250 if(data.portableLocation && data.portableLocation[0] && strcmp(data.portableLocation, location))
252 data.UpdatePortablePaths(data.portableLocation, location);
253 data.portableLocation = location;
258 data.ForcePathSeparatorStyle(true);
264 IDESettings data = (IDESettings)this.data;
265 Platform runtimePlatform = GetRuntimePlatform();
266 data.ForcePathSeparatorStyle(runtimePlatform != win32);
267 if(!GlobalSettings::Save())
268 PrintLn("Error saving IDE settings");
269 if(runtimePlatform == win32)
270 data.ForcePathSeparatorStyle(true);
275 class IDESettings : GlobalSettingsData
278 List<CompilerConfig> compilerConfigs { };
279 Array<String> recentFiles { };
280 Array<String> recentProjects { };
281 property char * docDir
283 set { delete docDir; if(value && value[0]) docDir = CopyString(value); }
284 get { return docDir ? docDir : ""; }
285 isset { return docDir && docDir[0]; }
287 property char * ideFileDialogLocation
289 set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); }
290 get { return ideFileDialogLocation ? ideFileDialogLocation : ""; }
291 isset { return ideFileDialogLocation && ideFileDialogLocation[0]; }
293 property char * ideProjectFileDialogLocation
295 set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); }
296 get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; }
297 isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; }
300 bool showLineNumbers;
301 bool caretFollowsScrolling;
302 char * displayDriver;
304 // TODO: Classify settings
305 //EditorSettings editor { };
307 property char * projectDefaultTargetDir
309 set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); }
310 get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; }
311 isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; }
313 property char * projectDefaultIntermediateObjDir
315 set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); }
316 get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; }
317 isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
320 property char * portableLocation
322 set { delete portableLocation; if(value && value[0]) portableLocation = CopyString(value); }
323 get { return portableLocation ? portableLocation : ""; }
324 isset { return portableLocation && portableLocation[0]; }
327 property char * defaultCompiler
329 set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); }
330 get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; }
331 isset { return defaultCompiler && defaultCompiler[0]; }
336 char * ideFileDialogLocation;
337 char * ideProjectFileDialogLocation;
338 char * projectDefaultTargetDir;
339 char * projectDefaultIntermediateObjDir;
340 char * portableLocation;
341 char * defaultCompiler;
343 CompilerConfig GetCompilerConfig(String compilerName)
345 char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName;
346 CompilerConfig compilerConfig = null;
347 for(compiler : compilerConfigs)
349 if(!strcmp(compiler.name, name))
351 compilerConfig = compiler;
355 if(!compilerConfig && compilerConfigs.count)
356 compilerConfig = compilerConfigs.firstIterator.data;
358 incref compilerConfig;
359 return compilerConfig;
364 compilerConfigs.Free();
365 delete compilerConfigs;
368 recentProjects.Free();
369 delete recentProjects;
372 delete projectDefaultTargetDir;
373 delete projectDefaultIntermediateObjDir;
374 delete portableLocation;
375 delete defaultCompiler;
377 delete ideFileDialogLocation;
378 delete ideProjectFileDialogLocation;
379 delete displayDriver;
382 void ForcePathSeparatorStyle(bool unixStyle)
386 from = '\\', to = '/';
388 from = '/', to = '\\';
389 if(compilerConfigs && compilerConfigs.count)
392 for(config : compilerConfigs)
394 if(config.includeDirs && config.includeDirs.count)
396 for(i = 0; i < config.includeDirs.count; i++)
398 if(config.includeDirs[i] && config.includeDirs[i][0])
399 ChangeCh(config.includeDirs[i], from, to);
402 if(config.libraryDirs && config.libraryDirs.count)
404 for(i = 0; i < config.libraryDirs.count; i++)
406 if(config.libraryDirs[i] && config.libraryDirs[i][0])
407 ChangeCh(config.libraryDirs[i], from, to);
410 if(config.executableDirs && config.executableDirs.count)
412 for(i = 0; i < config.executableDirs.count; i++)
414 if(config.executableDirs[i] && config.executableDirs[i][0])
415 ChangeCh(config.executableDirs[i], from, to);
420 if(recentFiles && recentFiles.count)
423 for(c = 0; c < recentFiles.count; c++)
425 if(recentFiles[c] && recentFiles[c][0])
426 ChangeCh(recentFiles[c], from, to);
429 if(recentProjects && recentProjects.count)
432 for(c = 0; c < recentProjects.count; c++)
434 if(recentProjects[c] && recentProjects[c][0])
435 ChangeCh(recentProjects[c], from, to);
438 if(docDir && docDir[0])
439 ChangeCh(docDir, from, to);
440 if(ideFileDialogLocation && ideFileDialogLocation[0])
441 ChangeCh(ideFileDialogLocation, from, to);
442 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
443 ChangeCh(ideProjectFileDialogLocation, from, to);
445 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
446 ChangeCh(projectDefaultTargetDir, from, to);
447 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
448 ChangeCh(projectDefaultIntermediateObjDir, from, to);
450 if(portableLocation && portableLocation[0])
451 ChangeCh(portableLocation, from, to);
454 bool UpdatePortablePaths(char * oldPath, char * newPath)
456 int oldLen = strlen(oldPath);
457 int newLen = strlen(newPath);
458 if(compilerConfigs && compilerConfigs.count)
460 for(config : compilerConfigs)
463 for(c = 0; c < DirTypes::enumSize; c++)
466 if(c == executables) dirs = config.executableDirs;
467 else if(c == includes) dirs = config.includeDirs;
468 else if(c == libraries) dirs = config.libraryDirs;
469 if(dirs && dirs.count)
472 for(i = 0; i < dirs.count; i++)
474 if(dirs[i] && dirs[i][0])
475 dirs[i] = ReplaceInCopyString(dirs[i], oldPath, oldLen, newPath, newLen);
481 if(recentFiles && recentFiles.count)
484 for(c = 0; c < recentFiles.count; c++)
486 if(recentFiles[c] && recentFiles[c][0])
487 recentFiles[c] = ReplaceInCopyString(recentFiles[c], oldPath, oldLen, newPath, newLen);
490 if(recentProjects && recentProjects.count)
493 for(c = 0; c < recentProjects.count; c++)
495 if(recentProjects[c] && recentProjects[c][0])
496 recentProjects[c] = ReplaceInCopyString(recentProjects[c], oldPath, oldLen, newPath, newLen);
499 if(docDir && docDir[0])
500 docDir = ReplaceInCopyString(docDir, oldPath, oldLen, newPath, newLen);
501 if(ideFileDialogLocation && ideFileDialogLocation[0])
502 ideFileDialogLocation = ReplaceInCopyString(ideFileDialogLocation, oldPath, oldLen, newPath, newLen);
503 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
504 ideProjectFileDialogLocation = ReplaceInCopyString(ideProjectFileDialogLocation, oldPath, oldLen, newPath, newLen);
506 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
507 projectDefaultTargetDir = ReplaceInCopyString(projectDefaultTargetDir, oldPath, oldLen, newPath, newLen);
508 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
509 projectDefaultIntermediateObjDir = ReplaceInCopyString(projectDefaultIntermediateObjDir, oldPath, oldLen, newPath, newLen);
513 char * ReplaceInCopyString(char * string, char * find, int lenFind, char * replace, int lenReplace)
515 char * output = string;
517 if(/*string && string[0] && */(start = strstr(string, find)))
519 if(lenFind == lenReplace)
520 strncpy(start, replace, lenReplace);
523 int newLen = strlen(string) + lenReplace - lenFind + 1;
524 char * newString = new char[newLen];
526 strcpy(newString, string);
528 strcat(newString, replace);
529 strcat(newString, start);
537 void AddRecentFile(char * fileName)
540 char * filePath = CopyString(fileName);
541 ChangeCh(filePath, '\\', '/');
542 for(c = 0; c<recentFiles.count; c++)
544 if(recentFiles[c] && !fstrcmp(recentFiles[c], filePath))
546 recentFiles.Delete((void *)&recentFiles[c]);
550 while(recentFiles.count >= MaxRecent)
551 recentFiles.Delete(recentFiles.GetLast());
552 recentFiles.Insert(null, filePath);
553 //UpdateRecentMenus(owner);
556 void AddRecentProject(char * projectName)
559 char * filePath = CopyString(projectName);
560 ChangeCh(filePath, '\\', '/');
561 for(c = 0; c<recentProjects.count; c++)
563 if(recentProjects[c] && !fstrcmp(recentProjects[c], filePath))
565 recentProjects.Delete((void *)&recentProjects[c]);
569 while(recentProjects.count >= MaxRecent)
570 recentProjects.Delete(recentProjects.GetLast());
571 recentProjects.Insert(null, filePath);
572 //UpdateRecentMenus(owner);
576 static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" };
577 static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" };
578 static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" };
579 static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
580 static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
581 // TODO: i18n with Array
582 static Array<String> compilerTypeLongNames
584 $"GNU Compiler Collection (GCC) / GNU Make",
585 $"Tiny C Compiler / GNU Make",
586 $"Portable C Compiler / GNU Make",
587 $"Microsoft Visual Studio 2005 (8.0) Compiler",
588 $"Microsoft Visual Studio 2008 (9.0) Compiler",
589 $"Microsoft Visual Studio 2010 (10.0) Compiler"
591 const CompilerType firstCompilerType = gcc;
592 const CompilerType lastCompilerType = vs10;
593 public enum CompilerType
595 gcc, tcc, pcc, vs8, vs9, vs10;
599 get { return this == vs8 || this == vs9 || this == vs10; }
604 get { return OnGetString(null, null, null); }
610 for(c = firstCompilerType; c <= lastCompilerType; c++)
611 if(!strcmpi(value, compilerTypeNames[c]))
618 property char * longName { get { return OnGetString(null, (void*)1, null); } };
619 property char * versionString { get { return OnGetString(null, (void*)2, null); } };
620 property char * yearString { get { return OnGetString(null, (void*)3, null); } };
621 property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } };
622 property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } };
624 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
626 if(this >= firstCompilerType && this <= lastCompilerType)
629 strcpy(tempString, compilerTypeNames[this]);
630 if(fieldData == null)
631 return compilerTypeNames[this];
632 else if(fieldData == (void*)1)
633 return compilerTypeLongNames[this];
634 else if(fieldData == (void*)2)
635 return compilerTypeVersionString[this];
636 else if(fieldData == (void*)3)
637 return compilerTypeYearString[this];
638 else if(fieldData == (void*)4)
639 return compilerTypeProjectFileExtension[this];
640 else if(fieldData == (void*)5)
641 return compilerTypeSolutionFileVersionString[this];
659 name = CopyString(value);
665 Platform targetPlatform;
667 property char * makeCommand
669 set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); }
670 get { return makeCommand; }
671 isset { return makeCommand && makeCommand[0]; }
673 property char * ecpCommand
675 set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); }
676 get { return ecpCommand; }
677 isset { return ecpCommand && ecpCommand[0]; }
679 property char * eccCommand
681 set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); }
682 get { return eccCommand; }
683 isset { return eccCommand && eccCommand[0]; }
685 property char * ecsCommand
687 set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); }
688 get { return ecsCommand; }
689 isset { return ecsCommand && ecsCommand[0]; }
691 property char * earCommand
693 set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); }
694 get { return earCommand; }
695 isset { return earCommand && earCommand[0]; }
697 property char * cppCommand
699 set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); }
700 get { return cppCommand; }
701 isset { return cppCommand && cppCommand[0]; }
703 property char * ccCommand
705 set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); }
706 get { return ccCommand; }
707 isset { return ccCommand && ccCommand[0]; }
709 property char * execPrefixCommand
711 set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); }
712 get { return execPrefixCommand; }
713 isset { return execPrefixCommand && execPrefixCommand[0]; }
717 property char * distccHosts
719 set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); }
720 get { return distccHosts; }
721 isset { return distccHosts && distccHosts[0]; }
723 property Array<String> includeDirs
734 get { return includeDirs; }
735 isset { return includeDirs.count != 0; }
737 property Array<String> libraryDirs
748 get { return libraryDirs; }
749 isset { return libraryDirs.count != 0; }
751 property Array<String> executableDirs
755 executableDirs.Free();
758 delete executableDirs;
759 executableDirs = value;
762 get { return executableDirs; }
763 isset { return executableDirs.count != 0; }
765 property Array<NamedString> environmentVars
769 environmentVars.Free();
772 delete environmentVars;
773 environmentVars = value;
776 get { return environmentVars; }
777 isset { return environmentVars.count != 0; }
780 Array<String> includeDirs { };
781 Array<String> libraryDirs { };
782 Array<String> executableDirs { };
783 // TODO: Can JSON parse and serialize maps?
784 //EnvironmentVariables { };
785 Array<NamedString> environmentVars { };
794 char * execPrefixCommand;
798 struct { Array<String> includes, libraries, executables; };
799 Array<String> dirs[DirTypes];
812 delete execPrefixCommand;
814 if(environmentVars) environmentVars.Free();
815 if(includeDirs) { includeDirs.Free(); }
816 if(libraryDirs) { libraryDirs.Free(); }
817 if(executableDirs) { executableDirs.Free(); }
819 CompilerConfig Copy()
840 for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
841 for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
842 for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
843 for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string });