2 public import static "ecere"
9 import "OldIDESettings"
13 enum DirTypes { includes, libraries, executables };
15 define defaultCompilerName = "Default";
17 define defaultObjDirExpression = "obj/$(CONFIG).$(PLATFORM)$(COMPILER_SUFFIX)$(DEBUG_SUFFIX)";
19 char * settingsDirectoryNames[DirTypes] =
26 // This function cannot accept same pointer for source and output
27 // todo: rename ReplaceSpaces to EscapeSpaceAndSpecialChars or something
28 void ReplaceSpaces(char * output, char * source)
33 for(c = 0, dc = 0; (ch = source[c]); c++, dc++)
35 if(ch == ' ') output[dc++] = '\\';
36 if(ch == '\"') output[dc++] = '\\';
37 if(ch == '&') output[dc++] = '\\';
40 if(ch == '(' || ch == ')') output[dc++] = '\\';
51 enum GlobalSettingsChange { none, editorSettings, projectOptions, compilerSettings };
53 enum PathRelationship { unrelated, identical, siblings, subPath, parentPath, insuficientInput, pathEmpty, toEmpty, pathNull, toNull, bothEmpty, bothNull };
54 PathRelationship eString_PathRelated(char * path, char * to, char * pathDiff)
56 PathRelationship result;
57 if(pathDiff) *pathDiff = '\0';
58 if(path && *path && to && *to)
60 char toPart[MAX_FILENAME], toRest[MAX_LOCATION];
61 char pathPart[MAX_FILENAME], pathRest[MAX_LOCATION];
63 strcpy(pathRest, path);
64 for(; toRest[0] && pathRest[0];)
66 SplitDirectory(toRest, toPart, toRest);
67 SplitDirectory(pathRest, pathPart, pathRest);
68 if(!fstrcmp(pathPart, toPart)) result = siblings;
71 if(result == siblings)
73 if(!*toRest && !*pathRest) result = identical;
74 else if(!*pathRest) result = parentPath;
75 else result = subPath;
76 if(pathDiff && result != identical) strcpy(pathDiff, *pathRest == '\0' ? toRest : pathRest);
78 else result = unrelated;
84 if(!*path && !*to) result = bothEmpty;
85 else if(!*path) result = pathEmpty;
86 else result = toEmpty;
88 else if(!path && !to) result = bothNull;
89 else if(!path) result = pathNull;
95 char * CopyValidateMakefilePath(char * path)
97 const int map[] = { 0, 1, 2, 3, 4, 5, 6, 0, 1, 2, 7 };
98 const char * vars[] = { "$(MODULE)", "$(CONFIG)", "$(PLATFORM)", "$(COMPILER)", "$(TARGET)", "$(COMPILER_SUFFIX)", "$(DEBUG_SUFFIX)", "$(PROJECT)", "$(CONFIGURATION)", "$(TARGET_PLATFORM)",(char *)0 };
105 copy = CopyString(path);
111 Array<char *> parts { };
118 for(v=0; vars[v]; v++)
120 if(SearchString(&tmp[c], 0, vars[v], false, false) == &tmp[c])
124 parts.Add(vars[map[v]]);
125 c += strlen(vars[v]);
139 for(c=0; c<parts.count; c++) len += strlen(parts[c]);
140 copy = new char[++len];
142 for(c=0; c<parts.count; c++) strcat(copy, parts[c]);
153 void ValidPathBufCopy(char *output, char *input)
156 bool volumePath = false;
158 strcpy(output, input);
159 TrimLSpaces(output, output);
160 TrimRSpaces(output, output);
161 MakeSystemPath(output);
163 if(output[0] && output[1] == ':')
170 char * chars = "*|:\",<>?";
171 char ch, * s = output, * o = output;
172 while((ch = *s++)) { if(!strchr(chars, ch)) *o++ = ch; }
176 if(volumePath && output[0])
181 void RemoveTrailingPathSeparator(char *path)
185 if(len>1 && path[len-1] == DIR_SEP)
189 void BasicValidatePathBoxPath(PathBox pathBox)
191 char path[MAX_LOCATION];
192 ValidPathBufCopy(path, pathBox.path);
193 RemoveTrailingPathSeparator(path);
197 CompilerConfig MakeDefaultCompiler(char * name, bool readOnly)
199 CompilerConfig defaultCompiler
204 GetRuntimePlatform(),
215 incref defaultCompiler;
216 return defaultCompiler;
219 class IDESettingsContainer : GlobalSettings
222 settingsName = "ecereIDESettingsTest";
224 settingsName = "ecereIDE";
227 virtual void OnLoad(GlobalSettingsData data);
229 char moduleLocation[MAX_LOCATION];
232 FileSize settingsFileSize;
234 IDESettingsContainer()
236 char path[MAX_LOCATION];
238 LocateModule(null, moduleLocation);
239 strcpy(path, moduleLocation);
240 StripLastDirectory(moduleLocation, moduleLocation);
241 ChangeCh(moduleLocation, '\\', '/');
242 // PortableApps.com directory structure
243 if((start = strstr(path, "\\App\\EcereSDK\\bin\\ide.exe")))
245 char configFilePath[MAX_LOCATION];
246 char defaultConfigFilePath[MAX_LOCATION];
250 strcpy(configFilePath, path);
251 PathCat(configFilePath, "Data");
252 PathCat(configFilePath, "ecereIDE.ini");
254 strcpy(defaultConfigFilePath, path);
255 PathCat(defaultConfigFilePath, "App");
256 PathCat(defaultConfigFilePath, "DefaultData");
257 PathCat(defaultConfigFilePath, "ecereIDE.ini");
259 if(FileExists(defaultConfigFilePath))
261 if(!FileExists(configFilePath))
263 File f = FileOpen(defaultConfigFilePath, read);
264 f.CopyTo(configFilePath);
268 PathCat(path, "Data");
269 // the forced settings location will only be
270 // used if the running ide's path matches
271 // the PortableApps.com directory structure
272 // and the default ini file is found in
273 // the DefaultData directory
274 settingsLocation = path;
280 void OnAskReloadSettings()
282 /*if(MessageBox { type = YesNo, master = this,
283 text = "Global Settings Modified Externally",
284 contents = "The global settings were modified by another instance.\n"
285 "Would you like to reload them?" }.Modal() == Yes)*/
288 FileSize newSettingsFileSize;
289 FileGetSize(settingsFilePath, &newSettingsFileSize);
290 o = settingsFileSize;
291 n = newSettingsFileSize;
296 GuiApplication app = ((GuiApplication)__thisModule.application);
298 for(w = app.desktop.firstChild; w && (!w.created || !w.visible); w = w.next);
299 MessageBox { master = w, type = ok,
300 text = "Global Settings Modified Externally",
301 contents = "The global settings were modified by another process and a drastic shrinking of the settings file was detected.\n"
302 "The new settings will not be loaded to prevent loss of your ide settings.\n"
303 "Please check your settings file and make sure to save this IDE's global settings if your settings file has been compromised."
310 SettingsIOResult Load()
312 SettingsIOResult result = GlobalSettings::Load();
313 IDESettings data = (IDESettings)this.data;
314 CompilerConfig defaultCompiler = null;
317 this.data = IDESettings { };
319 *dataOwner = this.data;
321 if(result == fileNotCompatibleWithDriver)
324 OldIDESettings oldSettings { };
326 loaded = oldSettings.Load() == success;
330 data = (IDESettings)this.data;
332 for(c : oldSettings.compilerConfigs)
333 data.compilerConfigs.Add(c.Copy());
335 for(s : oldSettings.recentFiles) data.recentFiles.Add(CopyString(s));
336 for(s : oldSettings.recentProjects) data.recentProjects.Add(CopyString(s));
338 data.docDir = oldSettings.docDir;
339 data.ideFileDialogLocation = oldSettings.ideFileDialogLocation;
340 data.ideProjectFileDialogLocation = oldSettings.ideProjectFileDialogLocation;
341 data.useFreeCaret = oldSettings.useFreeCaret;
342 data.showLineNumbers = oldSettings.showLineNumbers;
343 data.caretFollowsScrolling = oldSettings.caretFollowsScrolling;
344 delete data.displayDriver; data.displayDriver = CopyString(oldSettings.displayDriver);
345 data.projectDefaultTargetDir = oldSettings.projectDefaultTargetDir;
346 data.projectDefaultIntermediateObjDir = oldSettings.projectDefaultIntermediateObjDir;
353 if(result == fileNotFound || !data)
355 data = (IDESettings)this.data;
356 data.useFreeCaret = false; //true;
357 data.showLineNumbers = true;
358 data.caretFollowsScrolling = false; //true;
361 // Ensure we have a default compiler
362 defaultCompiler = data.GetCompilerConfig(defaultCompilerName);
365 defaultCompiler = MakeDefaultCompiler(defaultCompilerName, true);
366 data.compilerConfigs.Add(defaultCompiler);
369 // We incref the compilers below, so reset refCount to 0
370 defaultCompiler._refCount = 0;
373 FileGetSize(settingsFilePath, &settingsFileSize);
374 if(data.compilerConfigs)
376 for(c : data.compilerConfigs)
378 CompilerConfig compiler = c;
379 char * cxxCommand = compiler.cxxCommand;
380 if(!cxxCommand || !cxxCommand[0])
381 compiler.cxxCommand = cxxDefaultCommand;
385 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
386 data.ManagePortablePaths(moduleLocation, true);
387 data.ForcePathSeparatorStyle(true);
392 SettingsIOResult Save()
394 SettingsIOResult result;
396 IDESettings data = (IDESettings)this.data;
397 Platform runtimePlatform = GetRuntimePlatform();
398 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
399 data.ManagePortablePaths(moduleLocation, false);
400 data.ForcePathSeparatorStyle(true);
401 result = GlobalSettings::Save();
402 if(result != success)
403 PrintLn("Error saving IDE settings");
404 if(portable && moduleLocation[0] && FileExists(moduleLocation).isDirectory)
405 data.ManagePortablePaths(moduleLocation, true);
407 FileGetSize(settingsFilePath, &settingsFileSize);
412 class IDESettings : GlobalSettingsData
415 List<CompilerConfig> compilerConfigs { };
416 Array<String> recentFiles { };
417 Array<String> recentProjects { };
418 property char * docDir
420 set { delete docDir; if(value && value[0]) docDir = CopyString(value); }
421 get { return docDir ? docDir : ""; }
422 isset { return docDir && docDir[0]; }
424 property char * ideFileDialogLocation
426 set { delete ideFileDialogLocation; if(value && value[0]) ideFileDialogLocation = CopyString(value); }
427 get { return ideFileDialogLocation ? ideFileDialogLocation : ""; }
428 isset { return ideFileDialogLocation && ideFileDialogLocation[0]; }
430 property char * ideProjectFileDialogLocation
432 set { delete ideProjectFileDialogLocation; if(value && value[0]) ideProjectFileDialogLocation = CopyString(value); }
433 get { return ideProjectFileDialogLocation ? ideProjectFileDialogLocation : ""; }
434 isset { return ideProjectFileDialogLocation && ideProjectFileDialogLocation[0]; }
437 bool showLineNumbers;
438 bool caretFollowsScrolling;
439 char * displayDriver;
441 // TODO: Classify settings
442 //EditorSettings editor { };
444 property char * projectDefaultTargetDir
446 set { delete projectDefaultTargetDir; if(value && value[0]) projectDefaultTargetDir = CopyValidateMakefilePath(value); }
447 get { return projectDefaultTargetDir ? projectDefaultTargetDir : ""; }
448 isset { return projectDefaultTargetDir && projectDefaultTargetDir[0]; }
450 property char * projectDefaultIntermediateObjDir
452 set { delete projectDefaultIntermediateObjDir; if(value && value[0]) projectDefaultIntermediateObjDir = CopyValidateMakefilePath(value); }
453 get { return projectDefaultIntermediateObjDir ? projectDefaultIntermediateObjDir : ""; }
454 isset { return projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0]; }
457 property char * compilerConfigsDir
459 set { delete compilerConfigsDir; if(value && value[0]) compilerConfigsDir = CopyString(value); }
460 get { return compilerConfigsDir ? compilerConfigsDir : ""; }
461 isset { return compilerConfigsDir && compilerConfigsDir[0]; }
464 property char * defaultCompiler
466 set { delete defaultCompiler; if(value && value[0]) defaultCompiler = CopyString(value); }
467 get { return defaultCompiler && defaultCompiler[0] ? defaultCompiler : defaultCompilerName; }
468 isset { return defaultCompiler && defaultCompiler[0]; }
471 property String language
476 language = CopyString(value);
478 get { return language; }
479 isset { return language != null; }
484 char * ideFileDialogLocation;
485 char * ideProjectFileDialogLocation;
486 char * projectDefaultTargetDir;
487 char * projectDefaultIntermediateObjDir;
488 char * compilerConfigsDir;
489 char * defaultCompiler;
492 CompilerConfig GetCompilerConfig(String compilerName)
494 char * name = compilerName && compilerName[0] ? compilerName : defaultCompilerName;
495 CompilerConfig compilerConfig = null;
496 for(compiler : compilerConfigs)
498 if(!strcmp(compiler.name, name))
500 compilerConfig = compiler;
504 if(!compilerConfig && compilerConfigs.count)
505 compilerConfig = compilerConfigs.firstIterator.data;
507 incref compilerConfig;
508 return compilerConfig;
513 compilerConfigs.Free();
514 delete compilerConfigs;
517 recentProjects.Free();
518 delete recentProjects;
521 delete projectDefaultTargetDir;
522 delete projectDefaultIntermediateObjDir;
523 delete compilerConfigsDir;
524 delete defaultCompiler;
526 delete ideFileDialogLocation;
527 delete ideProjectFileDialogLocation;
528 delete displayDriver;
531 void ForcePathSeparatorStyle(bool unixStyle)
535 from = '\\', to = '/';
537 from = '/', to = '\\';
538 if(compilerConfigs && compilerConfigs.count)
541 for(config : compilerConfigs)
543 if(config.includeDirs && config.includeDirs.count)
545 for(i = 0; i < config.includeDirs.count; i++)
547 if(config.includeDirs[i] && config.includeDirs[i][0])
548 ChangeCh(config.includeDirs[i], from, to);
551 if(config.libraryDirs && config.libraryDirs.count)
553 for(i = 0; i < config.libraryDirs.count; i++)
555 if(config.libraryDirs[i] && config.libraryDirs[i][0])
556 ChangeCh(config.libraryDirs[i], from, to);
559 if(config.executableDirs && config.executableDirs.count)
561 for(i = 0; i < config.executableDirs.count; i++)
563 if(config.executableDirs[i] && config.executableDirs[i][0])
564 ChangeCh(config.executableDirs[i], from, to);
569 if(recentFiles && recentFiles.count)
572 for(c = 0; c < recentFiles.count; c++)
574 if(recentFiles[c] && recentFiles[c][0])
575 ChangeCh(recentFiles[c], from, to);
578 if(recentProjects && recentProjects.count)
581 for(c = 0; c < recentProjects.count; c++)
583 if(recentProjects[c] && recentProjects[c][0])
584 ChangeCh(recentProjects[c], from, to);
587 if(docDir && docDir[0])
588 ChangeCh(docDir, from, to);
589 if(ideFileDialogLocation && ideFileDialogLocation[0])
590 ChangeCh(ideFileDialogLocation, from, to);
591 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
592 ChangeCh(ideProjectFileDialogLocation, from, to);
594 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
595 ChangeCh(projectDefaultTargetDir, from, to);
596 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
597 ChangeCh(projectDefaultIntermediateObjDir, from, to);
599 if(compilerConfigsDir && compilerConfigsDir[0])
600 ChangeCh(compilerConfigsDir, from, to);
603 void ManagePortablePaths(char * location, bool makeAbsolute)
606 if(compilerConfigs && compilerConfigs.count)
608 for(config : compilerConfigs)
611 for(t = 0; t < DirTypes::enumSize; t++)
613 Array<String> dirs = null;
614 if(t == executables) dirs = config.executableDirs;
615 else if(t == includes) dirs = config.includeDirs;
616 else if(t == libraries) dirs = config.libraryDirs;
617 if(dirs && dirs.count)
619 for(c = 0; c < dirs.count; c++)
621 if(dirs[c] && dirs[c][0])
622 dirs[c] = UpdatePortablePath(dirs[c], location, makeAbsolute);
628 if(recentFiles && recentFiles.count)
630 for(c = 0; c < recentFiles.count; c++)
632 if(recentFiles[c] && recentFiles[c][0])
633 recentFiles[c] = UpdatePortablePath(recentFiles[c], location, makeAbsolute);
636 if(recentProjects && recentProjects.count)
638 for(c = 0; c < recentProjects.count; c++)
640 if(recentProjects[c] && recentProjects[c][0])
641 recentProjects[c] = UpdatePortablePath(recentProjects[c], location, makeAbsolute);
644 if(docDir && docDir[0])
645 docDir = UpdatePortablePath(docDir, location, makeAbsolute);
646 if(ideFileDialogLocation && ideFileDialogLocation[0])
647 ideFileDialogLocation = UpdatePortablePath(ideFileDialogLocation, location, makeAbsolute);
648 if(ideProjectFileDialogLocation && ideProjectFileDialogLocation[0])
649 ideProjectFileDialogLocation = UpdatePortablePath(ideProjectFileDialogLocation, location, makeAbsolute);
651 if(projectDefaultTargetDir && projectDefaultTargetDir[0])
652 projectDefaultTargetDir = UpdatePortablePath(projectDefaultTargetDir, location, makeAbsolute);
653 if(projectDefaultIntermediateObjDir && projectDefaultIntermediateObjDir[0])
654 projectDefaultIntermediateObjDir = UpdatePortablePath(projectDefaultIntermediateObjDir, location, makeAbsolute);
656 if(compilerConfigsDir && compilerConfigsDir[0])
657 compilerConfigsDir = UpdatePortablePath(compilerConfigsDir, location, makeAbsolute);
660 char * UpdatePortablePath(char * path, char * location, bool makeAbsolute)
665 char p[MAX_LOCATION];
667 PathCatSlash(p, path);
669 output = CopyString(p);
673 PathRelationship rel = eString_PathRelated(path, location, null);
674 if(rel == subPath || rel == identical)
676 char p[MAX_LOCATION];
677 MakePathRelative(path, location, p);
678 if(!*p) strcpy(p, "./");
679 else ChangeCh(p, '\\', '/');
681 output = CopyString(p);
689 void AddRecentFile(char * fileName)
692 char * filePath = CopyString(fileName);
693 ChangeCh(filePath, '\\', '/');
694 for(c = 0; c<recentFiles.count; c++)
696 if(recentFiles[c] && !fstrcmp(recentFiles[c], filePath))
698 recentFiles.Delete((void *)&recentFiles[c]);
702 while(recentFiles.count >= MaxRecent)
703 recentFiles.Delete(recentFiles.GetLast());
704 recentFiles.Insert(null, filePath);
705 //UpdateRecentMenus(owner);
708 void AddRecentProject(char * projectName)
711 char * filePath = CopyString(projectName);
712 ChangeCh(filePath, '\\', '/');
713 for(c = 0; c<recentProjects.count; c++)
715 if(recentProjects[c] && !fstrcmp(recentProjects[c], filePath))
717 recentProjects.Delete((void *)&recentProjects[c]);
721 while(recentProjects.count >= MaxRecent)
722 recentProjects.Delete(recentProjects.GetLast());
723 recentProjects.Insert(null, filePath);
724 //UpdateRecentMenus(owner);
728 static const char * compilerTypeNames[CompilerType] = { "GCC", "TCC", "PCC", "VS8", "VS9", "VS10" };
729 static const char * compilerTypeVersionString[CompilerType] = { "", "", "", "8.00", "9.00", "10.00" };
730 static const char * compilerTypeSolutionFileVersionString[CompilerType] = { "", "", "", "9.00", "10.00", "11.00" };
731 static const char * compilerTypeYearString[CompilerType] = { "", "", "", "2005", "2008", "2010" };
732 static const char * compilerTypeProjectFileExtension[CompilerType] = { "", "", "", "vcproj", "vcproj", "vcxproj" };
733 // TODO: i18n with Array
734 static Array<String> compilerTypeLongNames
736 $"GNU Compiler Collection (GCC) / GNU Make",
737 $"Tiny C Compiler / GNU Make",
738 $"Portable C Compiler / GNU Make",
739 $"Microsoft Visual Studio 2005 (8.0) Compiler",
740 $"Microsoft Visual Studio 2008 (9.0) Compiler",
741 $"Microsoft Visual Studio 2010 (10.0) Compiler"
743 const CompilerType firstCompilerType = gcc;
744 const CompilerType lastCompilerType = vs10;
745 public enum CompilerType
747 gcc, tcc, pcc, vs8, vs9, vs10;
751 get { return this == vs8 || this == vs9 || this == vs10; }
756 get { return OnGetString(null, null, null); }
762 for(c = firstCompilerType; c <= lastCompilerType; c++)
763 if(!strcmpi(value, compilerTypeNames[c]))
770 property char * longName { get { return OnGetString(null, (void*)1, null); } };
771 property char * versionString { get { return OnGetString(null, (void*)2, null); } };
772 property char * yearString { get { return OnGetString(null, (void*)3, null); } };
773 property char * projectFileExtension { get { return OnGetString(null, (void*)4, null); } };
774 property char * solutionFileVersionString { get { return OnGetString(null, (void*)5, null); } };
776 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
778 if(this >= firstCompilerType && this <= lastCompilerType)
781 strcpy(tempString, compilerTypeNames[this]);
782 if(fieldData == null)
783 return compilerTypeNames[this];
784 else if(fieldData == (void*)1)
785 return compilerTypeLongNames[this];
786 else if(fieldData == (void*)2)
787 return compilerTypeVersionString[this];
788 else if(fieldData == (void*)3)
789 return compilerTypeYearString[this];
790 else if(fieldData == (void*)4)
791 return compilerTypeProjectFileExtension[this];
792 else if(fieldData == (void*)5)
793 return compilerTypeSolutionFileVersionString[this];
811 name = CopyString(value);
817 Platform targetPlatform;
819 property char * makeCommand
821 set { delete makeCommand; if(value && value[0]) makeCommand = CopyString(value); }
822 get { return makeCommand; }
823 isset { return makeCommand && makeCommand[0]; }
825 property char * ecpCommand
827 set { delete ecpCommand; if(value && value[0]) ecpCommand = CopyString(value); }
828 get { return ecpCommand; }
829 isset { return ecpCommand && ecpCommand[0]; }
831 property char * eccCommand
833 set { delete eccCommand; if(value && value[0]) eccCommand = CopyString(value); }
834 get { return eccCommand; }
835 isset { return eccCommand && eccCommand[0]; }
837 property char * ecsCommand
839 set { delete ecsCommand; if(value && value[0]) ecsCommand = CopyString(value); }
840 get { return ecsCommand; }
841 isset { return ecsCommand && ecsCommand[0]; }
843 property char * earCommand
845 set { delete earCommand; if(value && value[0]) earCommand = CopyString(value); }
846 get { return earCommand; }
847 isset { return earCommand && earCommand[0]; }
849 property char * cppCommand
851 set { delete cppCommand; if(value && value[0]) cppCommand = CopyString(value); }
852 get { return cppCommand; }
853 isset { return cppCommand && cppCommand[0]; }
855 property char * ccCommand
857 set { delete ccCommand; if(value && value[0]) ccCommand = CopyString(value); }
858 get { return ccCommand; }
859 isset { return ccCommand && ccCommand[0]; }
861 property char * cxxCommand
863 set { delete cxxCommand; if(value && value[0]) cxxCommand = CopyString(value); }
864 get { return cxxCommand; }
865 isset { return cxxCommand && cxxCommand[0]; }
867 property char * execPrefixCommand // <-- old name for json ide settings file compatibility
869 set { delete executableLauncher; if(value && value[0]) executableLauncher = CopyString(value); }
870 get { return executableLauncher; }
871 isset { return executableLauncher && executableLauncher[0]; }
873 // TODO: implement CompilerConfig::windresCommand
877 property bool supportsBitDepth { set { } get { return true; } isset { return false; } }
879 property char * distccHosts
881 set { delete distccHosts; if(value && value[0]) distccHosts = CopyString(value); }
882 get { return distccHosts; }
883 isset { return distccHosts && distccHosts[0]; }
885 property char * gccPrefix // <-- old name for json ide settings file compatibility
887 set { delete gnuToolchainPrefix; if(value && value[0]) gnuToolchainPrefix = CopyString(value); }
888 get { return gnuToolchainPrefix; }
889 isset { return gnuToolchainPrefix && gnuToolchainPrefix[0]; }
891 property char * sysroot
893 set { delete sysroot; if(value && value[0]) sysroot = CopyString(value); }
894 get { return sysroot; }
895 isset { return sysroot && sysroot[0]; }
897 property Array<String> includeDirs
908 get { return includeDirs; }
909 isset { return includeDirs.count != 0; }
911 property Array<String> libraryDirs
922 get { return libraryDirs; }
923 isset { return libraryDirs.count != 0; }
925 property Array<String> executableDirs
929 executableDirs.Free();
932 delete executableDirs;
933 executableDirs = value;
936 get { return executableDirs; }
937 isset { return executableDirs.count != 0; }
939 property Array<NamedString> environmentVars
943 environmentVars.Free();
946 delete environmentVars;
947 environmentVars = value;
950 get { return environmentVars; }
951 isset { return environmentVars.count != 0; }
953 property Array<String> prepDirectives
957 prepDirectives.Free();
960 delete prepDirectives;
961 prepDirectives = value;
964 get { return prepDirectives; }
965 isset { return prepDirectives.count != 0; }
967 property Array<String> excludeLibs
978 get { return excludeLibs; }
979 isset { return excludeLibs.count != 0; }
981 property Array<String> eCcompilerFlags
985 eCcompilerFlags.Free();
988 delete eCcompilerFlags;
989 eCcompilerFlags = value;
992 get { return eCcompilerFlags; }
993 isset { return eCcompilerFlags.count != 0; }
995 property Array<String> compilerFlags
999 compilerFlags.Free();
1002 delete compilerFlags;
1003 compilerFlags = value;
1006 get { return compilerFlags; }
1007 isset { return compilerFlags.count != 0; }
1009 property Array<String> linkerFlags
1017 linkerFlags = value;
1020 get { return linkerFlags; }
1021 isset { return linkerFlags.count != 0; }
1024 Array<String> includeDirs { };
1025 Array<String> libraryDirs { };
1026 Array<String> executableDirs { };
1027 // TODO: Can JSON parse and serialize maps?
1028 //EnvironmentVariables { };
1029 Array<NamedString> environmentVars { };
1030 Array<String> prepDirectives { };
1031 Array<String> excludeLibs { };
1032 Array<String> eCcompilerFlags { };
1033 Array<String> compilerFlags { };
1034 Array<String> linkerFlags { };
1044 char * executableLauncher;
1046 char * gnuToolchainPrefix;
1050 struct { Array<String> includes, libraries, executables; };
1051 Array<String> dirs[DirTypes];
1065 delete executableLauncher;
1067 delete gnuToolchainPrefix;
1069 if(environmentVars) environmentVars.Free();
1070 if(includeDirs) { includeDirs.Free(); }
1071 if(libraryDirs) { libraryDirs.Free(); }
1072 if(executableDirs) { executableDirs.Free(); }
1073 if(prepDirectives) { prepDirectives.Free(); }
1074 if(excludeLibs) { excludeLibs.Free(); }
1075 if(compilerFlags) { compilerFlags.Free(); }
1076 if(eCcompilerFlags) { eCcompilerFlags.Free(); }
1077 if(linkerFlags) { linkerFlags.Free(); }
1079 CompilerConfig Copy()
1104 for(s : includeDirs) copy.includeDirs.Add(CopyString(s));
1105 for(s : libraryDirs) copy.libraryDirs.Add(CopyString(s));
1106 for(s : executableDirs) copy.executableDirs.Add(CopyString(s));
1107 for(ns : environmentVars) copy.environmentVars.Add(NamedString { name = ns.name, string = ns.string });
1108 for(s : prepDirectives) copy.prepDirectives.Add(CopyString(s));
1109 for(s : excludeLibs) copy.excludeLibs.Add(CopyString(s));
1110 for(s : compilerFlags) copy.compilerFlags.Add(CopyString(s));
1111 for(s : eCcompilerFlags) copy.eCcompilerFlags.Add(CopyString(s));
1112 for(s : linkerFlags) copy.linkerFlags.Add(CopyString(s));
1119 struct LanguageOption
1126 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
1131 void OnDisplay(Surface surface, int x, int y, int width, void * data, Alignment alignment, DataDisplayFlags flags)
1133 Bitmap icon = res ? res.bitmap : null;
1136 surface.Blit(icon, x + (16 - icon.width) / 2,y+2,0,0, icon.width, icon.height);
1137 class::OnDisplay(surface, x + w, y, width - w, null, alignment, flags);
1141 Array<LanguageOption> languages
1143 { "English", ":countryCode/gb.png", "" },
1144 { "汉语", ":countryCode/cn.png", "zh_CN" },
1145 { "Español", ":countryCode/es.png", "es_ES" },
1146 { "Русский (43%)", ":countryCode/ru.png", "ru_RU" },
1147 { "Português (28%)", ":countryCode/pt.png", "pt_BR" },
1148 { "Nederlandse (13%)", ":countryCode/nl.png", "nl_NL" },
1149 { "Tiếng Việt (12%)", ":countryCode/vn.png", "vi_VI" },
1150 { "मराठी (10%)", ":countryCode/in.png", "mr_MR" },
1151 { "Hebrew (8%)", ":countryCode/il.png", "he_HE" },
1152 { "Magyar (8%)", ":countryCode/hu.png", "hu_HU" }
1155 String GetLanguageString()
1157 String language = getenv("LANGUAGE");
1158 if(!language) language = getenv("LC_ALL");
1159 if(!language) language = getenv("LC_MESSAGES");
1160 if(!language) language = getenv("LANG");
1161 if(!language) language = "";
1165 bool LanguageRestart(char * code, Application app, IDESettings settings, IDESettingsContainer settingsContainer, Window ide, Window projectView, bool wait)
1167 bool restart = true;
1168 String command = null;
1169 int arg0Len = strlen(app.argv[0]);
1181 for(w = ide.firstChild; w; w = w.next)
1183 if(w.isActiveClient && w.isDocument)
1185 if(!w.CloseConfirmation(true))
1194 if(!projectView.CloseConfirmation(true))
1196 if(projectView.fileName)
1198 char * name = projectView.fileName;
1201 for(j = 0; (ch = name[j]); j++)
1202 len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
1206 command = new char[len + 1];
1208 strcpy(command, app.argv[0]);
1210 if(projectView.fileName)
1212 strcat(command, " ");
1214 ReplaceSpaces(command + len, projectView.fileName);
1219 for(w = ide.firstChild; w; w = w.next)
1220 if(w.isActiveClient && w.isDocument)
1221 w.modifiedDocument = false;
1222 projectView.modifiedDocument = false;
1227 for(w = ide.firstChild; w; w = w.next)
1229 if(w.isActiveClient && w.isDocument)
1231 if(!w.CloseConfirmation(true))
1238 char * name = w.fileName;
1240 for(j = 0; (ch = name[j]); j++)
1241 len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
1248 command = new char[len + 1];
1249 strcpy(command, app.argv[0]);
1252 for(w = ide.firstChild; w; w = w.next)
1254 if(w.isActiveClient && w.isDocument)
1256 char * name = w.fileName;
1259 strcat(command, " ");
1261 ReplaceSpaces(command + len, name);
1262 len = strlen(command);
1269 for(w = ide.firstChild; w; w = w.next)
1270 if(w.isActiveClient && w.isDocument)
1271 w.modifiedDocument = false;
1276 settings.language = code;
1277 settingsContainer.Save();
1278 if(eClass_IsDerived(app._class, class(GuiApplication)))
1280 GuiApplication guiApp = (GuiApplication)app;
1281 guiApp.desktop.Destroy(0);
1288 for(i = 1; i < app.argc; i++)
1290 char * arg = app.argv[i];
1292 for(j = 0; (ch = arg[j]); j++)
1293 len += (ch == ' ' || ch == '\"' || ch == '&' || ch == '$' || ch == '(' || ch == ')') ? 2 : 1;
1296 command = new char[len + 1];
1297 strcpy(command, app.argv[0]);
1299 for(i = 1; i < app.argc; i++)
1301 strcat(command, " ");
1303 ReplaceSpaces(command + len, app.argv[i]);
1304 len = strlen(command);
1310 SetEnvironment("LANGUAGE", code);
1312 ExecuteWait(command);