#ifdef ECERE_STATIC import static "ecere" #else import "ecere" #endif import "StringsBox" import "OldIDESettings" define MaxRecent = 9; enum DirTypes { includes, libraries, executables }; define defaultCompilerName = "Default"; define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)"; char * settingsDirectoryNames[DirTypes] = { "Include Files", "Library Files", "Executable Files" }; enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings }; char * CopyValidateMakefilePath(char * path) { const int map[] = { 0, 1, 2, 3, 4, 0, 1, 7 }; const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(PROJECT)", "$(CONFIGURATION)", (char *)0 }; char * copy = null; if(path) { int len; len = strlen(path); copy = CopyString(path); if(len) { int c; char * tmp = copy; char * start = tmp; Array parts { }; for(c=0; c compilerConfigs { }; Array recentFiles { }; Array recentProjects { }; property char * docDir { set { delete docDir; if(value && value[0]) docDir = CopyString(value); } get { return docDir ? docDir : ""; } isset { return docDir && docDir[0]; } } property char * ideFileDialogLocation { set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); } get { return ideFileDialogLocation ? ideFileDialogLocation : ""; } isset { return ideFileDialogLocation && ideFileDialogLocation[0]; } } property char * ideProjectFileDialogLocation { set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); } get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; } isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; } } bool useFreeCaret; bool showLineNumbers; bool caretFollowsScrolling; char * displayDriver; // TODO: Classify settings //EditorSettings editor { }; property char * projectDefaultTargetDir { set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); } get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; } isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; } } property char * projectDefaultIntermediateObjDir { set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); } get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; } isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; } } property char * portableLocation { set { delete portableLocation; if(value && value[0]) portableLocation = CopyString(value); } get { return portableLocation ? portableLocation : ""; } isset { return portableLocation && portableLocation[0]; } } property char * defaultCompiler { set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); } get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; } isset { return defaultCompiler && defaultCompiler[0]; } } private: char * docDir; char * ideFileDialogLocation; char * ideProjectFileDialogLocation; char * projectDefaultTargetDir; char * projectDefaultIntermediateObjDir; char * portableLocation; char * defaultCompiler; CompilerConfig GetCompilerConfig(String compilerName) { char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName; CompilerConfig compilerConfig = null; for(compiler : compilerConfigs) { if(!strcmp(compiler.name, name)) { compilerConfig = compiler; break; } } if(!compilerConfig && compilerConfigs.count) compilerConfig = compilerConfigs.firstIterator.data; if(compilerConfig) incref compilerConfig; return compilerConfig; } ~IDESettings() { compilerConfigs.Free(); delete compilerConfigs; recentFiles.Free(); delete recentFiles; recentProjects.Free(); delete recentProjects; delete docDir; delete projectDefaultTargetDir; delete projectDefaultIntermediateObjDir; delete portableLocation; delete defaultCompiler; delete ideFileDialogLocation; delete ideProjectFileDialogLocation; delete displayDriver; } void ForcePathSeparatorStyle(bool unixStyle) { char from, to; if(unixStyle) from = '\\', to = '/'; else from = '/', to = '\\'; if(compilerConfigs && compilerConfigs.count) { int i; for(config : compilerConfigs) { if(config.includeDirs && config.includeDirs.count) { for(i = 0; i < config.includeDirs.count; i++) { if(config.includeDirs[i] && config.includeDirs[i][0]) ChangeCh(config.includeDirs[i], from, to); } } if(config.libraryDirs && config.libraryDirs.count) { for(i = 0; i < config.libraryDirs.count; i++) { if(config.libraryDirs[i] && config.libraryDirs[i][0]) ChangeCh(config.libraryDirs[i], from, to); } } if(config.executableDirs && config.executableDirs.count) { for(i = 0; i < config.executableDirs.count; i++) { if(config.executableDirs[i] && config.executableDirs[i][0]) ChangeCh(config.executableDirs[i], from, to); } } } } if(recentFiles && recentFiles.count) { int c; for(c = 0; c < recentFiles.count; c++) { if(recentFiles[c] && recentFiles[c][0]) ChangeCh(recentFiles[c], from, to); } } if(recentProjects && recentProjects.count) { int c; for(c = 0; c < recentProjects.count; c++) { if(recentProjects[c] && recentProjects[c][0]) ChangeCh(recentProjects[c], from, to); } } if(docDir && docDir[0]) ChangeCh(docDir, from, to); if(ideFileDialogLocation && ideFileDialogLocation[0]) ChangeCh(ideFileDialogLocation, from, to); if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]) ChangeCh(ideProjectFileDialogLocation, from, to); if(projectDefaultTargetDir && projectDefaultTargetDir[0]) ChangeCh(projectDefaultTargetDir, from, to); if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]) ChangeCh(projectDefaultIntermediateObjDir, from, to); if(portableLocation && portableLocation[0]) ChangeCh(portableLocation, from, to); } bool UpdatePortablePaths(char * oldPath, char * newPath) { int oldLen = strlen(oldPath); int newLen = strlen(newPath); if(compilerConfigs && compilerConfigs.count) { for(config : compilerConfigs) { DirTypes c; for(c = 0; c < DirTypes::enumSize; c++) { Array dirs; if(c == executables) dirs = config.executableDirs; else if(c == includes) dirs = config.includeDirs; else if(c == libraries) dirs = config.libraryDirs; if(dirs && dirs.count) { int i; for(i = 0; i < dirs.count; i++) { if(dirs[i] && dirs[i][0]) dirs[i] = ReplaceInCopyString(dirs[i], oldPath, oldLen, newPath, newLen); } } } } } if(recentFiles && recentFiles.count) { int c; for(c = 0; c < recentFiles.count; c++) { if(recentFiles[c] && recentFiles[c][0]) recentFiles[c] = ReplaceInCopyString(recentFiles[c], oldPath, oldLen, newPath, newLen); } } if(recentProjects && recentProjects.count) { int c; for(c = 0; c < recentProjects.count; c++) { if(recentProjects[c] && recentProjects[c][0]) recentProjects[c] = ReplaceInCopyString(recentProjects[c], oldPath, oldLen, newPath, newLen); } } if(docDir && docDir[0]) docDir = ReplaceInCopyString(docDir, oldPath, oldLen, newPath, newLen); if(ideFileDialogLocation && ideFileDialogLocation[0]) ideFileDialogLocation = ReplaceInCopyString(ideFileDialogLocation, oldPath, oldLen, newPath, newLen); if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]) ideProjectFileDialogLocation = ReplaceInCopyString(ideProjectFileDialogLocation, oldPath, oldLen, newPath, newLen); if(projectDefaultTargetDir && projectDefaultTargetDir[0]) projectDefaultTargetDir = ReplaceInCopyString(projectDefaultTargetDir, oldPath, oldLen, newPath, newLen); if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]) projectDefaultIntermediateObjDir = ReplaceInCopyString(projectDefaultIntermediateObjDir, oldPath, oldLen, newPath, newLen); } char * ReplaceInCopyString(char * string, char * find, int lenFind, char * replace, int lenReplace) { char * output = string; char * start; if(/*string && string[0] && */(start = strstr(string, find))) { if(lenFind == lenReplace) strncpy(start, replace, lenReplace); else { int newLen = strlen(string) + lenReplace - lenFind + 1; char * newString = new char[newLen]; start[0] = '\0'; strcpy(newString, string); start += lenFind; strcat(newString, replace); strcat(newString, start); delete string; return newString; } } return output; } void AddRecentFile(char * fileName) { int c; char * filePath = CopyString(fileName); ChangeCh(filePath, '\\', '/'); for(c = 0; c= MaxRecent) recentFiles.Delete(recentFiles.GetLast()); recentFiles.Insert(null, filePath); //UpdateRecentMenus(owner); } void AddRecentProject(char * projectName) { int c; char * filePath = CopyString(projectName); ChangeCh(filePath, '\\', '/'); for(c = 0; c= MaxRecent) recentProjects.Delete(recentProjects.GetLast()); recentProjects.Insert(null, filePath); //UpdateRecentMenus(owner); } } static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" }; static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" }; static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" }; static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" }; static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" }; // TODO: i18n with Array static const char * compilerTypeLongNames[CompilerType] = { "GNU Compiler Collection (GCC) / GNU Make", "Tiny C Compiler / GNU Make", "Portable C Compiler / GNU Make", "Microsoft Visual Studio 2005 (8.0) Compiler", "Microsoft Visual Studio 2008 (9.0) Compiler", "Microsoft Visual Studio 2010 (10.0) Compiler" }; const CompilerType firstCompilerType = gcc; const CompilerType lastCompilerType = vs10; public enum CompilerType { gcc, tcc, pcc, vs8, vs9, vs10; property bool isVC { get { return this == vs8 || this == vs9 || this == vs10; } } property char * { get { return OnGetString(null, null, null); } set { if(value) { Platform c; for(c = firstCompilerType; c <= lastCompilerType; c++) if(!strcmpi(value, compilerTypeNames[c])) return c; } return gcc; } }; property char * longName { get { return OnGetString(null, (void*)1, null); } }; property char * versionString { get { return OnGetString(null, (void*)2, null); } }; property char * yearString { get { return OnGetString(null, (void*)3, null); } }; property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } }; property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } }; char * OnGetString(char * tempString, void * fieldData, bool * needClass) { if(this >= firstCompilerType && this <= lastCompilerType) { if(tempString) strcpy(tempString, compilerTypeNames[this]); if(fieldData == null) return compilerTypeNames[this]; else if(fieldData == (void*)1) return compilerTypeLongNames[this]; else if(fieldData == (void*)2) return compilerTypeVersionString[this]; else if(fieldData == (void*)3) return compilerTypeYearString[this]; else if(fieldData == (void*)4) return compilerTypeProjectFileExtension[this]; else if(fieldData == (void*)5) return compilerTypeSolutionFileVersionString[this]; } return null; } }; class CompilerConfig { class_no_expansion; numJobs = 1; public: property char * name { set { delete name; if(value) name = CopyString(value); } get { return name; } } bool readOnly; CompilerType type; Platform targetPlatform; int numJobs; property char * makeCommand { set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); } get { return makeCommand; } isset { return makeCommand && makeCommand[0]; } } property char * ecpCommand { set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); } get { return ecpCommand; } isset { return ecpCommand && ecpCommand[0]; } } property char * eccCommand { set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); } get { return eccCommand; } isset { return eccCommand && eccCommand[0]; } } property char * ecsCommand { set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); } get { return ecsCommand; } isset { return ecsCommand && ecsCommand[0]; } } property char * earCommand { set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); } get { return earCommand; } isset { return earCommand && earCommand[0]; } } property char * cppCommand { set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); } get { return cppCommand; } isset { return cppCommand && cppCommand[0]; } } property char * ccCommand { set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); } get { return ccCommand; } isset { return ccCommand && ccCommand[0]; } } property char * execPrefixCommand { set { delete execPrefixCommand; if(value && value[0]) execPrefixCommand = CopyString(value); } get { return execPrefixCommand; } isset { return execPrefixCommand && execPrefixCommand[0]; } } bool ccacheEnabled; bool distccEnabled; property char * distccHosts { set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); } get { return distccHosts; } isset { return distccHosts && distccHosts[0]; } } property Array includeDirs { set { includeDirs.Free(); if(value) { delete includeDirs; includeDirs = value; } } get { return includeDirs; } isset { return includeDirs.count != 0; } } property Array libraryDirs { set { libraryDirs.Free(); if(value) { delete libraryDirs; libraryDirs = value; } } get { return libraryDirs; } isset { return libraryDirs.count != 0; } } property Array executableDirs { set { executableDirs.Free(); if(value) { delete executableDirs; executableDirs = value; } } get { return executableDirs; } isset { return executableDirs.count != 0; } } property Array environmentVars { set { environmentVars.Free(); if(value) { delete environmentVars; environmentVars = value; } } get { return environmentVars; } isset { return environmentVars.count != 0; } } private: Array includeDirs { }; Array libraryDirs { }; Array executableDirs { }; // TODO: Can JSON parse and serialize maps? //EnvironmentVariables { }; Array environmentVars { }; char * name; char * makeCommand; char * ecpCommand; char * eccCommand; char * ecsCommand; char * earCommand; char * cppCommand; char * ccCommand; char * execPrefixCommand; char * distccHosts; /*union { struct { Array includes, libraries, executables; }; Array dirs[DirTypes]; }*/ ~CompilerConfig() { delete name; delete ecpCommand; delete eccCommand; delete ecsCommand; delete earCommand; delete cppCommand; delete ccCommand; delete makeCommand; delete execPrefixCommand; delete distccHosts; if(environmentVars) environmentVars.Free(); if(includeDirs) { includeDirs.Free(); } if(libraryDirs) { libraryDirs.Free(); } if(executableDirs) { executableDirs.Free(); } } CompilerConfig Copy() { CompilerConfig copy { name, readOnly, type, targetPlatform, numJobs, makeCommand, ecpCommand, eccCommand, ecsCommand, earCommand, cppCommand, ccCommand, execPrefixCommand, ccacheEnabled, distccEnabled, distccHosts }; for(s : includeDirs) copy.includeDirs.Add(CopyString(s)); for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s)); for(s : executableDirs) copy.executableDirs.Add(CopyString(s)); for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string }); incref copy; return copy; } }