5 import "SettingsDialog"
7 static Context globalContext { };
8 static OldList defines { };
9 static OldList imports { };
10 static NameSpace globalData;
11 static OldList excludedSymbols { offset = (uint)&((Symbol)0).left };
14 define app = (GuiApplication)__thisModule.application;
16 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
19 /*extern */int __ecereVMethodID_class_OnGetString;
26 a.OnGetString(null, null, null);
29 static bool editing = true;
31 enum CodeObjectType { typeClass, typeData, typeMethod, typeEvent, typeProperty, typeNameSpace, typeDataType, typeEnumValue, typeDataPrivate, typeMethodPrivate, typePropertyPrivate };
33 static char * iconNames[CodeObjectType] =
35 "<:ecere>constructs/class.png",
36 "<:ecere>constructs/data.png",
37 "<:ecere>constructs/method.png",
38 "<:ecere>constructs/event.png",
39 "<:ecere>constructs/property.png",
40 "<:ecere>constructs/namespace.png",
41 "<:ecere>constructs/dataType.png",
42 "<:ecere>constructs/enumValue.png",
43 "<:ecere>constructs/dataPrivate.png",
44 "<:ecere>constructs/methodPrivate.png",
45 "<:ecere>constructs/propertyPrivate.png"
48 IDESettings settings { }; // instantiate the IDESettings class from the IDESettings.ec file. Do this at a global level so that all methods can access settings.
50 IDESettingsContainer settingsContainer
54 dataOwner = &settings;
57 // WARNING : This function expects a null terminated string since it recursively concatenate...
58 static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
65 if(type._class && type._class.string)
68 strcat(string, type._class.string);
71 if(type._class.registered)
74 sprintf(hex, "%p", type._class.registered);
75 strcat(string, "<a href=\"api://");
77 strcat(string, "\" style=\"text-decoration: none;\">");
78 strcat(string, type._class.registered.name);
79 strcat(string, "</a>");
82 strcat(string, type._class.string);
89 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
90 if(funcType && funcType.kind == functionType)
93 DocPrintType(funcType.returnType, string, false, fullName);
95 if(printName || funcType.thisClass)
98 if(funcType.thisClass)
100 strcat(string, funcType.thisClass.string);
101 strcat(string, "::");
104 strcat(string, type.name);
106 strcat(string, ")(");
107 for(param = funcType.params.first; param; param = param.next)
109 DocPrintType(param, string, false, fullName);
110 if(param.next) strcat(string, ", ");
116 _PrintType(type.type, string, false /*printName*/, printFunction, fullName);
117 if(string[strlen(string)-1] == '(')
120 strcat(string, " *");
124 case voidType: strcat(string, "void"); break;
125 case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
126 case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
127 case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
128 case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
129 case floatType: strcat(string, "float"); break;
130 case doubleType: strcat(string, "double"); break;
134 strcat(string, "struct ");
135 strcat(string, type.enumName);
137 else if(type.typeName)
139 strcat(string, type.typeName);
144 strcat(string, "struct ");
145 strcat(string,"(unnamed)");
148 strcat(string, "struct {");
149 for(member = type.members.first; member; member = member.next)
151 DocPrintType(member, string, true, fullName);
160 strcat(string, "union ");
161 strcat(string, type.enumName);
163 else if(type.typeName)
165 strcat(string, type.typeName);
169 strcat(string, "union ");
170 strcat(string,"(unnamed)");
176 strcat(string, "enum ");
177 strcat(string, type.enumName);
179 else if(type.typeName)
181 strcat(string, type.typeName);
184 strcat(string, "enum");
191 strcat(string, "dllexport ");
192 DocPrintType(type.returnType, string, false, fullName);
196 // DANGER: Testing This
202 strcat(string, type.name);
205 char * name = RSearchString(type.name, "::", strlen(type.name), true, false);
206 if(name) name += 2; else name = type.name;
207 strcat(string, "<b>");
208 strcat(string, name);
209 strcat(string, "</b>");
222 for(param = type.params.first; param; param = param.next)
224 DocPrintType(param, string, true, fullName);
225 if(param.next) strcat(string, ", ");
234 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
235 if(funcType && funcType.kind == functionType)
238 DocPrintType(funcType.returnType, string, false, fullName);
239 strcat(string, "(*");
240 if(printName || funcType.thisClass)
243 if(funcType.thisClass)
245 strcat(string, funcType.thisClass.string);
246 strcat(string, "::");
249 strcat(string, type.name);
251 strcat(string, ")(");
252 for(param = funcType.params.first; param; param = param.next)
254 DocPrintType(param, string, false, fullName);
255 if(param.next) strcat(string, ", ");
261 char baseType[1024], size[256];
262 Type arrayType = type;
266 while(arrayType.kind == TypeKind::arrayType)
269 if(arrayType.enumClass)
270 strcat(size, arrayType.enumClass.string);
271 else if(arrayType.arraySizeExp)
272 PrintExpression(arrayType.arraySizeExp, size);
273 //sprintf(string, "%s[%s]", baseType, size);
276 arrayType = arrayType.arrayType;
278 _PrintType(arrayType, baseType, printName, printFunction, fullName);
279 strcat(string, baseType);
280 strcat(string, size);
284 DocPrintType(type.arrayType, baseType, printName, fullName);
286 strcpy(size, type.enumClass.string);
287 else if(type.arraySizeExp)
288 PrintExpression(type.arraySizeExp, size);
289 //sprintf(string, "%s[%s]", baseType, size);
290 strcat(string, baseType);
292 strcat(string, size);
300 strcat(string, "...");
303 _PrintType(type.method.dataType, string, false, printFunction, fullName);
306 strcat(string, "subclass(");
307 strcat(string, type._class ? type._class.string : "int");
313 if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
316 strcat(string, type.name);
321 void DocPrintType(Type type, char * string, bool printName, bool fullName)
324 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
325 if(funcType && funcType.kind == functionType && type != funcType)
327 char typeString[1024];
330 DocPrintType(funcType.returnType, string, false, fullName);
332 _PrintType(type, string, printName, false, fullName);
336 strcat(string, type.name);
343 for(param = funcType.params.first; param; param = param.next)
345 DocPrintType(param, string, true, fullName);
346 if(param.next) strcat(string, ", ");
351 _PrintType(type, string, printName, true, fullName);
354 void AddComponents(Module module, bool isDll)
359 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
361 row = mainForm.browser.AddRow();
362 row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
363 row.tag = (int64)null;
364 AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
367 for(m = module.modules.first; m; m = m.next)
369 if(m.importMode == publicAccess || !isDll)
370 AddComponents(m.module, true);
373 // PUT MODULE DESCRIPTION HERE
374 if(module.name && strcmp(module.name, "ecereCOM"))
376 row = mainForm.browser.AddRow();
377 row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
378 row.tag = (int64)module;
379 AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
381 AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
393 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
398 virtual void Generate(File f)
403 virtual Module GetModule()
405 return page ? page.GetModule() : null;
408 virtual NameSpace * GetNameSpace()
410 return page ? page.GetNameSpace() : null;
414 enum DocumentationType
422 enum DocumentationItem
438 static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
440 NameSpace * nameSpace, * ns;
442 Method method = null;
443 GlobalFunction function = null;
444 char nsName[1024], temp[1024];
450 case nameSpaceDoc: nameSpace = object; break;
451 case classDoc: cl = (Class)object; nameSpace = cl.nameSpace; break;
452 case functionDoc: function = object; nameSpace = function.nameSpace; break;
453 case methodDoc: method = object; cl = method._class; nameSpace = cl.nameSpace; break;
458 while(ns && ns->name)
460 strcpy(temp, "namespaces/");
461 strcat(temp, ns->name);
463 strcat(temp, nsName);
464 strcpy(nsName, temp);
467 sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
468 if(strchr(docFile, DIR_SEP))
470 GetLastDirectory(docFile, temp);
471 strcpy(docFile, temp);
474 sprintf(fileName, "<%s/%s>", settings.docDir, docFile); // Note that in the ecereIDE.ini file, there can be no quotes around the path, and there needs to be the final backslash. Otherwise this does not work.
475 strcat(fileName, nsName);
479 strcat(fileName, "classes/");
480 strcat(fileName, cl.name);
481 strcat(fileName, "/");
486 strcat(fileName, "methods/");
487 strcat(fileName, method.name);
488 strcat(fileName, "/");
492 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
493 if(name) name += 2; else name = function.name;
494 strcat(fileName, "functions/");
495 strcat(fileName, name);
496 strcat(fileName, "/");
501 case description: strcat(fileName, "description"); break;
502 case usage: strcat(fileName, "usage"); break;
503 case remarks: strcat(fileName, "remarks"); break;
504 case example: strcat(fileName, "example"); break;
505 case seeAlso: strcat(fileName, "seeAlso"); break;
506 case returnValue: strcat(fileName, "returnValue"); break;
507 case enumerationValue:
508 strcat(fileName, "enumeration values/");
509 strcat(fileName, ((NamedLink)data).name);
512 strcat(fileName, "definitions/");
513 strcat(fileName, ((Definition)data).name);
517 char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
518 if(name) name += 2; else name = ((Property)data).name;
519 strcat(fileName, "conversions/");
520 strcat(fileName, name);
523 case memberDescription:
524 strcat(fileName, "data members/");
525 strcat(fileName, ((DataMember)data).name);
527 case propertyDescription:
528 strcat(fileName, "properties/");
529 strcat(fileName, ((Property)data).name);
536 strcat(fileName, "parameters/");
537 for(prev = data, count = 0; prev; prev = prev.prev, count++);
538 sprintf(name, "%s.%d", ((Type)data).name, count);
539 strcat(fileName, name);
545 static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
547 char fileName[MAX_LOCATION];
548 String contents = null;
551 FigureFileName(fileName, module, type, object, item, data);
552 file = FileOpen(fileName, read);
556 if((len = file.GetSize()))
558 contents = new char[len+1];
559 file.Read(contents, 1, len);
560 contents[len] = '\0';
567 for(c = 0; contents[c]; c++)
568 if(!isspace(contents[c])) break;
572 if(editing && !contents && !readOnly)
573 contents = CopyString($"[Add Text]");
577 class APIPageNameSpace : APIPage
579 NameSpace * nameSpace;
587 NameSpace * GetNameSpace()
592 void Generate(File f)
595 char nsName[1024], temp[1024];
602 while(ns && ns->name)
604 strcpy(temp, ns->name);
605 if(nsName[0]) strcat(temp, "::");
606 strcat(temp, nsName);
607 strcpy(nsName, temp);
610 // Generate Class Page
611 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
614 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
615 tag = (uint)nameSpace;
616 f.Printf($"Module: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
620 tag = (uint)((!module || !module.name || !strcmp(nsName, "ecere::com") ? null : module));
621 f.Printf($"<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
625 ns = nameSpace->parent;
626 while(ns && ns->name)
628 strcpy(temp, ns->name);
629 if(nsName[0]) strcat(temp, "::");
630 strcat(temp, nsName);
631 strcpy(nsName, temp);
635 f.Printf($"Parent namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
639 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
642 f.Printf($"<H3>Description</H3><br><br>\n");
645 char fileName[MAX_LOCATION];
646 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
647 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
649 f.Printf("</a><br><br>");
652 f.Printf("%s<br><br>", desc);
657 if(nameSpace->nameSpaces.first)
660 for(ns = (NameSpace *)nameSpace->nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
662 char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
665 f.Printf($"<H3>Sub Namespaces</H3><br><br>\n");
666 f.Printf("<TABLE>\n");
670 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeNameSpace], ns, ns->name);
675 char fileName[MAX_LOCATION];
676 FigureFileName(fileName, module, nameSpaceDoc, ns, description, null);
677 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
679 f.Printf("</a></TD>");
682 f.Printf("<TD valign=top height=22> %s</TD>", desc);
685 f.Printf("</TR><br>\n");
688 f.Printf("</TABLE><br>\n");
691 if(nameSpace->classes.first)
694 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
696 Class cl = link.data;
697 if(!cl.templateClass)
699 char * desc = ReadDoc(module, classDoc, cl, description, null);
703 f.Printf($"<a name=Classes></a><H3>Classes</H3><br><br>\n");
704 f.Printf("<TABLE>\n");
710 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a></TD>", (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? iconNames[typeDataType] : iconNames[typeClass], cl, cl.name);
715 char fileName[MAX_LOCATION];
716 FigureFileName(fileName, module, classDoc, cl, description, null);
717 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
719 f.Printf("</a></TD>");
722 f.Printf("<TD valign=top height=22>%s</TD>", desc);
729 f.Printf("</TABLE><br>\n");
732 if(nameSpace->functions.first)
735 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
737 GlobalFunction function = link.data;
738 char * desc = ReadDoc(module, functionDoc, function, description, null);
739 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
740 if(name) name += 2; else name = function.name;
743 f.Printf($"<a name=Functions></a><H3>Functions</H3><br><br>\n");
744 f.Printf("<TABLE>\n");
748 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeMethod], function, name);
753 char fileName[MAX_LOCATION];
754 FigureFileName(fileName, module, functionDoc, function, description, null);
755 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
757 f.Printf("</a></TD>");
760 f.Printf("<TD valign=top height=22> %s</TD>", desc);
763 f.Printf("</TR><br>\n");
766 f.Printf("</TABLE><br>\n");
769 if(nameSpace->defines.first)
772 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
774 DefinedExpression def = link.data;
775 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
778 f.Printf($"<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
779 f.Printf("<TABLE>\n");
783 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", def, iconNames[typeData], def.name);
784 f.Printf("<TD valign=top height=22>%s</TD>", def.value);
789 char fileName[MAX_LOCATION];
790 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, definition, def);
791 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
793 f.Printf("</a></TD>");
796 f.Printf("<TD valign=top height=22> %s</TD>", desc);
799 f.Printf("</TR><br>\n");
802 f.Printf("</TABLE><br>\n");
805 f.Printf("</FONT></BODY></HTML>\n");
809 class APIPageClass : APIPage
818 NameSpace * GetNameSpace()
823 void Generate(File f)
829 char nsName[1024], temp[1024];
830 NameSpace * ns = cl.nameSpace;
831 Module module = cl.module;
834 while(ns && ns->name)
836 strcpy(temp, ns->name);
837 if(nsName[0]) strcat(temp, "::");
838 strcat(temp, nsName);
839 strcpy(nsName, temp);
842 // Generate Class Page
843 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
844 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
846 f.Printf($"Module: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
848 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
851 char * classType = null;
855 classType = $"Bit Collection";
858 classType = $"Enumeration";
861 classType = $"Structure";
864 classType = $"Class";
867 classType = $"Class (No header)";
873 classType = $"Basic Data Type";
876 f.Printf($"Type: %s<br>\n", classType);
879 if(cl.type != systemClass && cl.base)
881 f.Printf($"Base Class: ");
882 if(!strcmp(cl.base.name, "struct") || !strcmp(cl.base.name, "class"))
884 f.Printf(cl.type == bitClass ? cl.dataTypeString : $"None");
886 else if(cl.type == enumClass && !strcmp(cl.base.name, "enum"))
887 f.Printf("%s", cl.dataTypeString);
889 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", cl.base.templateClass ? cl.base.templateClass : cl.base, cl.base.name);
894 char * desc = ReadDoc(module, classDoc, cl, description, null);
897 f.Printf($"<br><H3>Description</H3><br><br>\n");
900 char fileName[MAX_LOCATION];
901 FigureFileName(fileName, module, classDoc, cl, description, null);
902 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
904 f.Printf("</a><br><br>");
907 f.Printf("%s<br><br>", desc);
912 if(cl.type == enumClass)
914 EnumClassData enumeration = (EnumClassData)cl.data;
915 if(enumeration.values.first)
919 f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
920 f.Printf("<TABLE>\n");
922 for(item = enumeration.values.first; item; item = item.next)
924 char * desc = ReadDoc(module, classDoc, cl, enumerationValue, item);
925 bool needClass = true;
928 char tempString[1024];
930 while(base.type == enumClass) base = base.base;
932 if(base.type == systemClass ||
933 (base.type == bitClass && base.membersAndProperties.first && !strcmp(cl.fullName, ((DataMember)base.membersAndProperties.first).dataTypeString)))
936 base.dataType = ProcessTypeString(base.dataTypeString, false);
938 if(base.dataType.kind != classType)
943 PrintType(base.dataType, string, false, true);
944 classSym = FindClass(string);
945 dataClass = classSym ? classSym.registered : null;
948 dataClass = base.dataType._class ? base.dataType._class.registered : null;
954 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", item, iconNames[typeEnumValue], item.name);
955 if(dataClass.type == systemClass)
958 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)dataClass._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
961 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)eSystem_FindClass(componentsApp, "class")._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
963 f.Printf("<TD valign=top height=22 nowrap=1>%s { %s }</TD>", dataClass.name, s);
965 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", s);
970 char fileName[MAX_LOCATION];
971 FigureFileName(fileName, module, classDoc, cl, enumerationValue, item);
972 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
974 f.Printf("</a></TD>");
977 f.Printf("<TD valign=top height=22>%s</TD>", desc);
982 f.Printf("</TABLE><BR>\n");
986 if(cl.conversions.first)
988 f.Printf($"<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
989 f.Printf("<TABLE>\n");
990 for(prop = cl.conversions.first; prop; prop = prop.next)
992 if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
994 char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
997 Type type = ProcessTypeString(prop.name, false);
998 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
999 if(name) name += 2; else name = prop.name;
1004 DocPrintType(type, string, true, false);
1006 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeDataType], string);
1011 char fileName[MAX_LOCATION];
1012 FigureFileName(fileName, module, classDoc, cl, conversion, prop);
1013 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1015 f.Printf("</a></TD>");
1018 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1022 f.Printf("</TR>\n");
1027 f.Printf("</TABLE><br>\n");
1030 if(cl.membersAndProperties.first)
1033 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1035 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1039 f.Printf($"<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
1040 f.Printf("<TABLE>\n");
1046 char * desc = ReadDoc(module, classDoc, cl, propertyDescription, prop);
1048 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1052 DocPrintType(prop.dataType, string, true, false);
1054 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeProperty], prop.name);
1055 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
1060 char fileName[MAX_LOCATION];
1061 FigureFileName(fileName, module, classDoc, cl, propertyDescription, prop);
1062 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1064 f.Printf("</a></TD>");
1067 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1070 f.Printf("</TR>\n");
1074 AddDataMemberToPage(f, (DataMember)prop, 0, showPrivate);
1079 f.Printf("</TABLE><br>\n");
1082 if(cl.methods.first)
1086 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1088 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type == virtualMethod)
1090 char * desc = ReadDoc(module, methodDoc, method, description, null);
1093 f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
1094 f.Printf("<TABLE>\n");
1097 if(!method.dataType)
1098 ProcessMethodType(method);
1101 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a></TD>", method.dataType.thisClass ? iconNames[typeEvent] : iconNames[typeMethod], method, method.name);
1106 char fileName[MAX_LOCATION];
1107 FigureFileName(fileName, module, methodDoc, method, description, null);
1108 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1110 f.Printf("</a></TD>");
1113 f.Printf("<TD valign=top height=22> %s</TD>", desc);
1116 f.Printf("</TR><br>\n");
1120 f.Printf("</TABLE><br>\n");
1122 // Non-Virtual Methods
1124 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1126 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type != virtualMethod)
1128 char * desc = ReadDoc(module, methodDoc, method, description, null);
1131 f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
1132 f.Printf("<TABLE>\n");
1136 if(!method.dataType)
1137 ProcessMethodType(method);
1140 f.Printf("<TD valign=top height=22 nowrap=1><img valign=center src=\"%s\"> <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a></TD>", iconNames[typeMethod], method, method.name);
1145 char fileName[MAX_LOCATION];
1146 FigureFileName(fileName, module, methodDoc, method, description, null);
1147 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1149 f.Printf("</a></TD>");
1152 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1156 f.Printf("</TR><br>\n");
1160 f.Printf("</TABLE><br>\n");
1163 char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
1166 f.Printf($"<H3>Usage</H3><br>\n");
1169 char fileName[MAX_LOCATION];
1170 FigureFileName(fileName, module, classDoc, cl, usage, null);
1171 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1176 f.Printf("<br>%s\n", usageDoc);
1177 f.Printf("<br><br>\n");
1182 char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
1185 f.Printf($"<H3>Example</H3><br>\n");
1186 f.Printf($"<FONT face=\"Courier New\">\n");
1187 f.Printf("<br><TABLE>\n");
1190 char fileName[MAX_LOCATION];
1191 FigureFileName(fileName, module, classDoc, cl, example, null);
1192 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1194 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1197 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1199 f.Printf("</TABLE></FONT>\n");
1205 char * remarksDoc = ReadDoc(module, classDoc, cl, remarks, null);
1209 f.Printf($"<H3>Remarks</H3><br>\n");
1212 char fileName[MAX_LOCATION];
1213 FigureFileName(fileName, module, classDoc, cl, remarks, null);
1214 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1219 f.Printf("<br>%s\n", remarksDoc);
1220 f.Printf("<br><br>\n");
1225 if(cl.type != systemClass)
1229 for(c = cl.derivatives.first; c; c = c.next)
1231 Class deriv = c.data;
1232 // TO VERIFY: Does this properly check public status?
1233 if(eSystem_FindClass(componentsApp, deriv.fullName))
1237 f.Printf($"<H3>Derived Classes</H3><br>\n");
1243 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
1247 f.Printf("<br><br>\n");
1250 char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
1253 f.Printf($"<H3>See Also</H3><br>\n");
1256 char fileName[MAX_LOCATION];
1257 FigureFileName(fileName, module, classDoc, cl, seeAlso, null);
1258 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1263 f.Printf("<br>%s\n", seeAlsoDoc);
1264 f.Printf("<br><br>\n");
1268 f.Printf("</FONT></BODY></HTML>\n");
1272 class APIPageMethod : APIPage
1278 return method._class.module;
1281 NameSpace * GetNameSpace()
1283 return method._class.nameSpace;
1286 void Generate(File f)
1288 Class cl = method._class;
1290 Module module = cl.module;
1292 char nsName[1024], temp[1024];
1293 NameSpace * ns = cl.nameSpace;
1296 while(ns && ns->name)
1298 strcpy(temp, ns->name);
1299 if(nsName[0]) strcat(temp, "::");
1300 strcat(temp, nsName);
1301 strcpy(nsName, temp);
1305 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1306 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1308 f.Printf($"Module: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
1310 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
1311 f.Printf("Class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl, cl.name);
1312 if(method.dataType.staticMethod)
1314 f.Printf($"this pointer class: None<br>\n");
1316 else if(method.dataType.thisClass && method.dataType.thisClass.registered && (method.dataType.thisClass.registered != method._class || method.type == virtualMethod))
1318 f.Printf($"this pointer class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", method.dataType.thisClass.registered, method.dataType.thisClass.registered.name);
1321 // Generate Method Page
1323 if(!method.dataType.name)
1324 method.dataType.name = CopyString(method.name);
1325 DocPrintType(method.dataType, string, true, false);
1326 f.Printf("<br>%s", string);
1329 char * desc = ReadDoc(module, methodDoc, method, description, null);
1332 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1335 char fileName[MAX_LOCATION];
1336 FigureFileName(fileName, module, methodDoc, method, description, null);
1337 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1342 f.Printf("%s", desc);
1347 f.Printf("<br><br>\n");
1348 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1350 f.Printf($"<H3>Parameters</H3><br><br>\n");
1352 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1353 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1355 f.Printf("<TABLE valign=center>\n");
1358 for(param = method.dataType.params.first; param; param = param.next)
1360 // ADD DESCRIPTION HERE
1361 if(param.kind != voidType)
1363 char * desc = ReadDoc(module, methodDoc, method, parameter, param);
1366 DocPrintType(param, string, false, false);
1368 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1369 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1374 char fileName[MAX_LOCATION];
1375 FigureFileName(fileName, module, methodDoc, method, parameter, param);
1376 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1378 f.Printf("</a></TD>\n");
1381 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1385 f.Printf("</TR>\n");
1388 if(method.dataType.returnType && method.dataType.returnType.kind != voidType)
1390 char * desc = ReadDoc(module, methodDoc, method, returnValue, null);
1391 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1393 f.Printf("<TR><TD> </TD></TR>");
1396 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1398 DocPrintType(method.dataType.returnType, string, false, false);
1399 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1404 char fileName[MAX_LOCATION];
1405 FigureFileName(fileName, module, methodDoc, method, returnValue, null);
1406 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1408 f.Printf("</a> </TD>\n");
1411 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1414 f.Printf("</TR>\n");
1415 f.Printf("</TABLE>\n");
1417 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1418 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1420 f.Printf("</TABLE><br>\n");
1423 char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
1426 f.Printf($"<H3>Usage</H3><br>\n");
1429 char fileName[MAX_LOCATION];
1430 FigureFileName(fileName, module, methodDoc, method, usage, null);
1431 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1436 f.Printf("<br>%s\n", usageDoc);
1437 f.Printf("<br><br>\n");
1442 char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
1445 f.Printf($"<H3>Example</H3><br>\n");
1446 f.Printf($"<FONT face=\"Courier New\">\n");
1447 f.Printf("<br><TABLE>\n");
1450 char fileName[MAX_LOCATION];
1451 FigureFileName(fileName, module, methodDoc, method, example, null);
1452 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1454 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1457 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1458 f.Printf("</TABLE></FONT>\n");
1464 char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
1467 f.Printf($"<H3>Remarks</H3><br>\n");
1470 char fileName[MAX_LOCATION];
1471 FigureFileName(fileName, module, methodDoc, method, remarks, null);
1472 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1477 f.Printf("<br>%s\n", method, remarksDoc);
1478 f.Printf("<br><br>\n");
1483 char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
1486 f.Printf($"<H3>See Also</H3><br>\n");
1489 char fileName[MAX_LOCATION];
1490 FigureFileName(fileName, module, methodDoc, method, seeAlso, null);
1491 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1496 f.Printf("<br>%s\n", method, seeAlsoDoc);
1498 f.Printf("<br><br>\n");
1502 f.Printf("</FONT></BODY></HTML>\n");
1506 class APIPageFunction : APIPage
1508 GlobalFunction function;
1512 return function.module;
1515 NameSpace * GetNameSpace()
1517 return function.nameSpace;
1520 void Generate(File f)
1523 Module module = function.module;
1525 char nsName[1024], temp[1024];
1526 NameSpace * ns = function.nameSpace;
1529 while(ns && ns->name)
1531 strcpy(temp, ns->name);
1532 if(nsName[0]) strcat(temp, "::");
1533 strcat(temp, nsName);
1534 strcpy(nsName, temp);
1538 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1539 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1541 f.Printf($"Module: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", (module && module.name) ? module : null, (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
1544 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", function.nameSpace, nsName);
1546 if(!function.dataType)
1547 function.dataType = ProcessTypeString(function.dataTypeString, false);
1549 if(function.dataType.thisClass && function.dataType.thisClass.registered)
1551 f.Printf($"this pointer class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", function.dataType.thisClass.registered, function.dataType.thisClass.registered.name);
1554 // Generate Method Page
1556 if(!function.dataType.name)
1557 function.dataType.name = CopyString(function.name);
1558 DocPrintType(function.dataType, string, true, false);
1559 f.Printf("<br>%s", string);
1562 char * desc = ReadDoc(module, functionDoc, function, description, null);
1565 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1568 char fileName[MAX_LOCATION];
1569 FigureFileName(fileName, module, functionDoc, function, description, null);
1570 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1575 f.Printf("%s", desc);
1579 f.Printf("<br><br>\n");
1580 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1582 f.Printf($"<H3>Parameters</H3><br><br>\n");
1584 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1585 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1587 f.Printf("<TABLE valign=center>\n");
1590 for(param = function.dataType.params.first; param; param = param.next)
1592 // ADD DESCRIPTION HERE
1593 if(param.kind != voidType)
1595 char * desc = ReadDoc(module, functionDoc, function, parameter, param);
1598 DocPrintType(param, string, false, false);
1600 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1601 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1606 char fileName[MAX_LOCATION];
1607 FigureFileName(fileName, module, functionDoc, function, parameter, param);
1608 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1611 f.Printf("</a> </TD>\n");
1614 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1617 f.Printf("</TR>\n");
1620 if(function.dataType.returnType && function.dataType.returnType.kind != voidType)
1622 char * desc = ReadDoc(module, functionDoc, function, returnValue, null);
1623 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1625 f.Printf("<TR><TD> </TD></TR>");
1628 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1630 DocPrintType(function.dataType.returnType, string, false, false);
1631 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1636 char fileName[MAX_LOCATION];
1637 FigureFileName(fileName, module, functionDoc, function, returnValue, null);
1638 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1640 f.Printf("</a> </TD>\n");
1643 f.Printf("<TD valign=top height=22>%s </TD>\n", function, desc);
1646 f.Printf("</TR>\n");
1647 f.Printf("</TABLE>\n");
1649 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1650 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1652 f.Printf("</TABLE><br>\n");
1655 char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
1658 f.Printf($"<H3>Usage</H3><br>\n");
1661 char fileName[MAX_LOCATION];
1662 FigureFileName(fileName, module, functionDoc, function, usage, null);
1663 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1668 f.Printf("<br>%s\n", usageDoc);
1669 f.Printf("<br><br>\n");
1674 char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
1677 f.Printf($"<H3>Example</H3><br>\n");
1678 f.Printf($"<FONT face=\"Courier New\">\n");
1679 f.Printf("<br><TABLE>\n");
1682 char fileName[MAX_LOCATION];
1683 FigureFileName(fileName, module, functionDoc, function, example, null);
1684 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1686 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1689 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1690 f.Printf("</TABLE></FONT>\n");
1696 char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
1699 f.Printf($"<H3>Remarks</H3><br>\n");
1702 char fileName[MAX_LOCATION];
1703 FigureFileName(fileName, module, functionDoc, function, remarks, null);
1704 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1709 f.Printf("<br>%s\n", remarksDoc);
1710 f.Printf("<br><br>\n");
1715 char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
1718 f.Printf($"<H3>See Also</H3><br>\n");
1721 char fileName[MAX_LOCATION];
1722 FigureFileName(fileName, module, functionDoc, function, seeAlso, null);
1723 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1728 f.Printf("<br>%s\n", seeAlsoDoc);
1729 f.Printf("<br><br>\n");
1733 f.Printf("</FONT></BODY></HTML>\n");
1737 static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, char * parentName, bool showPrivate)
1741 NameSpace * nameSpace = mainNameSpace;
1743 DataRow classesRow = null;
1744 DataRow functionsRow = null, definesRow = null;
1747 char fileName[MAX_LOCATION];
1749 strcpy(nsName, parentName ? parentName : "");
1753 strcat(nsName, "::");
1754 strcat(nsName, nameSpace->name);
1759 row = parentRow.AddRow();
1760 row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
1761 row.tag = (int64)nameSpace;
1762 row.icon = mainForm.icons[typeNameSpace];
1766 // "Global NameSpace"
1768 page = parentRow.GetData(null);
1774 for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1776 NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
1777 AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
1779 if(comNameSpace != null)
1781 for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1783 if(!mainNameSpace.nameSpaces.FindString(ns->name))
1785 AddNameSpace(row, module, ns, null, nsName, showPrivate);
1790 if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
1792 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1794 if(nameSpace->classes.first)
1798 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
1801 if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
1803 if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { $"Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
1804 AddClass(classesRow, module, cl, nsName, showPrivate);
1811 if(mainNameSpace.functions.first || (comNameSpace && comNameSpace.functions.first))
1813 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1815 if(nameSpace->functions.first)
1819 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
1822 if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
1824 char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
1826 if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
1827 fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int64)fn;
1834 if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
1836 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1838 if(nameSpace->defines.first)
1842 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
1845 //if(def.module == module)
1847 char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
1849 if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
1850 defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int64)def;
1858 static void AddDataMemberToPage(File f, DataMember member, int indent, bool showPrivate)
1862 if(!member.dataType)
1863 member.dataType = ProcessTypeString(member.dataTypeString, false);
1867 DocPrintType(member.dataType, string, true, false);
1869 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a>", member);
1870 for(c = 0; c<indent; c++)
1871 f.Printf(" ");
1872 f.Printf("<img valign=center src=\"%s\"> %s</TD>", iconNames[typeData], member.name ? member.name : ((member.type == structMember) ? "(struct)" : "(union)"));
1873 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", (member.type == normalMember) ? string : "");
1874 if(member.type == normalMember)
1876 char * desc = ReadDoc(member._class.module, classDoc, member._class, memberDescription, member);
1881 char fileName[MAX_LOCATION];
1882 FigureFileName(fileName, member._class.module, classDoc, member._class, memberDescription, member);
1883 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1885 f.Printf("</a></TD>");
1888 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1893 f.Printf("<TD valign=top height=22></TD>");
1895 if(member.type != normalMember)
1897 DataMember subMember;
1898 for(subMember = member.members.first; subMember; subMember = subMember.next)
1900 if((subMember.memberAccess == publicAccess || (subMember.memberAccess == privateAccess && showPrivate)))
1902 AddDataMemberToPage(f, subMember, indent + 1, showPrivate);
1906 f.Printf("</TR><br>\n");
1909 static void AddDataMember(DataRow parentRow, APIPage page, DataMember member)
1912 if(member.type == normalMember)
1914 row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
1915 row.tag = (int64)member;
1920 row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
1921 row.icon = mainForm.icons[typeData];
1922 row.tag = (int64)member;
1924 for(m = member.members.first; m; m = m.next)
1926 if(m.memberAccess == publicAccess || (m.memberAccess == privateAccess && page.showPrivate))
1927 AddDataMember(row, page, m);
1932 static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
1934 char fileName[MAX_LOCATION];
1941 DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
1942 DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
1945 row = parentRow.AddRow();
1946 row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
1947 row.tag = (int64)cl;
1948 row.collapsed = true;
1949 row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
1952 if(cl.methods.first)
1954 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1956 if(method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate))
1959 if(!method.dataType)
1960 ProcessMethodType(method);
1961 if(method.type == virtualMethod)
1963 if(method.dataType.thisClass)
1965 if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { $"Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
1966 mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
1967 mRow.tag = (int64)method;
1971 if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { $"Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
1972 mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
1973 mRow.tag = (int64)method;
1978 if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { $"Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
1979 mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
1980 mRow.tag = (int64)method;
1986 if(cl.membersAndProperties.first)
1988 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1990 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1993 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1997 if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { $"Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
1998 mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
1999 mRow.tag = (int64)prop;
2003 if(!membersRow) { membersRow = row.AddRow(); membersRow.SetData(null, APIPage { $"Data Members", page = page }); membersRow.collapsed = true; membersRow.icon = mainForm.icons[typeData]; membersRow.tag = 6; }
2004 AddDataMember(membersRow, page, (DataMember)prop);
2010 if(cl.conversions.first)
2012 for(prop = cl.conversions.first; prop; prop = prop.next)
2016 if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { $"Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
2017 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
2018 if(name) name += 2; else name = prop.name;
2019 mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
2020 mRow.tag = (int64)prop;
2023 if(cl.type == enumClass)
2025 EnumClassData enumeration = (EnumClassData)cl.data;
2027 for(item = enumeration.values.first; item; item = item.next)
2030 if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
2031 mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
2032 mRow.tag = (int64)item;
2037 class AddressBar : Window
2039 background = activeBorder;
2043 this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, bitmap = { ":actions/docOpen.png" };
2045 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2047 MainForm mainForm = (MainForm)parent;
2048 FileDialog fileDialog = mainForm.fileDialog;
2049 if(fileDialog.Modal() == ok)
2050 mainForm.OpenModule(fileDialog.filePath);
2056 this, bevelOver = true, inactive = true, anchor = Anchor { left = 28, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
2059 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2061 ((MainForm)parent).Back();
2067 this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
2070 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2072 ((MainForm)parent).Forward();
2078 this, bevelOver = true, inactive = true, anchor = Anchor { left = 80, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
2080 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2082 ((MainForm)parent).Home();
2086 /* TODO: Search (#143/#441)
2087 When there's something in the search box, list matching sections, the exact match first,instead of the Hierarchy in the ListBox.
2088 Update this in the NotifyUpdate. Enter goes to the exact match.
2090 Label { this, anchor = Anchor { left = (124+12) }, labeledWindow = search };
2094 this, text = "Search:", anchor = Anchor { left = (16+48+124), right = 60, top = 0, bottom = 0 }, hotKey = altD;
2096 bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
2098 if(!disabled && (SmartKey)key == enter)
2099 ((MainForm)parent).Go(editBox.contents);
2103 void NotifyUpdate(EditBox editBox)
2105 String location = ((MainForm)parent).view.location;
2106 disabled = !strcmp(location ? location : "", editBox.contents);
2111 bool OnKeyHit(Key key, unichar ch)
2114 ((MainForm)parent).view.MakeActive();
2119 class MainForm : Window
2121 size = { 1000, 600 };
2123 borderStyle = sizable;
2126 nativeDecorations = true;
2127 icon = { ":documentorIcon.png" };
2128 text = $"API Documentation Browser";
2130 BitmapResource icons[CodeObjectType];
2135 for(c = 0; c < CodeObjectType::enumSize; c++)
2137 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2139 browser.AddField(DataField { dataType = class(APIPage) });
2144 Menu fileMenu { menu, $"File", f };
2145 Array<FileFilter> fileFilters
2147 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2148 { $"eC Symbol files (*.sym)", "sym" }
2151 FileDialog fileDialog
2153 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2155 MenuItem fileOpenItem
2157 fileMenu, $"Open...", o, ctrlO;
2159 bool NotifySelect(MenuItem selection, Modifiers mods)
2161 if(fileDialog.Modal() == ok)
2163 OpenModule(fileDialog.filePath);
2168 MenuItem fileSettingsItem
2170 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2172 bool NotifySelect(MenuItem selection, Modifiers mods)
2174 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2184 MenuDivider { fileMenu };
2185 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2187 void OpenModule(char * filePath)
2189 char moduleName[MAX_LOCATION];
2190 char extension[MAX_EXTENSION];
2191 Module module = null;
2192 static char symbolsDir[MAX_LOCATION];
2196 FreeContext(globalContext);
2197 FreeExcludedSymbols(excludedSymbols);
2198 ::defines.Free(FreeModuleDefine);
2199 imports.Free(FreeModuleImport);
2201 FreeGlobalData(globalData);
2202 FreeTypeData(componentsApp);
2204 delete componentsApp;
2206 SetGlobalContext(globalContext);
2207 componentsApp = __ecere_COM_Initialize(false, 1, null);
2208 SetPrivateModule(componentsApp);
2210 StripLastDirectory(filePath, symbolsDir);
2211 SetSymbolsDir(symbolsDir);
2213 GetExtension(filePath, extension);
2215 mainForm.browser.Clear();
2217 ImportModule(filePath, normalImport, publicAccess, false);
2219 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll"))
2220 componentsApp.name = CopyString(filePath);
2222 for(module = componentsApp.allModules.first; module; module = module.next)
2224 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2228 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2229 AddComponents(componentsApp, false);
2231 // lib prefix and extension get removed by ImportModule
2234 char name[MAX_FILENAME];
2235 GetLastDirectory(filePath, name);
2236 StripLastDirectory(filePath, moduleName);
2237 StripExtension(name);
2238 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(name, "lib") == name)
2239 memmove(name, name + 3, strlen(name)-3);
2240 PathCat(moduleName, name);
2243 strcpy(moduleName, filePath);
2245 for(module = componentsApp.allModules.first; module; module = module.next)
2247 if(module.name && (!strcmp(module.name, moduleName)))
2250 if(!module) module = componentsApp;
2251 homeModule = module;
2252 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2254 SetSymbolsDir(null);
2257 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2260 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2261 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2264 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2266 APIPage page = row.GetData(null);
2267 if(view.edit) view.OnLeftButtonDown(0,0,0);
2268 if(page && page.page) page = page.page;
2270 view.PositionCaret(true);
2271 if(page != view.page)
2273 Window activeChild = this.activeChild;
2275 // Back / Forward Support
2276 if(row && !dontRecordHistory)
2278 if(history.count > historyPos+1)
2279 history.count = historyPos+1;
2280 historyPos = history.count-1;
2281 addressBar.back.disabled = (historyPos == 0);
2282 addressBar.forward.disabled = (historyPos >= history.count-1);
2284 history.Add((Instance)(uint64)row.tag);
2285 historyPos = history.count-1;
2287 addressBar.back.disabled = (historyPos == 0);
2288 addressBar.forward.disabled = (historyPos >= history.count-1);
2294 activeChild.Activate();
2296 else if(!view.created)
2300 page = row.GetData(null);
2301 if(page && page.page)
2305 case 1: view.GoToAnchor("Classes"); break;
2306 case 2: view.GoToAnchor("Functions"); break;
2307 case 3: view.GoToAnchor("Definitions"); break;
2308 case 4: view.GoToAnchor("VirtualMethods"); break;
2309 case 5: view.GoToAnchor("Methods"); break;
2310 case 6: view.GoToAnchor("Members"); break;
2311 case 7: view.GoToAnchor("Conversions"); break;
2312 case 8: view.GoToAnchor("EnumerationValues"); break;
2316 sprintf(hex, "%p", row.tag);
2317 view.GoToAnchor(hex);
2323 view.SetScrollPosition(0, 0);
2331 this, anchor = { top = 26, bottom = 0, right = 0 };
2336 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2339 bool OnClose(bool parentClosing)
2342 view.OnLeftButtonDown(0,0,0);
2348 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2349 //mainForm.OpenModule("ec");
2350 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2351 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2353 int index = mainForm.browser.currentRow.index;
2354 int rowHeight = mainForm.browser.rowHeight;
2355 int height = mainForm.browser.clientSize.h;
2357 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2362 Array<Instance> history { };
2364 bool dontRecordHistory;
2369 if(historyPos < history.count-1)
2373 addressBar.back.disabled = (historyPos == 0);
2374 addressBar.forward.disabled = (historyPos >= history.count-1);
2375 sprintf(location, "api://%p", history[historyPos]);
2376 dontRecordHistory = true;
2377 view.OnOpen(location);
2378 dontRecordHistory = false;
2390 addressBar.back.disabled = (historyPos == 0);
2391 addressBar.forward.disabled = (historyPos >= history.count-1);
2392 sprintf(location, "api://%p", history[historyPos]);
2393 dontRecordHistory = true;
2394 view.OnOpen(location);
2395 dontRecordHistory = false;
2403 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2407 class EditDialog : Window
2409 borderStyle = sizable;
2410 size = { 600, 400 };
2415 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2419 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2423 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2427 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2428 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2430 class HelpView : HTMLView
2434 hasVertScroll = true;
2435 hasHorzScroll = true;
2437 char editString[MAX_LOCATION];
2443 page = mainForm.browser.currentRow.GetData(null);
2448 char docFile[MAX_LOCATION];
2450 Module module = page ? page.GetModule() : null;
2451 NameSpace * ns = page ? page.GetNameSpace() : null;
2453 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2454 if(strchr(docFile, DIR_SEP))
2456 char temp[MAX_LOCATION];
2457 GetLastDirectory(docFile, temp);
2458 strcpy(docFile, temp);
2461 if(FileExists(docFile))
2463 archive = ArchiveOpen(docFile, { true } );
2464 readOnly = archive == null;
2470 archive = ArchiveOpen(docFile, { true } );
2473 // Must create root directory on archive creation
2474 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2486 GoToAnchor(page.label);
2488 if(page.page) page = page.page;
2491 return HTMLView::OnCreate();
2500 char archiveFile[MAX_LOCATION];
2501 char fileName[MAX_FILENAME];
2502 char directory[MAX_LOCATION];
2504 Archive archive = null;
2505 if(SplitArchivePath(editString, archiveFile, &location))
2507 GetLastDirectory(location, fileName);
2508 StripLastDirectory(location, directory);
2509 archive = ArchiveOpen(archiveFile, { true } );
2513 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2516 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2518 if(block.type == TEXT && block.textLen)
2526 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2528 if(block.type == BR)
2530 else if(block.type == TEXT)
2531 f.Write(block.text, 1, block.textLen);
2536 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2542 Block parent = textBlock.parent;
2543 while((block = parent.subBlocks.first))
2545 parent.subBlocks.Remove(block);
2548 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2549 textBlock.text = CopyString($"[Add Text]");
2550 textBlock.textLen = strlen(textBlock.text);
2551 parent.subBlocks.Add(textBlock);
2559 PositionCaret(true);
2565 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2569 if(edit && (!textBlock || overLink != textBlock.parent))
2573 HTMLView::OnLeftButtonDown(x, y, mods);
2574 selPosition = curPosition = 0;
2575 selBlock = textBlock;
2579 result = HTMLView::OnLeftButtonDown(x, y, mods);
2581 if(!edit && clickedLink)
2584 if(clickedLink == overLink && clickedLink.href)
2586 if(OnOpen(clickedLink.href))
2594 if(textBlock && overLink == textBlock.parent)
2596 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2597 selBlock = textBlock;
2598 PositionCaret(true);
2606 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2608 if(!edit || !textBlock || clickedLink != textBlock.parent)
2610 HTMLView::OnLeftButtonUp(x, y, mods);
2613 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2614 selBlock = textBlock;
2615 PositionCaret(true);
2626 bool OnMouseMove(int x, int y, Modifiers mods)
2628 if(edit && selecting)
2630 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2631 PositionCaret(true);
2634 return HTMLView::OnMouseMove(x, y, mods);
2637 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2639 if(edit && textBlock)
2645 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2646 selBlock = textBlock;
2647 for(c = curPosition; c >= 0; c--)
2650 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2651 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2652 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2658 for(c = start; c < textBlock.textLen; c += numBytes)
2660 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2661 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2664 selPosition = start;
2667 PositionCaret(true);
2675 bool OnOpen(char * href)
2677 if(!strncmp(href, "api://", 6))
2679 int tag = (uint)strtoul(href + 6, null, 16);
2680 DataRow row = mainForm.browser.FindSubRow(tag);
2684 mainForm.browser.SelectRow(row);
2685 while((row = row.parent))
2686 row.collapsed = false;
2687 row = mainForm.browser.currentRow;
2688 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2691 else if(!strncmp(href, "edit://", 7))
2694 int startX = clickedLink.startX, startY = clickedLink.startY;
2695 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2697 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2698 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2700 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2702 display.FontExtent(block.font.font, " ", 1, null, &th);
2705 block.parent.subBlocks.Insert(null, newBlock);
2710 block.parent.subBlocks.Insert(block, newBlock);
2711 startY += block.prev.height;
2713 newBlock.startX = startX;
2714 newBlock.startY = startY;
2715 newBlock.text = new0 char[1];
2719 textBlock = (Block)clickedLink.subBlocks.first;
2720 if(!strcmp(textBlock.text, $"[Add Text]"))
2722 textBlock.text[0] = 0;
2723 textBlock.textLen = 0;
2726 strcpy(editString, href + 7);
2727 selPosition = curPosition = 0;
2728 selBlock = textBlock;
2731 // PositionCaret(true);
2738 void DeleteSelection()
2740 if(textBlock != selBlock || curPosition != selPosition)
2742 if(textBlock == selBlock)
2744 // Within same block
2745 int start = Min(curPosition, selPosition);
2746 int end = Max(curPosition, selPosition);
2747 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2748 textBlock.textLen -= end-start;
2749 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2750 curPosition = start;
2751 selPosition = start;
2755 int startSel, endSel;
2756 Block startSelBlock = null, endSelBlock = null, b, next;
2758 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2760 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2761 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2763 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2764 for(b = startSelBlock.next; b; b = next)
2766 bool isEnd = b == endSelBlock;
2767 next = GetNextBlock(b);
2768 b.parent.subBlocks.Remove(b);
2773 textBlock = startSelBlock;
2774 selBlock = startSelBlock;
2775 curPosition = startSel;
2776 selPosition = startSel;
2780 PositionCaret(true);
2785 String GetSelectionString()
2787 String selection = null;
2788 if(textBlock == selBlock)
2790 // Within same block
2791 int start = Min(curPosition, selPosition);
2792 int end = Max(curPosition, selPosition);
2793 int len = end - start;
2794 selection = new char[len + 1];
2795 memcpy(selection, textBlock.text + start, len);
2800 int startSel, endSel;
2801 Block startSelBlock = null, endSelBlock = null, b;
2804 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2807 for(b = startSelBlock; b; b = GetNextBlock(b))
2809 int start = (b == startSelBlock) ? startSel : 0;
2810 int end = (b == endSelBlock) ? endSel : b.textLen;
2811 int len = end - start;
2813 if(b == endSelBlock)
2815 else if(b.type == TEXT)
2819 selection = new char[totalLen + 1];
2821 for(b = startSelBlock; b; b = GetNextBlock(b))
2823 int start = (b == startSelBlock) ? startSel : 0;
2824 int end = (b == endSelBlock) ? endSel : b.textLen;
2825 int len = end - start;
2826 memcpy(selection + totalLen, b.text + start, len);
2828 if(b == endSelBlock)
2830 else if(b.type == TEXT)
2831 selection[totalLen++] = '\n';
2833 selection[totalLen] = 0;
2838 void CopySelection()
2840 String s = GetSelectionString();
2843 int len = strlen(s);
2845 if(cb.Allocate(len + 1))
2847 memcpy(cb.text, s, len + 1);
2855 bool OnKeyDown(Key key, unichar ch)
2862 OnLeftButtonDown(0,0,0);
2864 case Key { end, shift = true }:
2866 curPosition = textBlock.textLen;
2869 selPosition = curPosition;
2870 selBlock = textBlock;
2872 PositionCaret(true);
2875 case Key { home, shift = true }:
2880 selPosition = curPosition;
2881 selBlock = textBlock;
2883 PositionCaret(true);
2886 case Key { home, ctrl = true, shift = true }:
2889 while(textBlock.prev)
2890 textBlock = textBlock.prev.prev;
2893 selPosition = curPosition;
2894 selBlock = textBlock;
2896 PositionCaret(true);
2899 case Key { end, ctrl = true, shift = true }:
2901 while(textBlock.next && textBlock.next.next)
2902 textBlock = textBlock.next.next;
2903 curPosition = textBlock.textLen;
2906 selPosition = curPosition;
2907 selBlock = textBlock;
2909 PositionCaret(true);
2915 return HTMLView::OnKeyDown(key, ch);
2919 bool OnKeyHit(Key key, unichar ch)
2925 case Key { up, shift = true }:
2928 if(caretY == textBlock.startY)
2932 textBlock = textBlock.prev.prev;
2933 curPosition = Min(curPosition, textBlock.textLen);
2936 selPosition = curPosition;
2937 selBlock = textBlock;
2940 PositionCaret(false);
2950 int sx = textBlock.startX, sy = textBlock.startY;
2951 char * text = textBlock.text;
2953 Block block = textBlock;
2954 while(block && block.type != TD) block = block.parent;
2957 Block table = block;
2958 while(table && table.type != TABLE) table = table.parent;
2960 maxW = block.w - 2* table.cellPadding;
2962 maxW = clientSize.w - 10 - sx;
2965 maxW = clientSize.w - 10 - sx;
2966 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
2970 int startPos = textPos;
2973 bool lineComplete = false;
2974 for(; textPos<textBlock.textLen && !lineComplete;)
2978 char * nextSpace = strchr(text + textPos, ' ');
2981 len = (nextSpace - (text + textPos)) + 1;
2983 len = textBlock.textLen - textPos;
2985 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
2987 if(x + width + w > maxW && x > 0)
2989 lineComplete = true;
2999 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3002 curPosition = textPos;
3003 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3006 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3007 len = curPosition - startPos;
3008 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3012 selPosition = curPosition;
3013 selBlock = textBlock;
3017 PositionCaret(false);
3021 if(sy == caretY - th || textPos == textBlock.textLen)
3023 if(textPos != textBlock.textLen)
3025 int c = textPos - 1;
3026 while(c > 0 && text[c] == ' ') c--;
3027 curPosition = c + 1;
3030 selPosition = curPosition;
3031 selBlock = textBlock;
3037 curPosition = textBlock.textLen;
3040 selPosition = curPosition;
3041 selBlock = textBlock;
3045 PositionCaret(false);
3049 sx = textBlock.startX;
3050 } while(textPos < textBlock.textLen);
3055 case Key { down, shift = true }:
3060 int sx = textBlock.startX, sy = textBlock.startY;
3061 char * text = textBlock.text;
3063 Block block = textBlock;
3064 while(block && block.type != TD) block = block.parent;
3067 Block table = block;
3068 while(table && table.type != TABLE) table = table.parent;
3070 maxW = block.w - 2* table.cellPadding;
3072 maxW = clientSize.w - 10 - sx;
3075 maxW = clientSize.w - 10 - sx;
3076 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3078 while(!textPos || textPos < textBlock.textLen)
3080 int startPos = textPos;
3083 bool lineComplete = false;
3084 for(; (textPos < textBlock.textLen) && !lineComplete;)
3088 char * nextSpace = strchr(text + textPos, ' ');
3091 len = (nextSpace - (text + textPos)) + 1;
3093 len = textBlock.textLen - textPos;
3095 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3097 if(x + width + w > maxW && x > 0)
3099 lineComplete = true;
3109 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3111 curPosition = textPos;
3113 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3116 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3117 len = curPosition - startPos;
3118 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3122 selPosition = curPosition;
3123 selBlock = textBlock;
3126 PositionCaret(false);
3132 curPosition = textBlock.textLen;
3135 selPosition = curPosition;
3136 selBlock = textBlock;
3139 PositionCaret(false);
3142 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3146 textBlock = textBlock.next.next;
3147 sy = textBlock.startY;
3148 sx = textBlock.startX;
3149 text = textBlock.text;
3154 sx = textBlock.startX;
3158 /*if(textBlock.next && textBlock.next.next)
3160 textBlock = textBlock.next.next;
3161 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3162 selBlock = textBlock;
3163 PositionCaret(false);
3167 case Key { right, shift = true, ctrl = true }:
3170 bool foundAlpha = false;
3172 Block line, lastLine;
3175 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3177 int start = (line == textBlock) ? curPosition : 0;
3179 for(c = start; c < line.textLen; c++)
3181 char ch = line.text[c];
3182 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3183 if(key.shift ? isAlUnder : !isAlUnder)
3197 selPosition = curPosition;
3198 selBlock = textBlock;
3202 PositionCaret(true);
3207 // No next word found,
3208 if(!found && (c != curPosition || line != textBlock))
3212 lastC = line.textLen-1;
3217 curPosition = line.textLen;
3220 selPosition = curPosition;
3221 selBlock = textBlock;
3226 PositionCaret(true);
3232 if(key.shift && found)
3234 curPosition = lastC+1;
3235 textBlock = lastLine;
3236 PositionCaret(true);
3241 case Key { left, ctrl = true, shift = true }:
3244 bool foundAlpha = false;
3246 Block line, lastLine;
3249 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3252 if(curPosition == 0 && line != textBlock)
3255 lastC = line.textLen;
3259 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3260 for(c = start; c>=0; c--)
3262 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3277 // No next word found,
3278 if(!found && curPosition > 0)
3288 textBlock = lastLine;
3289 curPosition = lastC;
3292 selPosition = curPosition;
3293 selBlock = textBlock;
3295 PositionCaret(true);
3300 case Key { right, shift = true }:
3302 if(curPosition < textBlock.textLen)
3304 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3307 selPosition = curPosition;
3308 selBlock = textBlock;
3310 PositionCaret(true);
3313 else if(textBlock.next && textBlock.next.next)
3315 textBlock = textBlock.next.next;
3319 selPosition = curPosition;
3320 selBlock = textBlock;
3322 PositionCaret(true);
3326 case Key { left, shift = true }:
3330 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3333 selPosition = curPosition;
3334 selBlock = textBlock;
3336 PositionCaret(true);
3339 else if(textBlock.prev)
3341 textBlock = textBlock.prev.prev;
3342 curPosition = textBlock.textLen;
3345 selPosition = curPosition;
3346 selBlock = textBlock;
3348 PositionCaret(true);
3354 if(textBlock == selBlock && curPosition == selPosition)
3358 int c = curPosition;
3360 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3361 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3362 textBlock.textLen -= nb;
3363 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3365 selPosition = curPosition;
3366 selBlock = textBlock;
3370 PositionCaret(true);
3373 else if(textBlock.prev)
3375 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3376 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3377 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3379 selPosition = curPosition = prevBlock.textLen;
3380 selBlock = textBlock;
3381 prevBlock.textLen += textBlock.textLen;
3382 textBlock.parent.subBlocks.Remove(prev);
3383 if(prev == selBlock)
3385 selBlock = textBlock;
3386 selPosition = curPosition;
3389 textBlock.parent.subBlocks.Remove(textBlock);
3390 if(textBlock == selBlock)
3392 selBlock = prevBlock;
3393 selPosition = curPosition;
3396 textBlock = prevBlock;
3400 PositionCaret(true);
3409 if(textBlock != selBlock || curPosition != selPosition)
3411 else if(textBlock.textLen > curPosition)
3413 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3414 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3415 textBlock.textLen -= nb;
3416 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3421 PositionCaret(true);
3424 else if(textBlock.next && textBlock.next.next)
3426 Block next = textBlock.next, nextBlock = textBlock.next.next;
3427 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3428 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3430 textBlock.textLen += nextBlock.textLen;
3431 textBlock.parent.subBlocks.Remove(next);
3432 if(next == selBlock)
3434 selBlock = textBlock;
3435 selPosition = curPosition;
3438 textBlock.parent.subBlocks.Remove(nextBlock);
3439 if(nextBlock == selBlock)
3441 selBlock = textBlock;
3442 selPosition = curPosition;
3448 PositionCaret(true);
3462 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3463 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3464 startY = textBlock.startY;
3465 startX = textBlock.startX;
3467 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3468 textBlock.parent.subBlocks.Insert(textBlock, block);
3469 textBlock.parent.subBlocks.Insert(block, newBlock);
3473 newBlock.textLen = textBlock.textLen - curPosition;
3474 newBlock.text = new char[newBlock.textLen+1];
3475 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3476 textBlock.textLen = curPosition;
3477 textBlock.text[curPosition] = 0;
3479 newBlock.startY = startY;
3480 newBlock.startX = startX;
3481 selPosition = curPosition = 0;
3486 textBlock = newBlock;
3487 selBlock = textBlock;
3488 PositionCaret(true);
3493 case Key { del, shift = true }:
3508 ClipBoard clipBoard { };
3509 if(clipBoard.Load())
3512 char * text = clipBoard.memory;
3520 parent = textBlock.parent;
3521 font = textBlock.font;
3526 if(ch == '\n' || ch == '\r' || !ch)
3528 int len = c - start;
3529 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3530 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3531 memcpy(textBlock.text + curPosition, text + start, len);
3532 textBlock.textLen += len;
3534 selPosition = curPosition;
3535 selBlock = textBlock;
3538 Block block { type = BR, parent = parent, font = font };
3539 Block newBlock { type = TEXT, parent = parent, font = font };
3540 int startY = textBlock.startY, startX = textBlock.startX;
3543 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3544 textBlock.parent.subBlocks.Insert(textBlock, block);
3545 textBlock.parent.subBlocks.Insert(block, newBlock);
3549 newBlock.textLen = textBlock.textLen - curPosition;
3550 newBlock.text = new char[newBlock.textLen+1];
3551 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3552 textBlock.textLen = curPosition;
3553 textBlock.text[curPosition] = 0;
3555 newBlock.startY = startY;
3556 newBlock.startX = startX;
3557 selPosition = curPosition = 0;
3558 selBlock = textBlock;
3559 textBlock = newBlock;
3561 if(ch == '\r' && text[c+1] == '\n') c++;
3567 PositionCaret(true);
3575 // eC BUG HERE: (Should be fixed)
3576 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3579 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3584 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3585 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3587 for(c = 0; c<len; c++)
3589 textBlock.text[curPosition] = string[c];
3590 textBlock.textLen++;
3593 selPosition = curPosition;
3594 selBlock = textBlock;
3597 //Clear(html.block);
3598 //CreateForms(html.block);
3603 PositionCaret(true);
3612 void OnResize(int width, int height)
3614 HTMLView::OnResize(width, height);
3615 PositionCaret(true);
3619 void PositionCaret(bool setCaretX)
3625 int sx = textBlock.startX, sy = textBlock.startY;
3626 char * text = textBlock.text;
3628 Block block = textBlock;
3629 while(block && block.type != TD) block = block.parent;
3632 Block table = block;
3633 while(table && table.type != TABLE) table = table.parent;
3635 maxW = block.w - 2* table.cellPadding;
3637 maxW = clientSize.w - 10 - sx;
3640 maxW = clientSize.w - 10 - sx;
3642 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3644 while(textPos < textBlock.textLen)
3646 int startPos = textPos;
3649 bool lineComplete = false;
3651 for(; textPos<textBlock.textLen && !lineComplete;)
3655 char * nextSpace = strchr(text + textPos, ' ');
3658 len = (nextSpace - (text + textPos)) + 1;
3660 len = textBlock.textLen - textPos;
3662 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3664 if(x + width + w > maxW && x > 0)
3666 lineComplete = true;
3679 if(curPosition < textPos || textPos == textBlock.textLen)
3681 int len = curPosition - startPos;
3682 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3687 sx = textBlock.startX;
3692 SetCaret(sx, sy, th);
3694 Point scrollPos = scroll;
3695 bool doScroll = false;
3696 if(sy - scroll.y + th > clientSize.h)
3698 scrollPos.y = sy + th - clientSize.h;
3701 else if(sy - scroll.y < 0)
3706 if(sx - scroll.x + 10 > clientSize.w)
3708 scrollPos.x = sx + 10 - clientSize.w;
3711 else if(sx - scroll.x < 10)
3713 scrollPos.x = sx - 10;
3724 // Returns a character offset into the TextBlock from a window coordinate
3725 int TextPosFromPoint(int px, int py, Block * block, bool half)
3727 Block parentBlock = this.textBlock.parent;
3730 *block = this.textBlock;
3735 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3737 int sx = textBlock.startX, sy = textBlock.startY;
3740 char * text = textBlock.text;
3742 Block b = textBlock;
3745 if(textBlock.type != TEXT) continue;
3747 while(b && b.type != TD) b = b.parent;
3751 while(table && table.type != TABLE) table = table.parent;
3753 maxW = b.w - 2* table.cellPadding;
3755 maxW = clientSize.w - 10 - sx;
3758 maxW = clientSize.w - 10 - sx;
3760 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3761 //space = space/2+2;
3764 while(textPos < textBlock.textLen)
3766 int startPos = textPos;
3769 bool lineComplete = false;
3771 for(; textPos<textBlock.textLen && !lineComplete;)
3775 char * nextSpace = strchr(text + textPos, ' ');
3778 len = (nextSpace - (text + textPos)) + 1;
3780 len = textBlock.textLen - textPos;
3782 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3784 sx = x + textBlock.startX;
3785 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3790 for(c = textPos; (ch = text[c]); c += numBytes)
3792 numBytes = UTF8_NUM_BYTES(ch);
3793 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3794 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3801 if(x + width + w > maxW && x > 0)
3803 lineComplete = true;
3816 if(/*py >= sy && */py < sy + th)
3819 return textBlock.textLen;
3824 result = textBlock.textLen;
3830 Application componentsApp;
3832 class Documentor : GuiApplication
3836 Platform os = GetRuntimePlatform();
3837 componentsApp = __ecere_COM_Initialize(false, 1, null);
3838 SetPrivateModule(componentsApp);
3839 SetGlobalContext(globalContext);
3840 SetExcludedSymbols(&excludedSymbols);
3841 SetDefines(&::defines);
3842 SetImports(&imports);
3844 SetGlobalData(globalData);
3846 settingsContainer.dataOwner = &settings;
3847 settingsContainer.Load();
3848 if(!settings.docDir || !settings.docDir[0] )
3850 if(os == win32) // if Windows OS then
3852 char programFilesDir[MAX_LOCATION];
3853 char appData[MAX_LOCATION];
3854 char homeDrive[MAX_LOCATION];
3855 char winDir[MAX_LOCATION];
3856 GetEnvironment("APPDATA", appData, sizeof(appData));
3857 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3858 GetEnvironment("windir", winDir, sizeof(winDir));
3859 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3861 PathCat(programFilesDir, "ECERE SDK\\doc");
3862 settings.docDir = programFilesDir;
3864 else if(homeDrive && homeDrive[0])
3866 PathCat(homeDrive, "ECERE SDK\\doc");
3867 settings.docDir = homeDrive;
3869 else if(winDir && winDir[0])
3871 PathCat(winDir, "..\\ECERE SDK\\doc");
3872 settings.docDir = winDir;
3875 settings.docDir = "C:\\ECERE SDK\\doc";
3877 else // if Os is Linux, or Mac OSX or something else
3878 settings.docDir = "/usr/share/ecere/doc/";
3879 settingsContainer.Save();
3885 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3887 AddComponents(module, true);
3888 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3889 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3890 while((row = row.parent))
3891 row.collapsed = false;
3895 commandThread.Create();
3899 bool Cycle(bool idle)
3902 mainForm.Destroy(0);
3911 if(commandThread.created)
3913 console.CloseInput();
3914 console.CloseOutput();
3916 commandThread.Wait();
3920 FreeContext(globalContext);
3921 FreeExcludedSymbols(excludedSymbols);
3922 ::defines.Free(FreeModuleDefine);
3923 imports.Free(FreeModuleImport);
3925 FreeGlobalData(globalData);
3926 FreeTypeData(componentsApp);
3928 delete componentsApp;
3932 ConsoleFile console { };
3933 MainForm mainForm { };
3936 Thread commandThread
3943 console.GetLine(command, sizeof(command));
3944 if(!quit && command[0])
3947 if(!strcmpi(command, "Activate"))
3948 mainForm.Activate();
3949 else if(!strcmpi(command, "Quit"))