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 // We incref the compilers below, so reset refCount to 0
220 defaultCompiler._refCount = 0;
221 data = (IDESettings)this.data;
223 data.compilerConfigs.Add(defaultCompiler);
224 data.useFreeCaret = true;
225 data.showLineNumbers = true;
226 data.caretFollowsScrolling = true;
230 if(data.compilerConfigs)
232 for(c : data.compilerConfigs)
234 CompilerConfig compiler = c;
240 char location[MAX_LOCATION];
241 LocateModule(null, location);
242 StripLastDirectory(location, location);
243 if(location[0] && FileExists(location).isDirectory)
245 if(data.portableLocation && data.portableLocation[0] && strcmp(data.portableLocation, location))
247 data.UpdatePortablePaths(data.portableLocation, location);
248 data.portableLocation = location;
253 data.ForcePathSeparatorStyle(true);
259 IDESettings data = (IDESettings)this.data;
260 Platform runtimePlatform = GetRuntimePlatform();
261 data.ForcePathSeparatorStyle(runtimePlatform != win32);
262 if(!GlobalSettings::Save())
263 PrintLn("Error saving IDE settings");
264 if(runtimePlatform == win32)
265 data.ForcePathSeparatorStyle(true);
270 class IDESettings : GlobalSettingsData
273 List<CompilerConfig> compilerConfigs { };
274 Array<String> recentFiles { };
275 Array<String> recentProjects { };
276 property char * docDir
278 set { delete docDir; if(value && value[0]) docDir = CopyString(value); }
279 get { return docDir ? docDir : ""; }
280 isset { return docDir && docDir[0]; }
282 property char * ideFileDialogLocation
284 set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); }
285 get { return ideFileDialogLocation ? ideFileDialogLocation : ""; }
286 isset { return ideFileDialogLocation && ideFileDialogLocation[0]; }
288 property char * ideProjectFileDialogLocation
290 set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); }
291 get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; }
292 isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; }
295 bool showLineNumbers;
296 bool caretFollowsScrolling;
297 char * displayDriver;
299 // TODO: Classify settings
300 //EditorSettings editor { };
302 property char * projectDefaultTargetDir
304 set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); }
305 get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; }
306 isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; }
308 property char * projectDefaultIntermediateObjDir
310 set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); }
311 get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; }
312 isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
315 property char * portableLocation
317 set { delete portableLocation; if(value && value[0]) portableLocation = CopyString(value); }
318 get { return portableLocation ? portableLocation : ""; }
319 isset { return portableLocation && portableLocation[0]; }
322 property char * defaultCompiler
324 set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); }
325 get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; }
326 isset { return defaultCompiler && defaultCompiler[0]; }
331 char * ideFileDialogLocation;
332 char * ideProjectFileDialogLocation;
333 char * projectDefaultTargetDir;
334 char * projectDefaultIntermediateObjDir;
335 char * portableLocation;
336 char * defaultCompiler;
338 CompilerConfig GetCompilerConfig(String compilerName)
340 char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName;
341 CompilerConfig compilerConfig = null;
342 for(compiler : compilerConfigs)
344 if(!strcmp(compiler.name, name))
346 compilerConfig = compiler;
350 if(!compilerConfig && compilerConfigs.count)
351 compilerConfig = compilerConfigs.firstIterator.data;
353 incref compilerConfig;
354 return compilerConfig;
359 compilerConfigs.Free();
360 delete compilerConfigs;
363 recentProjects.Free();
364 delete recentProjects;
367 delete projectDefaultTargetDir;
368 delete projectDefaultIntermediateObjDir;
369 delete portableLocation;
370 delete defaultCompiler;
372 delete ideFileDialogLocation;
373 delete ideProjectFileDialogLocation;
374 delete displayDriver;
377 void ForcePathSeparatorStyle(bool unixStyle)
381 from = '\\', to = '/';
383 from = '/', to = '\\';
384 if(compilerConfigs && compilerConfigs.count)
387 for(config : compilerConfigs)
389 if(config.includeDirs && config.includeDirs.count)
391 for(i = 0; i < config.includeDirs.count; i++)
393 if(config.includeDirs[i] && config.includeDirs[i][0])
394 ChangeCh(config.includeDirs[i], from, to);
397 if(config.libraryDirs && config.libraryDirs.count)
399 for(i = 0; i < config.libraryDirs.count; i++)
401 if(config.libraryDirs[i] && config.libraryDirs[i][0])
402 ChangeCh(config.libraryDirs[i], from, to);
405 if(config.executableDirs && config.executableDirs.count)
407 for(i = 0; i < config.executableDirs.count; i++)
409 if(config.executableDirs[i] && config.executableDirs[i][0])
410 ChangeCh(config.executableDirs[i], from, to);
415 if(recentFiles && recentFiles.count)
418 for(c = 0; c < recentFiles.count; c++)
420 if(recentFiles[c] && recentFiles[c][0])
421 ChangeCh(recentFiles[c], from, to);
424 if(recentProjects && recentProjects.count)
427 for(c = 0; c < recentProjects.count; c++)
429 if(recentProjects[c] && recentProjects[c][0])
430 ChangeCh(recentProjects[c], from, to);
433 if(docDir && docDir[0])
434 ChangeCh(docDir, from, to);
435 if(ideFileDialogLocation && ideFileDialogLocation[0])
436 ChangeCh(ideFileDialogLocation, from, to);
437 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
438 ChangeCh(ideProjectFileDialogLocation, from, to);
440 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
441 ChangeCh(projectDefaultTargetDir, from, to);
442 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
443 ChangeCh(projectDefaultIntermediateObjDir, from, to);
445 if(portableLocation && portableLocation[0])
446 ChangeCh(portableLocation, from, to);
449 bool UpdatePortablePaths(char * oldPath, char * newPath)
451 int oldLen = strlen(oldPath);
452 int newLen = strlen(newPath);
453 if(compilerConfigs && compilerConfigs.count)
455 for(config : compilerConfigs)
458 for(c = 0; c < DirTypes::enumSize; c++)
461 if(c == executables) dirs = config.executableDirs;
462 else if(c == includes) dirs = config.includeDirs;
463 else if(c == libraries) dirs = config.libraryDirs;
464 if(dirs && dirs.count)
467 for(i = 0; i < dirs.count; i++)
469 if(dirs[i] && dirs[i][0])
470 dirs[i] = ReplaceInCopyString(dirs[i], oldPath, oldLen, newPath, newLen);
476 if(recentFiles && recentFiles.count)
479 for(c = 0; c < recentFiles.count; c++)
481 if(recentFiles[c] && recentFiles[c][0])
482 recentFiles[c] = ReplaceInCopyString(recentFiles[c], oldPath, oldLen, newPath, newLen);
485 if(recentProjects && recentProjects.count)
488 for(c = 0; c < recentProjects.count; c++)
490 if(recentProjects[c] && recentProjects[c][0])
491 recentProjects[c] = ReplaceInCopyString(recentProjects[c], oldPath, oldLen, newPath, newLen);
494 if(docDir && docDir[0])
495 docDir = ReplaceInCopyString(docDir, oldPath, oldLen, newPath, newLen);
496 if(ideFileDialogLocation && ideFileDialogLocation[0])
497 ideFileDialogLocation = ReplaceInCopyString(ideFileDialogLocation, oldPath, oldLen, newPath, newLen);
498 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
499 ideProjectFileDialogLocation = ReplaceInCopyString(ideProjectFileDialogLocation, oldPath, oldLen, newPath, newLen);
501 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
502 projectDefaultTargetDir = ReplaceInCopyString(projectDefaultTargetDir, oldPath, oldLen, newPath, newLen);
503 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
504 projectDefaultIntermediateObjDir = ReplaceInCopyString(projectDefaultIntermediateObjDir, oldPath, oldLen, newPath, newLen);
507 char * ReplaceInCopyString(char * string, char * find, int lenFind, char * replace, int lenReplace)
509 char * output = string;
511 if(/*string && string[0] && */(start = strstr(string, find)))
513 if(lenFind == lenReplace)
514 strncpy(start, replace, lenReplace);
517 int newLen = strlen(string) + lenReplace - lenFind + 1;
518 char * newString = new char[newLen];
520 strcpy(newString, string);
522 strcat(newString, replace);
523 strcat(newString, start);
531 void AddRecentFile(char * fileName)
534 char * filePath = CopyString(fileName);
535 ChangeCh(filePath, '\\', '/');
536 for(c = 0; c<recentFiles.count; c++)
538 if(recentFiles[c] && !fstrcmp(recentFiles[c], filePath))
540 recentFiles.Delete((void *)&recentFiles[c]);
544 while(recentFiles.count >= MaxRecent)
545 recentFiles.Delete(recentFiles.GetLast());
546 recentFiles.Insert(null, filePath);
547 //UpdateRecentMenus(owner);
550 void AddRecentProject(char * projectName)
553 char * filePath = CopyString(projectName);
554 ChangeCh(filePath, '\\', '/');
555 for(c = 0; c<recentProjects.count; c++)
557 if(recentProjects[c] && !fstrcmp(recentProjects[c], filePath))
559 recentProjects.Delete((void *)&recentProjects[c]);
563 while(recentProjects.count >= MaxRecent)
564 recentProjects.Delete(recentProjects.GetLast());
565 recentProjects.Insert(null, filePath);
566 //UpdateRecentMenus(owner);
570 static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" };
571 static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" };
572 static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" };
573 static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
574 static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
575 // TODO: i18n with Array
576 static Array<String> compilerTypeLongNames
578 $"GNU Compiler Collection (GCC) / GNU Make",
579 $"Tiny C Compiler / GNU Make",
580 $"Portable C Compiler / GNU Make",
581 $"Microsoft Visual Studio 2005 (8.0) Compiler",
582 $"Microsoft Visual Studio 2008 (9.0) Compiler",
583 $"Microsoft Visual Studio 2010 (10.0) Compiler"
585 const CompilerType firstCompilerType = gcc;
586 const CompilerType lastCompilerType = vs10;
587 public enum CompilerType
589 gcc, tcc, pcc, vs8, vs9, vs10;
593 get { return this == vs8 || this == vs9 || this == vs10; }
598 get { return OnGetString(null, null, null); }
604 for(c = firstCompilerType; c <= lastCompilerType; c++)
605 if(!strcmpi(value, compilerTypeNames[c]))
612 property char * longName { get { return OnGetString(null, (void*)1, null); } };
613 property char * versionString { get { return OnGetString(null, (void*)2, null); } };
614 property char * yearString { get { return OnGetString(null, (void*)3, null); } };
615 property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } };
616 property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } };
618 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
620 if(this >= firstCompilerType && this <= lastCompilerType)
623 strcpy(tempString, compilerTypeNames[this]);
624 if(fieldData == null)
625 return compilerTypeNames[this];
626 else if(fieldData == (void*)1)
627 return compilerTypeLongNames[this];
628 else if(fieldData == (void*)2)
629 return compilerTypeVersionString[this];
630 else if(fieldData == (void*)3)
631 return compilerTypeYearString[this];
632 else if(fieldData == (void*)4)
633 return compilerTypeProjectFileExtension[this];
634 else if(fieldData == (void*)5)
635 return compilerTypeSolutionFileVersionString[this];
653 name = CopyString(value);
659 Platform targetPlatform;
661 property char * makeCommand
663 set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); }
664 get { return makeCommand; }
665 isset { return makeCommand && makeCommand[0]; }
667 property char * ecpCommand
669 set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); }
670 get { return ecpCommand; }
671 isset { return ecpCommand && ecpCommand[0]; }
673 property char * eccCommand
675 set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); }
676 get { return eccCommand; }
677 isset { return eccCommand && eccCommand[0]; }
679 property char * ecsCommand
681 set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); }
682 get { return ecsCommand; }
683 isset { return ecsCommand && ecsCommand[0]; }
685 property char * earCommand
687 set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); }
688 get { return earCommand; }
689 isset { return earCommand && earCommand[0]; }
691 property char * cppCommand
693 set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); }
694 get { return cppCommand; }
695 isset { return cppCommand && cppCommand[0]; }
697 property char * ccCommand
699 set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); }
700 get { return ccCommand; }
701 isset { return ccCommand && ccCommand[0]; }
703 property char * execPrefixCommand
705 set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); }
706 get { return execPrefixCommand; }
707 isset { return execPrefixCommand && execPrefixCommand[0]; }
711 property char * distccHosts
713 set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); }
714 get { return distccHosts; }
715 isset { return distccHosts && distccHosts[0]; }
717 property Array<String> includeDirs
728 get { return includeDirs; }
729 isset { return includeDirs.count != 0; }
731 property Array<String> libraryDirs
742 get { return libraryDirs; }
743 isset { return libraryDirs.count != 0; }
745 property Array<String> executableDirs
749 executableDirs.Free();
752 delete executableDirs;
753 executableDirs = value;
756 get { return executableDirs; }
757 isset { return executableDirs.count != 0; }
759 property Array<NamedString> environmentVars
763 environmentVars.Free();
766 delete environmentVars;
767 environmentVars = value;
770 get { return environmentVars; }
771 isset { return environmentVars.count != 0; }
774 Array<String> includeDirs { };
775 Array<String> libraryDirs { };
776 Array<String> executableDirs { };
777 // TODO: Can JSON parse and serialize maps?
778 //EnvironmentVariables { };
779 Array<NamedString> environmentVars { };
788 char * execPrefixCommand;
792 struct { Array<String> includes, libraries, executables; };
793 Array<String> dirs[DirTypes];
806 delete execPrefixCommand;
808 if(environmentVars) environmentVars.Free();
809 if(includeDirs) { includeDirs.Free(); }
810 if(libraryDirs) { libraryDirs.Free(); }
811 if(executableDirs) { executableDirs.Free(); }
813 CompilerConfig Copy()
834 for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
835 for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
836 for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
837 for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string });