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)(uintptr)&((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;
23 static __attribute__((unused)) void Dummy()
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 const 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 void GetTemplateString(Class c, char * templateString)
59 Module m = c.module.application;
60 const char * n = c.name;
61 char * lt = strchr(n, '<');
67 memcpy(templateString, n, lt-n);
68 templateString[lt-n] = 0;
69 strcat(templateString, "</a>");
71 for(s = lt; (ch = *s); s++)
73 if(ch == '<' || ch == '>' || ch == ',')
78 char * d = templateString + strlen(templateString);
80 pc = eSystem_FindClass(m, curName);
82 sprintf(d, "<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", pc, pc.name);
87 strcat(templateString, "<");
89 strcat(templateString, ">");
91 strcat(templateString, ", ");
100 strcat(templateString, curName);
108 // WARNING : This function expects a null terminated string since it recursively concatenate...
109 static void _PrintType(Type type, char * string, bool printName, bool printFunction, bool fullName)
113 if(type.constant && (type.kind != pointerType && type.kind != arrayType))
114 strcat(string, "const ");
118 if(type._class && type._class.string)
121 strcat(string, type._class.string);
124 if(type._class.registered)
127 const char * s = type._class.registered.name;
128 sprintf(hex, "%p", type._class.registered.templateClass ? type._class.registered.templateClass : type._class.registered);
129 strcat(string, "<a href=\"api://");
131 strcat(string, "\" style=\"text-decoration: none;\">");
135 GetTemplateString(type._class.registered, n);
139 strcat(string, type._class.registered.name);
140 strcat(string, "</a>");
143 strcat(string, type._class.string);
150 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
151 if(funcType && funcType.kind == functionType)
154 DocPrintType(funcType.returnType, string, false, fullName);
155 strcat(string, "(*");
156 if(printName || funcType.thisClass)
159 if(funcType.thisClass)
161 strcat(string, funcType.thisClass.string);
162 strcat(string, "::");
165 strcat(string, type.name);
167 strcat(string, ")(");
168 for(param = funcType.params.first; param; param = param.next)
170 DocPrintType(param, string, false, fullName);
171 if(param.next) strcat(string, ", ");
177 _PrintType(type.type, string, false /*printName*/, printFunction, fullName);
178 if(string[strlen(string)-1] == '(')
181 strcat(string, " *");
185 case voidType: strcat(string, "void"); break;
186 case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
187 case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
188 case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
189 case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
190 case floatType: strcat(string, "float"); break;
191 case doubleType: strcat(string, "double"); break;
195 strcat(string, "struct ");
196 strcat(string, type.enumName);
198 else if(type.typeName)
200 strcat(string, type.typeName);
205 strcat(string, "struct ");
206 strcat(string,"(unnamed)");
209 strcat(string, "struct {");
210 for(member = type.members.first; member; member = member.next)
212 DocPrintType(member, string, true, fullName);
221 strcat(string, "union ");
222 strcat(string, type.enumName);
224 else if(type.typeName)
226 strcat(string, type.typeName);
230 strcat(string, "union ");
231 strcat(string,"(unnamed)");
237 strcat(string, "enum ");
238 strcat(string, type.enumName);
240 else if(type.typeName)
242 strcat(string, type.typeName);
245 strcat(string, "enum");
252 strcat(string, "dllexport ");
253 DocPrintType(type.returnType, string, false, fullName);
257 // DANGER: Testing This
263 strcat(string, type.name);
266 char * name = RSearchString(type.name, "::", strlen(type.name), true, false);
267 if(name) name += 2; else name = type.name;
268 strcat(string, "<b>");
269 strcat(string, name);
270 strcat(string, "</b>");
279 for(param = type.params.first; param; param = param.next)
281 DocPrintType(param, string, true, fullName);
282 if(param.next) strcat(string, ", ");
291 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
292 if(funcType && funcType.kind == functionType)
295 DocPrintType(funcType.returnType, string, false, fullName);
296 strcat(string, "(*");
297 if(printName || funcType.thisClass)
300 if(funcType.thisClass)
302 strcat(string, funcType.thisClass.string);
303 strcat(string, "::");
306 strcat(string, type.name);
308 strcat(string, ")(");
309 for(param = funcType.params.first; param; param = param.next)
311 DocPrintType(param, string, false, fullName);
312 if(param.next) strcat(string, ", ");
318 char baseType[1024], size[256];
319 Type arrayType = type;
323 while(arrayType.kind == TypeKind::arrayType)
326 if(arrayType.enumClass)
327 strcat(size, arrayType.enumClass.string);
328 else if(arrayType.arraySizeExp)
329 PrintExpression(arrayType.arraySizeExp, size);
330 //sprintf(string, "%s[%s]", baseType, size);
333 arrayType = arrayType.arrayType;
335 _PrintType(arrayType, baseType, printName, printFunction, fullName);
336 strcat(string, baseType);
337 strcat(string, size);
341 DocPrintType(type.arrayType, baseType, printName, fullName);
343 strcpy(size, type.enumClass.string);
344 else if(type.arraySizeExp)
345 PrintExpression(type.arraySizeExp, size);
346 //sprintf(string, "%s[%s]", baseType, size);
347 strcat(string, baseType);
349 strcat(string, size);
357 strcat(string, "...");
360 _PrintType(type.method.dataType, string, false, printFunction, fullName);
363 strcat(string, "subclass(");
364 strcat(string, type._class ? type._class.string : "int");
370 if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
373 strcat(string, type.name);
378 void DocPrintType(Type type, char * string, bool printName, bool fullName)
381 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
382 if(funcType && funcType.kind == functionType && type != funcType)
386 DocPrintType(funcType.returnType, string, false, fullName);
388 _PrintType(type, string, printName, false, fullName);
392 strcat(string, type.name);
399 for(param = funcType.params.first; param; param = param.next)
401 DocPrintType(param, string, true, fullName);
402 if(param.next) strcat(string, ", ");
407 _PrintType(type, string, printName, true, fullName);
410 void AddComponents(Module module, bool isDll)
415 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
417 row = mainForm.browser.AddRow();
418 row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
419 row.tag = (int64)null;
420 AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
423 for(m = module.modules.first; m; m = m.next)
425 if(m.importMode == publicAccess || !isDll)
426 AddComponents(m.module, true);
429 // PUT MODULE DESCRIPTION HERE
430 if(module.name && strcmp(module.name, "ecereCOM"))
432 row = mainForm.browser.AddRow();
433 row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
434 row.tag = (int64)module;
435 AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
437 AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
449 const char * OnGetString(char * tempString, void * fieldData, bool * needClass)
454 virtual void Generate(File f)
459 virtual Module GetModule()
461 return page ? page.GetModule() : null;
464 virtual NameSpace * GetNameSpace()
466 return page ? page.GetNameSpace() : null;
470 enum DocumentationType
478 enum DocumentationItem
494 static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
496 NameSpace * nameSpace, * ns;
498 Method method = null;
499 GlobalFunction function = null;
500 char nsName[1024], temp[1024];
506 case nameSpaceDoc: nameSpace = object; break;
507 case classDoc: cl = (Class)object; nameSpace = cl.nameSpace; break;
508 case functionDoc: function = object; nameSpace = function.nameSpace; break;
509 case methodDoc: method = object; cl = method._class; nameSpace = cl.nameSpace; break;
514 while(ns && ns->name)
516 strcpy(temp, "namespaces/");
517 strcat(temp, ns->name);
519 strcat(temp, nsName);
520 strcpy(nsName, temp);
523 sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
524 if(strchr(docFile, DIR_SEP))
526 GetLastDirectory(docFile, temp);
527 strcpy(docFile, temp);
530 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.
531 strcat(fileName, nsName);
535 strcat(fileName, "classes/");
536 strcat(fileName, cl.name);
537 strcat(fileName, "/");
542 strcat(fileName, "methods/");
543 strcat(fileName, method.name);
544 strcat(fileName, "/");
548 const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
549 if(name) name += 2; else name = function.name;
550 strcat(fileName, "functions/");
551 strcat(fileName, name);
552 strcat(fileName, "/");
557 case description: strcat(fileName, "description"); break;
558 case usage: strcat(fileName, "usage"); break;
559 case remarks: strcat(fileName, "remarks"); break;
560 case example: strcat(fileName, "example"); break;
561 case seeAlso: strcat(fileName, "seeAlso"); break;
562 case returnValue: strcat(fileName, "returnValue"); break;
563 case enumerationValue:
564 strcat(fileName, "enumeration values/");
565 strcat(fileName, ((NamedLink)data).name);
568 strcat(fileName, "definitions/");
569 strcat(fileName, ((Definition)data).name);
573 const char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
574 if(name) name += 2; else name = ((Property)data).name;
575 strcat(fileName, "conversions/");
576 strcat(fileName, name);
579 case memberDescription:
580 strcat(fileName, "data members/");
581 strcat(fileName, ((DataMember)data).name);
583 case propertyDescription:
584 strcat(fileName, "properties/");
585 strcat(fileName, ((Property)data).name);
592 strcat(fileName, "parameters/");
593 for(prev = data, count = 0; prev; prev = prev.prev, count++);
594 sprintf(name, "%s.%d", ((Type)data).name, count);
595 strcat(fileName, name);
601 static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
603 char fileName[MAX_LOCATION];
604 String contents = null;
607 FigureFileName(fileName, module, type, object, item, data);
608 file = FileOpen(fileName, read);
612 if((len = file.GetSize()))
614 contents = new char[len+1];
615 file.Read(contents, 1, len);
616 contents[len] = '\0';
623 for(c = 0; contents[c]; c++)
624 if(!isspace(contents[c])) break;
628 if(editing && !contents && !readOnly)
629 contents = CopyString($"[Add Text]");
633 class APIPageNameSpace : APIPage
635 NameSpace * nameSpace;
643 NameSpace * GetNameSpace()
648 void Generate(File f)
650 char nsName[1024], temp[1024];
656 while(ns && ns->name)
658 strcpy(temp, ns->name);
659 if(nsName[0]) strcat(temp, "::");
660 strcat(temp, nsName);
661 strcpy(nsName, temp);
664 // Generate Class Page
665 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
668 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
669 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);
672 f.Printf($"<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
675 ns = nameSpace->parent;
676 while(ns && ns->name)
678 strcpy(temp, ns->name);
679 if(nsName[0]) strcat(temp, "::");
680 strcat(temp, nsName);
681 strcpy(nsName, temp);
685 f.Printf($"Parent namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
689 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
692 f.Printf($"<H3>Description</H3><br><br>\n");
695 char fileName[MAX_LOCATION];
696 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
697 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
699 f.Printf("</a><br><br>");
702 f.Printf("%s<br><br>", desc);
707 if(nameSpace->nameSpaces.first)
710 for(ns = (NameSpace *)nameSpace->nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
712 char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
715 f.Printf($"<H3>Sub Namespaces</H3><br><br>\n");
716 f.Printf("<TABLE>\n");
720 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);
725 char fileName[MAX_LOCATION];
726 FigureFileName(fileName, module, nameSpaceDoc, ns, description, null);
727 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
729 f.Printf("</a></TD>");
732 f.Printf("<TD valign=top height=22> %s</TD>", desc);
735 f.Printf("</TR><br>\n");
738 f.Printf("</TABLE><br>\n");
741 if(nameSpace->classes.first)
744 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
746 Class cl = link.data;
747 if(!cl.templateClass)
749 char * desc = ReadDoc(module, classDoc, cl, description, null);
753 f.Printf($"<a name=Classes></a><H3>Classes</H3><br><br>\n");
754 f.Printf("<TABLE>\n");
760 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);
765 char fileName[MAX_LOCATION];
766 FigureFileName(fileName, module, classDoc, cl, description, null);
767 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
769 f.Printf("</a></TD>");
772 f.Printf("<TD valign=top height=22>%s</TD>", desc);
779 f.Printf("</TABLE><br>\n");
782 if(nameSpace->functions.first)
785 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
787 GlobalFunction function = link.data;
788 char * desc = ReadDoc(module, functionDoc, function, description, null);
789 const char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
790 if(name) name += 2; else name = function.name;
793 f.Printf($"<a name=Functions></a><H3>Functions</H3><br><br>\n");
794 f.Printf("<TABLE>\n");
798 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);
803 char fileName[MAX_LOCATION];
804 FigureFileName(fileName, module, functionDoc, function, description, null);
805 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
807 f.Printf("</a></TD>");
810 f.Printf("<TD valign=top height=22> %s</TD>", desc);
813 f.Printf("</TR><br>\n");
816 f.Printf("</TABLE><br>\n");
819 if(nameSpace->defines.first)
822 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
824 DefinedExpression def = link.data;
825 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
828 f.Printf($"<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
829 f.Printf("<TABLE>\n");
833 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);
834 f.Printf("<TD valign=top height=22>%s</TD>", def.value);
839 char fileName[MAX_LOCATION];
840 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, definition, def);
841 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
843 f.Printf("</a></TD>");
846 f.Printf("<TD valign=top height=22> %s</TD>", desc);
849 f.Printf("</TR><br>\n");
852 f.Printf("</TABLE><br>\n");
855 f.Printf("</FONT></BODY></HTML>\n");
859 class APIPageClass : APIPage
868 NameSpace * GetNameSpace()
873 void Generate(File f)
878 char nsName[1024], temp[1024];
879 NameSpace * ns = cl.nameSpace;
880 Module module = cl.module;
883 while(ns && ns->name)
885 strcpy(temp, ns->name);
886 if(nsName[0]) strcat(temp, "::");
887 strcat(temp, nsName);
888 strcpy(nsName, temp);
891 // Generate Class Page
892 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
893 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
895 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);
897 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
900 const char * classType = null;
904 classType = $"Bit Collection";
907 classType = $"Enumeration";
910 classType = $"Structure";
913 classType = $"Class";
916 classType = $"Class (No header)";
922 classType = $"Basic Data Type";
925 f.Printf($"Type: %s<br>\n", classType);
928 if(cl.type != systemClass && cl.base)
930 f.Printf($"Base Class: ");
931 if(!strcmp(cl.base.name, "struct") || !strcmp(cl.base.name, "class"))
933 f.Printf(cl.type == bitClass ? cl.dataTypeString : $"None");
935 else if(cl.type == enumClass && !strcmp(cl.base.name, "enum"))
936 f.Printf("%s", cl.dataTypeString);
938 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", cl.base.templateClass ? cl.base.templateClass : cl.base, cl.base.name);
943 char * desc = ReadDoc(module, classDoc, cl, description, null);
946 f.Printf($"<br><H3>Description</H3><br><br>\n");
949 char fileName[MAX_LOCATION];
950 FigureFileName(fileName, module, classDoc, cl, description, null);
951 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
953 f.Printf("</a><br><br>");
956 f.Printf("%s<br><br>", desc);
961 if(cl.type == enumClass)
963 EnumClassData enumeration = (EnumClassData)cl.data;
964 if(enumeration.values.first)
968 f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
969 f.Printf("<TABLE>\n");
971 for(item = enumeration.values.first; item; item = item.next)
973 char * desc = ReadDoc(module, classDoc, cl, enumerationValue, item);
974 bool needClass = true;
977 char tempString[1024];
979 while(base.type == enumClass) base = base.base;
981 if(base.type == systemClass ||
982 (base.type == bitClass && base.membersAndProperties.first && !strcmp(cl.fullName, ((DataMember)base.membersAndProperties.first).dataTypeString)))
985 base.dataType = ProcessTypeString(base.dataTypeString, false);
987 if(base.dataType.kind != classType)
992 PrintType(base.dataType, string, false, true);
993 classSym = FindClass(string);
994 dataClass = classSym ? classSym.registered : null;
997 dataClass = base.dataType._class ? base.dataType._class.registered : null;
1003 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);
1004 if(dataClass.type == systemClass)
1007 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)dataClass._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1010 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)eSystem_FindClass(componentsApp, "class")._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1012 f.Printf("<TD valign=top height=22 nowrap=1>%s { %s }</TD>", dataClass.name, s);
1014 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", s);
1019 char fileName[MAX_LOCATION];
1020 FigureFileName(fileName, module, classDoc, cl, enumerationValue, item);
1021 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1023 f.Printf("</a></TD>");
1026 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1031 f.Printf("</TABLE><BR>\n");
1035 if(cl.conversions.first)
1037 f.Printf($"<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
1038 f.Printf("<TABLE>\n");
1039 for(prop = cl.conversions.first; prop; prop = prop.next)
1041 if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
1043 char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
1045 Type type = ProcessTypeString(prop.name, false);
1046 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
1047 if(name) name += 2; else name = prop.name;
1052 DocPrintType(type, 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[typeDataType], string);
1059 char fileName[MAX_LOCATION];
1060 FigureFileName(fileName, module, classDoc, cl, conversion, prop);
1061 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1063 f.Printf("</a></TD>");
1066 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1070 f.Printf("</TR>\n");
1075 f.Printf("</TABLE><br>\n");
1078 if(cl.membersAndProperties.first)
1081 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1083 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1087 f.Printf($"<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
1088 f.Printf("<TABLE>\n");
1094 char * desc = ReadDoc(module, classDoc, cl, propertyDescription, prop);
1096 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1100 DocPrintType(prop.dataType, string, true, false);
1102 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);
1103 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
1108 char fileName[MAX_LOCATION];
1109 FigureFileName(fileName, module, classDoc, cl, propertyDescription, prop);
1110 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1112 f.Printf("</a></TD>");
1115 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1118 f.Printf("</TR>\n");
1122 AddDataMemberToPage(f, (DataMember)prop, 0, showPrivate);
1127 f.Printf("</TABLE><br>\n");
1130 if(cl.methods.first)
1134 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1136 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type == virtualMethod)
1138 char * desc = ReadDoc(module, methodDoc, method, description, null);
1141 f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
1142 f.Printf("<TABLE>\n");
1145 if(!method.dataType)
1146 ProcessMethodType(method);
1149 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);
1154 char fileName[MAX_LOCATION];
1155 FigureFileName(fileName, module, methodDoc, method, description, null);
1156 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1158 f.Printf("</a></TD>");
1161 f.Printf("<TD valign=top height=22> %s</TD>", desc);
1164 f.Printf("</TR><br>\n");
1168 f.Printf("</TABLE><br>\n");
1170 // Non-Virtual Methods
1172 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1174 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type != virtualMethod)
1176 char * desc = ReadDoc(module, methodDoc, method, description, null);
1179 f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
1180 f.Printf("<TABLE>\n");
1184 if(!method.dataType)
1185 ProcessMethodType(method);
1188 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);
1193 char fileName[MAX_LOCATION];
1194 FigureFileName(fileName, module, methodDoc, method, description, null);
1195 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1197 f.Printf("</a></TD>");
1200 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1204 f.Printf("</TR><br>\n");
1208 f.Printf("</TABLE><br>\n");
1211 char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
1214 f.Printf($"<H3>Usage</H3><br>\n");
1217 char fileName[MAX_LOCATION];
1218 FigureFileName(fileName, module, classDoc, cl, usage, null);
1219 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1224 f.Printf("<br>%s\n", usageDoc);
1225 f.Printf("<br><br>\n");
1230 char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
1233 f.Printf($"<H3>Example</H3><br>\n");
1234 f.Printf($"<FONT face=\"Courier New\">\n");
1235 f.Printf("<br><TABLE>\n");
1238 char fileName[MAX_LOCATION];
1239 FigureFileName(fileName, module, classDoc, cl, example, null);
1240 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1242 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1245 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1247 f.Printf("</TABLE></FONT>\n");
1253 char * remarksDoc = ReadDoc(module, classDoc, cl, remarks, null);
1257 f.Printf($"<H3>Remarks</H3><br>\n");
1260 char fileName[MAX_LOCATION];
1261 FigureFileName(fileName, module, classDoc, cl, remarks, null);
1262 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1267 f.Printf("<br>%s\n", remarksDoc);
1268 f.Printf("<br><br>\n");
1273 if(cl.type != systemClass)
1277 for(c = cl.derivatives.first; c; c = c.next)
1279 Class deriv = c.data;
1280 // TO VERIFY: Does this properly check public status?
1281 if(eSystem_FindClass(componentsApp, deriv.fullName))
1285 f.Printf($"<H3>Derived Classes</H3><br>\n");
1291 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
1295 f.Printf("<br><br>\n");
1298 char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
1301 f.Printf($"<H3>See Also</H3><br>\n");
1304 char fileName[MAX_LOCATION];
1305 FigureFileName(fileName, module, classDoc, cl, seeAlso, null);
1306 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1311 f.Printf("<br>%s\n", seeAlsoDoc);
1312 f.Printf("<br><br>\n");
1316 f.Printf("</FONT></BODY></HTML>\n");
1320 class APIPageMethod : APIPage
1326 return method._class.module;
1329 NameSpace * GetNameSpace()
1331 return method._class.nameSpace;
1334 void Generate(File f)
1336 Class cl = method._class;
1338 Module module = cl.module;
1340 char nsName[1024], temp[1024];
1341 NameSpace * ns = cl.nameSpace;
1344 while(ns && ns->name)
1346 strcpy(temp, ns->name);
1347 if(nsName[0]) strcat(temp, "::");
1348 strcat(temp, nsName);
1349 strcpy(nsName, temp);
1353 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1354 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1356 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);
1358 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
1359 f.Printf("Class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl, cl.name);
1360 if(method.dataType.staticMethod)
1362 f.Printf($"this pointer class: None<br>\n");
1364 else if(method.dataType.thisClass && method.dataType.thisClass.registered && (method.dataType.thisClass.registered != method._class || method.type == virtualMethod))
1366 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);
1369 // Generate Method Page
1371 if(!method.dataType.name)
1372 method.dataType.name = CopyString(method.name);
1373 DocPrintType(method.dataType, string, true, false);
1374 f.Printf("<br>%s", string);
1377 char * desc = ReadDoc(module, methodDoc, method, description, null);
1380 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1383 char fileName[MAX_LOCATION];
1384 FigureFileName(fileName, module, methodDoc, method, description, null);
1385 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1390 f.Printf("%s", desc);
1395 f.Printf("<br><br>\n");
1396 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1398 f.Printf($"<H3>Parameters</H3><br><br>\n");
1400 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1401 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1403 f.Printf("<TABLE valign=center>\n");
1406 for(param = method.dataType.params.first; param; param = param.next)
1408 // ADD DESCRIPTION HERE
1409 if(param.kind != voidType)
1411 char * desc = ReadDoc(module, methodDoc, method, parameter, param);
1414 DocPrintType(param, string, false, false);
1416 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1417 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1422 char fileName[MAX_LOCATION];
1423 FigureFileName(fileName, module, methodDoc, method, parameter, param);
1424 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1426 f.Printf("</a></TD>\n");
1429 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1433 f.Printf("</TR>\n");
1436 if(method.dataType.returnType && method.dataType.returnType.kind != voidType)
1438 char * desc = ReadDoc(module, methodDoc, method, returnValue, null);
1439 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1441 f.Printf("<TR><TD> </TD></TR>");
1444 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1446 DocPrintType(method.dataType.returnType, string, false, false);
1447 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1452 char fileName[MAX_LOCATION];
1453 FigureFileName(fileName, module, methodDoc, method, returnValue, null);
1454 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1456 f.Printf("</a> </TD>\n");
1459 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1462 f.Printf("</TR>\n");
1463 f.Printf("</TABLE>\n");
1465 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1466 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1468 f.Printf("</TABLE><br>\n");
1471 char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
1474 f.Printf($"<H3>Usage</H3><br>\n");
1477 char fileName[MAX_LOCATION];
1478 FigureFileName(fileName, module, methodDoc, method, usage, null);
1479 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1484 f.Printf("<br>%s\n", usageDoc);
1485 f.Printf("<br><br>\n");
1490 char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
1493 f.Printf($"<H3>Example</H3><br>\n");
1494 f.Printf($"<FONT face=\"Courier New\">\n");
1495 f.Printf("<br><TABLE>\n");
1498 char fileName[MAX_LOCATION];
1499 FigureFileName(fileName, module, methodDoc, method, example, null);
1500 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1502 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1505 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1506 f.Printf("</TABLE></FONT>\n");
1512 char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
1515 f.Printf($"<H3>Remarks</H3><br>\n");
1518 char fileName[MAX_LOCATION];
1519 FigureFileName(fileName, module, methodDoc, method, remarks, null);
1520 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1525 f.Printf("<br>%s\n", method, remarksDoc);
1526 f.Printf("<br><br>\n");
1531 char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
1534 f.Printf($"<H3>See Also</H3><br>\n");
1537 char fileName[MAX_LOCATION];
1538 FigureFileName(fileName, module, methodDoc, method, seeAlso, null);
1539 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1544 f.Printf("<br>%s\n", method, seeAlsoDoc);
1546 f.Printf("<br><br>\n");
1550 f.Printf("</FONT></BODY></HTML>\n");
1554 class APIPageFunction : APIPage
1556 GlobalFunction function;
1560 return function.module;
1563 NameSpace * GetNameSpace()
1565 return function.nameSpace;
1568 void Generate(File f)
1571 Module module = function.module;
1573 char nsName[1024], temp[1024];
1574 NameSpace * ns = function.nameSpace;
1577 while(ns && ns->name)
1579 strcpy(temp, ns->name);
1580 if(nsName[0]) strcat(temp, "::");
1581 strcat(temp, nsName);
1582 strcpy(nsName, temp);
1586 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1587 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1589 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);
1592 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", function.nameSpace, nsName);
1594 if(!function.dataType)
1595 function.dataType = ProcessTypeString(function.dataTypeString, false);
1597 if(function.dataType.thisClass && function.dataType.thisClass.registered)
1599 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);
1602 // Generate Method Page
1604 if(!function.dataType.name)
1605 function.dataType.name = CopyString(function.name);
1606 DocPrintType(function.dataType, string, true, false);
1607 f.Printf("<br>%s", string);
1610 char * desc = ReadDoc(module, functionDoc, function, description, null);
1613 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1616 char fileName[MAX_LOCATION];
1617 FigureFileName(fileName, module, functionDoc, function, description, null);
1618 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1623 f.Printf("%s", desc);
1627 f.Printf("<br><br>\n");
1628 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1630 f.Printf($"<H3>Parameters</H3><br><br>\n");
1632 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1633 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1635 f.Printf("<TABLE valign=center>\n");
1638 for(param = function.dataType.params.first; param; param = param.next)
1640 // ADD DESCRIPTION HERE
1641 if(param.kind != voidType)
1643 char * desc = ReadDoc(module, functionDoc, function, parameter, param);
1646 DocPrintType(param, string, false, false);
1648 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1649 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1654 char fileName[MAX_LOCATION];
1655 FigureFileName(fileName, module, functionDoc, function, parameter, param);
1656 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1659 f.Printf("</a> </TD>\n");
1662 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1665 f.Printf("</TR>\n");
1668 if(function.dataType.returnType && function.dataType.returnType.kind != voidType)
1670 char * desc = ReadDoc(module, functionDoc, function, returnValue, null);
1671 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1673 f.Printf("<TR><TD> </TD></TR>");
1676 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1678 DocPrintType(function.dataType.returnType, string, false, false);
1679 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1684 char fileName[MAX_LOCATION];
1685 FigureFileName(fileName, module, functionDoc, function, returnValue, null);
1686 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1688 f.Printf("</a> </TD>\n");
1691 f.Printf("<TD valign=top height=22>%s </TD>\n", function, desc);
1694 f.Printf("</TR>\n");
1695 f.Printf("</TABLE>\n");
1697 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1698 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1700 f.Printf("</TABLE><br>\n");
1703 char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
1706 f.Printf($"<H3>Usage</H3><br>\n");
1709 char fileName[MAX_LOCATION];
1710 FigureFileName(fileName, module, functionDoc, function, usage, null);
1711 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1716 f.Printf("<br>%s\n", usageDoc);
1717 f.Printf("<br><br>\n");
1722 char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
1725 f.Printf($"<H3>Example</H3><br>\n");
1726 f.Printf($"<FONT face=\"Courier New\">\n");
1727 f.Printf("<br><TABLE>\n");
1730 char fileName[MAX_LOCATION];
1731 FigureFileName(fileName, module, functionDoc, function, example, null);
1732 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1734 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1737 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1738 f.Printf("</TABLE></FONT>\n");
1744 char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
1747 f.Printf($"<H3>Remarks</H3><br>\n");
1750 char fileName[MAX_LOCATION];
1751 FigureFileName(fileName, module, functionDoc, function, remarks, null);
1752 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1757 f.Printf("<br>%s\n", remarksDoc);
1758 f.Printf("<br><br>\n");
1763 char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
1766 f.Printf($"<H3>See Also</H3><br>\n");
1769 char fileName[MAX_LOCATION];
1770 FigureFileName(fileName, module, functionDoc, function, seeAlso, null);
1771 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1776 f.Printf("<br>%s\n", seeAlsoDoc);
1777 f.Printf("<br><br>\n");
1781 f.Printf("</FONT></BODY></HTML>\n");
1785 static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, const char * parentName, bool showPrivate)
1789 NameSpace * nameSpace = mainNameSpace;
1791 DataRow classesRow = null;
1792 DataRow functionsRow = null, definesRow = null;
1795 strcpy(nsName, parentName ? parentName : "");
1799 strcat(nsName, "::");
1800 strcat(nsName, nameSpace->name);
1805 row = parentRow.AddRow();
1806 row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
1807 row.tag = (int64)nameSpace;
1808 row.icon = mainForm.icons[typeNameSpace];
1812 // "Global NameSpace"
1814 page = parentRow.GetData(null);
1817 for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1819 NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
1820 AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
1822 if(comNameSpace != null)
1824 for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1826 if(!mainNameSpace.nameSpaces.FindString(ns->name))
1828 AddNameSpace(row, module, ns, null, nsName, showPrivate);
1833 if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
1835 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1837 if(nameSpace->classes.first)
1841 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
1844 if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
1846 if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { $"Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
1847 AddClass(classesRow, module, cl, nsName, showPrivate);
1854 if(mainNameSpace.functions.first || (comNameSpace && comNameSpace.functions.first))
1856 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1858 if(nameSpace->functions.first)
1862 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
1865 if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
1867 const char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
1869 if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
1870 fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int64)fn;
1877 if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
1879 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1881 if(nameSpace->defines.first)
1885 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
1888 //if(def.module == module)
1890 char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
1892 if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
1893 defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int64)def;
1901 static void AddDataMemberToPage(File f, DataMember member, int indent, bool showPrivate)
1905 if(!member.dataType)
1906 member.dataType = ProcessTypeString(member.dataTypeString, false);
1910 DocPrintType(member.dataType, string, true, false);
1912 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a>", member);
1913 for(c = 0; c<indent; c++)
1914 f.Printf(" ");
1915 f.Printf("<img valign=center src=\"%s\"> %s</TD>", iconNames[typeData], member.name ? member.name : ((member.type == structMember) ? "(struct)" : "(union)"));
1916 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", (member.type == normalMember) ? string : "");
1917 if(member.type == normalMember)
1919 char * desc = ReadDoc(member._class.module, classDoc, member._class, memberDescription, member);
1924 char fileName[MAX_LOCATION];
1925 FigureFileName(fileName, member._class.module, classDoc, member._class, memberDescription, member);
1926 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1928 f.Printf("</a></TD>");
1931 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1936 f.Printf("<TD valign=top height=22></TD>");
1938 if(member.type != normalMember)
1940 DataMember subMember;
1941 for(subMember = member.members.first; subMember; subMember = subMember.next)
1943 if((subMember.memberAccess == publicAccess || (subMember.memberAccess == privateAccess && showPrivate)))
1945 AddDataMemberToPage(f, subMember, indent + 1, showPrivate);
1949 f.Printf("</TR><br>\n");
1952 static void AddDataMember(DataRow parentRow, APIPage page, DataMember member)
1955 if(member.type == normalMember)
1957 row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
1958 row.tag = (int64)member;
1963 row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
1964 row.icon = mainForm.icons[typeData];
1965 row.tag = (int64)member;
1967 for(m = member.members.first; m; m = m.next)
1969 if(m.memberAccess == publicAccess || (m.memberAccess == privateAccess && page.showPrivate))
1970 AddDataMember(row, page, m);
1975 static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
1980 DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
1981 DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
1984 row = parentRow.AddRow();
1985 row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
1986 row.tag = (int64)cl;
1987 row.collapsed = true;
1988 row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
1991 if(cl.methods.first)
1993 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1995 if(method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate))
1998 if(!method.dataType)
1999 ProcessMethodType(method);
2000 if(method.type == virtualMethod)
2002 if(method.dataType.thisClass)
2004 if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { $"Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
2005 mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
2006 mRow.tag = (int64)method;
2010 if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { $"Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
2011 mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2012 mRow.tag = (int64)method;
2017 if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { $"Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
2018 mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2019 mRow.tag = (int64)method;
2025 if(cl.membersAndProperties.first)
2027 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
2029 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
2032 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
2036 if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { $"Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
2037 mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
2038 mRow.tag = (int64)prop;
2042 if(!membersRow) { membersRow = row.AddRow(); membersRow.SetData(null, APIPage { $"Data Members", page = page }); membersRow.collapsed = true; membersRow.icon = mainForm.icons[typeData]; membersRow.tag = 6; }
2043 AddDataMember(membersRow, page, (DataMember)prop);
2049 if(cl.conversions.first)
2051 for(prop = cl.conversions.first; prop; prop = prop.next)
2055 if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { $"Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
2056 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
2057 if(name) name += 2; else name = prop.name;
2058 mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
2059 mRow.tag = (int64)prop;
2062 if(cl.type == enumClass)
2064 EnumClassData enumeration = (EnumClassData)cl.data;
2066 for(item = enumeration.values.first; item; item = item.next)
2069 if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
2070 mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
2071 mRow.tag = (int64)item;
2076 class AddressBar : Window
2078 background = activeBorder;
2082 this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, bitmap = { ":actions/docOpen.png" };
2084 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2086 MainForm mainForm = (MainForm)parent;
2087 FileDialog fileDialog = mainForm.fileDialog;
2088 if(fileDialog.Modal() == ok)
2089 mainForm.OpenModule(fileDialog.filePath);
2095 this, bevelOver = true, inactive = true, anchor = Anchor { left = 28, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
2098 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2100 ((MainForm)parent).Back();
2106 this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
2109 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2111 ((MainForm)parent).Forward();
2117 this, bevelOver = true, inactive = true, anchor = Anchor { left = 80, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
2119 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2121 ((MainForm)parent).Home();
2125 /* TODO: Search (#143/#441)
2126 When there's something in the search box, list matching sections, the exact match first,instead of the Hierarchy in the ListBox.
2127 Update this in the NotifyUpdate. Enter goes to the exact match.
2129 Label { this, anchor = Anchor { left = (124+12) }, labeledWindow = search };
2133 this, text = "Search:", anchor = Anchor { left = (16+48+124), right = 60, top = 0, bottom = 0 }, hotKey = altD;
2135 bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
2137 if(!disabled && (SmartKey)key == enter)
2138 ((MainForm)parent).Go(editBox.contents);
2142 void NotifyUpdate(EditBox editBox)
2144 String location = ((MainForm)parent).view.location;
2145 disabled = !strcmp(location ? location : "", editBox.contents);
2150 bool OnKeyHit(Key key, unichar ch)
2153 ((MainForm)parent).view.MakeActive();
2158 class MainForm : Window
2160 size = { 1000, 600 };
2162 borderStyle = sizable;
2165 icon = { ":documentorIcon.png" };
2166 text = $"API Documentation Browser";
2168 BitmapResource icons[CodeObjectType];
2173 for(c = 0; c < CodeObjectType::enumSize; c++)
2175 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2177 browser.AddField(DataField { dataType = class(APIPage) });
2182 Menu fileMenu { menu, $"File", f };
2183 Array<FileFilter> fileFilters
2185 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2186 { $"eC Symbol files (*.sym)", "sym" }
2189 FileDialog fileDialog
2191 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2193 MenuItem fileOpenItem
2195 fileMenu, $"Open...", o, ctrlO;
2197 bool NotifySelect(MenuItem selection, Modifiers mods)
2199 if(fileDialog.Modal() == ok)
2201 OpenModule(fileDialog.filePath);
2206 MenuItem fileSettingsItem
2208 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2210 bool NotifySelect(MenuItem selection, Modifiers mods)
2212 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2222 MenuDivider { fileMenu };
2223 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2225 void OpenModule(const char * filePath)
2227 char moduleName[MAX_LOCATION];
2228 char extension[MAX_EXTENSION];
2229 Module module = null;
2230 static char symbolsDir[MAX_LOCATION];
2234 FreeContext(globalContext);
2235 FreeExcludedSymbols(excludedSymbols);
2236 ::defines.Free(FreeModuleDefine);
2237 imports.Free(FreeModuleImport);
2239 FreeGlobalData(globalData);
2240 FreeTypeData(componentsApp);
2242 delete componentsApp;
2244 SetGlobalContext(globalContext);
2245 componentsApp = __ecere_COM_Initialize(false, 1, null);
2246 SetPrivateModule(componentsApp);
2248 StripLastDirectory(filePath, symbolsDir);
2249 SetSymbolsDir(symbolsDir);
2251 GetExtension(filePath, extension);
2253 mainForm.browser.Clear();
2255 ImportModule(filePath, normalImport, publicAccess, false);
2257 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
2258 componentsApp.name = CopyString(filePath);
2260 for(module = componentsApp.allModules.first; module; module = module.next)
2262 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2266 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2267 AddComponents(componentsApp, false);
2269 GetLastDirectory(filePath, moduleName);
2270 // Extension, path and lib prefix get removed in Module::name
2273 StripExtension(moduleName);
2274 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
2276 int len = strlen(moduleName) - 3;
2277 memmove(moduleName, moduleName + 3, len);
2278 moduleName[len] = 0;
2282 for(module = componentsApp.allModules.first; module; module = module.next)
2284 if(module.name && (!strcmp(module.name, moduleName)))
2287 if(!module) module = componentsApp;
2288 homeModule = module;
2289 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2291 SetSymbolsDir(null);
2294 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2297 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2298 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2301 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2303 APIPage page = row.GetData(null);
2304 if(view.edit) view.OnLeftButtonDown(0,0,0);
2305 if(page && page.page) page = page.page;
2307 view.PositionCaret(true);
2308 if(page != view.page)
2310 Window activeChild = this.activeChild;
2312 // Back / Forward Support
2313 if(row && !dontRecordHistory)
2315 if(history.count > historyPos+1)
2316 history.count = historyPos+1;
2317 historyPos = history.count-1;
2318 addressBar.back.disabled = (historyPos == 0);
2319 addressBar.forward.disabled = (historyPos >= history.count-1);
2321 history.Add((Instance)(uint64)row.tag);
2322 historyPos = history.count-1;
2324 addressBar.back.disabled = (historyPos == 0);
2325 addressBar.forward.disabled = (historyPos >= history.count-1);
2331 activeChild.Activate();
2333 else if(!view.created)
2337 page = row.GetData(null);
2338 if(page && page.page)
2342 case 1: view.GoToAnchor("Classes"); break;
2343 case 2: view.GoToAnchor("Functions"); break;
2344 case 3: view.GoToAnchor("Definitions"); break;
2345 case 4: view.GoToAnchor("VirtualMethods"); break;
2346 case 5: view.GoToAnchor("Methods"); break;
2347 case 6: view.GoToAnchor("Members"); break;
2348 case 7: view.GoToAnchor("Conversions"); break;
2349 case 8: view.GoToAnchor("EnumerationValues"); break;
2353 sprintf(hex, "%p", (void *)(uintptr)row.tag);
2354 view.GoToAnchor(hex);
2360 view.SetScrollPosition(0, 0);
2368 this, anchor = { top = 26, bottom = 0, right = 0 };
2373 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2376 bool OnClose(bool parentClosing)
2379 view.OnLeftButtonDown(0,0,0);
2385 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2386 //mainForm.OpenModule("ec");
2387 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2388 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2390 int index = mainForm.browser.currentRow.index;
2391 int rowHeight = mainForm.browser.rowHeight;
2392 int height = mainForm.browser.clientSize.h;
2394 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2399 Array<Instance> history { };
2401 bool dontRecordHistory;
2406 if(historyPos < history.count-1)
2410 addressBar.back.disabled = (historyPos == 0);
2411 addressBar.forward.disabled = (historyPos >= history.count-1);
2412 sprintf(location, "api://%p", history[historyPos]);
2413 dontRecordHistory = true;
2414 view.OnOpen(location);
2415 dontRecordHistory = false;
2427 addressBar.back.disabled = (historyPos == 0);
2428 addressBar.forward.disabled = (historyPos >= history.count-1);
2429 sprintf(location, "api://%p", history[historyPos]);
2430 dontRecordHistory = true;
2431 view.OnOpen(location);
2432 dontRecordHistory = false;
2440 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2444 class EditDialog : Window
2446 borderStyle = sizable;
2447 size = { 600, 400 };
2452 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2456 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2460 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2464 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2465 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2467 class HelpView : HTMLView
2471 hasVertScroll = true;
2472 hasHorzScroll = true;
2474 char editString[MAX_LOCATION];
2480 page = mainForm.browser.currentRow.GetData(null);
2485 char docFile[MAX_LOCATION];
2487 Module module = page ? page.GetModule() : null;
2488 NameSpace * ns = page ? page.GetNameSpace() : null;
2490 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2491 if(FileExists(docFile))
2493 archive = ArchiveOpen(docFile, { true } );
2494 readOnly = archive == null;
2500 archive = ArchiveOpen(docFile, { true } );
2503 // Must create root directory on archive creation
2504 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2516 GoToAnchor(page.label);
2518 if(page.page) page = page.page;
2521 return HTMLView::OnCreate();
2530 char archiveFile[MAX_LOCATION];
2531 char fileName[MAX_FILENAME];
2532 char directory[MAX_LOCATION];
2533 const char * location;
2534 Archive archive = null;
2535 if(SplitArchivePath(editString, archiveFile, &location))
2537 GetLastDirectory(location, fileName);
2538 StripLastDirectory(location, directory);
2539 archive = ArchiveOpen(archiveFile, { true } );
2543 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2546 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2548 if(block.type == TEXT && block.textLen)
2556 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2558 if(block.type == BR)
2560 else if(block.type == TEXT)
2561 f.Write(block.text, 1, block.textLen);
2566 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2572 Block parent = textBlock.parent;
2573 while((block = parent.subBlocks.first))
2575 parent.subBlocks.Remove(block);
2578 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2579 textBlock.text = CopyString($"[Add Text]");
2580 textBlock.textLen = strlen(textBlock.text);
2581 parent.subBlocks.Add(textBlock);
2589 PositionCaret(true);
2595 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2599 if(edit && (!textBlock || overLink != textBlock.parent))
2603 HTMLView::OnLeftButtonDown(x, y, mods);
2604 selPosition = curPosition = 0;
2605 selBlock = textBlock;
2609 result = HTMLView::OnLeftButtonDown(x, y, mods);
2611 if(!edit && clickedLink)
2614 if(clickedLink == overLink && clickedLink.href)
2616 if(OnOpen(clickedLink.href))
2624 if(textBlock && overLink == textBlock.parent)
2626 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2627 selBlock = textBlock;
2628 PositionCaret(true);
2636 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2638 if(!edit || !textBlock || clickedLink != textBlock.parent)
2640 HTMLView::OnLeftButtonUp(x, y, mods);
2643 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2644 selBlock = textBlock;
2645 PositionCaret(true);
2656 bool OnMouseMove(int x, int y, Modifiers mods)
2658 if(edit && selecting)
2660 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2661 PositionCaret(true);
2664 return HTMLView::OnMouseMove(x, y, mods);
2667 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2669 if(edit && textBlock)
2675 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2676 selBlock = textBlock;
2677 for(c = curPosition; c >= 0; c--)
2680 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2681 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2682 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2688 for(c = start; c < textBlock.textLen; c += numBytes)
2690 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2691 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2694 selPosition = start;
2697 PositionCaret(true);
2705 bool OnOpen(char * href)
2707 if(!strncmp(href, "api://", 6))
2709 int64 tag = (int64)strtoull(href + 6, null, 16);
2710 DataRow row = mainForm.browser.FindSubRow(tag);
2714 mainForm.browser.SelectRow(row);
2715 while((row = row.parent))
2716 row.collapsed = false;
2717 row = mainForm.browser.currentRow;
2718 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2721 else if(!strncmp(href, "edit://", 7))
2724 int startX = clickedLink.startX, startY = clickedLink.startY;
2725 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2727 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2728 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2730 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2732 display.FontExtent(block.font.font, " ", 1, null, &th);
2735 block.parent.subBlocks.Insert(null, newBlock);
2740 block.parent.subBlocks.Insert(block, newBlock);
2741 startY += block.prev.height;
2743 newBlock.startX = startX;
2744 newBlock.startY = startY;
2745 newBlock.text = new0 char[1];
2749 textBlock = (Block)clickedLink.subBlocks.first;
2750 if(!strcmp(textBlock.text, $"[Add Text]"))
2752 textBlock.text[0] = 0;
2753 textBlock.textLen = 0;
2756 strcpy(editString, href + 7);
2757 selPosition = curPosition = 0;
2758 selBlock = textBlock;
2761 // PositionCaret(true);
2768 void DeleteSelection()
2770 if(textBlock != selBlock || curPosition != selPosition)
2772 if(textBlock == selBlock)
2774 // Within same block
2775 int start = Min(curPosition, selPosition);
2776 int end = Max(curPosition, selPosition);
2777 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2778 textBlock.textLen -= end-start;
2779 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2780 curPosition = start;
2781 selPosition = start;
2785 int startSel, endSel;
2786 Block startSelBlock = null, endSelBlock = null, b, next;
2788 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2790 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2791 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2793 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2794 for(b = startSelBlock.next; b; b = next)
2796 bool isEnd = b == endSelBlock;
2797 next = GetNextBlock(b);
2798 b.parent.subBlocks.Remove(b);
2803 textBlock = startSelBlock;
2804 selBlock = startSelBlock;
2805 curPosition = startSel;
2806 selPosition = startSel;
2810 PositionCaret(true);
2815 String GetSelectionString()
2817 String selection = null;
2818 if(textBlock == selBlock)
2820 // Within same block
2821 int start = Min(curPosition, selPosition);
2822 int end = Max(curPosition, selPosition);
2823 int len = end - start;
2824 selection = new char[len + 1];
2825 memcpy(selection, textBlock.text + start, len);
2830 int startSel, endSel;
2831 Block startSelBlock = null, endSelBlock = null, b;
2834 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2837 for(b = startSelBlock; b; b = GetNextBlock(b))
2839 int start = (b == startSelBlock) ? startSel : 0;
2840 int end = (b == endSelBlock) ? endSel : b.textLen;
2841 int len = end - start;
2843 if(b == endSelBlock)
2845 else if(b.type == TEXT)
2849 selection = new char[totalLen + 1];
2851 for(b = startSelBlock; b; b = GetNextBlock(b))
2853 int start = (b == startSelBlock) ? startSel : 0;
2854 int end = (b == endSelBlock) ? endSel : b.textLen;
2855 int len = end - start;
2856 memcpy(selection + totalLen, b.text + start, len);
2858 if(b == endSelBlock)
2860 else if(b.type == TEXT)
2861 selection[totalLen++] = '\n';
2863 selection[totalLen] = 0;
2868 void CopySelection()
2870 String s = GetSelectionString();
2873 int len = strlen(s);
2875 if(cb.Allocate(len + 1))
2877 memcpy(cb.text, s, len + 1);
2885 bool OnKeyDown(Key key, unichar ch)
2892 OnLeftButtonDown(0,0,0);
2894 case Key { end, shift = true }:
2896 curPosition = textBlock.textLen;
2899 selPosition = curPosition;
2900 selBlock = textBlock;
2902 PositionCaret(true);
2905 case Key { home, shift = true }:
2910 selPosition = curPosition;
2911 selBlock = textBlock;
2913 PositionCaret(true);
2916 case Key { home, ctrl = true, shift = true }:
2919 while(textBlock.prev)
2920 textBlock = textBlock.prev.prev;
2923 selPosition = curPosition;
2924 selBlock = textBlock;
2926 PositionCaret(true);
2929 case Key { end, ctrl = true, shift = true }:
2931 while(textBlock.next && textBlock.next.next)
2932 textBlock = textBlock.next.next;
2933 curPosition = textBlock.textLen;
2936 selPosition = curPosition;
2937 selBlock = textBlock;
2939 PositionCaret(true);
2945 return HTMLView::OnKeyDown(key, ch);
2949 bool OnKeyHit(Key key, unichar ch)
2955 case Key { up, shift = true }:
2958 if(caretY == textBlock.startY)
2962 textBlock = textBlock.prev.prev;
2963 curPosition = Min(curPosition, textBlock.textLen);
2966 selPosition = curPosition;
2967 selBlock = textBlock;
2970 PositionCaret(false);
2980 int sx = textBlock.startX, sy = textBlock.startY;
2981 char * text = textBlock.text;
2983 Block block = textBlock;
2984 while(block && block.type != TD) block = block.parent;
2987 Block table = block;
2988 while(table && table.type != TABLE) table = table.parent;
2990 maxW = block.w - 2* table.cellPadding;
2992 maxW = clientSize.w - 10 - sx;
2995 maxW = clientSize.w - 10 - sx;
2996 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3000 int startPos = textPos;
3003 bool lineComplete = false;
3004 for(; textPos<textBlock.textLen && !lineComplete;)
3008 char * nextSpace = strchr(text + textPos, ' ');
3011 len = (nextSpace - (text + textPos)) + 1;
3013 len = textBlock.textLen - textPos;
3015 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3017 if(x + width + w > maxW && x > 0)
3019 lineComplete = true;
3029 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3032 curPosition = textPos;
3033 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3036 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3037 len = curPosition - startPos;
3038 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3042 selPosition = curPosition;
3043 selBlock = textBlock;
3047 PositionCaret(false);
3051 if(sy == caretY - th || textPos == textBlock.textLen)
3053 if(textPos != textBlock.textLen)
3055 int c = textPos - 1;
3056 while(c > 0 && text[c] == ' ') c--;
3057 curPosition = c + 1;
3060 selPosition = curPosition;
3061 selBlock = textBlock;
3067 curPosition = textBlock.textLen;
3070 selPosition = curPosition;
3071 selBlock = textBlock;
3075 PositionCaret(false);
3079 sx = textBlock.startX;
3080 } while(textPos < textBlock.textLen);
3085 case Key { down, shift = true }:
3090 int sx = textBlock.startX, sy = textBlock.startY;
3091 char * text = textBlock.text;
3093 Block block = textBlock;
3094 while(block && block.type != TD) block = block.parent;
3097 Block table = block;
3098 while(table && table.type != TABLE) table = table.parent;
3100 maxW = block.w - 2* table.cellPadding;
3102 maxW = clientSize.w - 10 - sx;
3105 maxW = clientSize.w - 10 - sx;
3106 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3108 while(!textPos || textPos < textBlock.textLen)
3110 int startPos = textPos;
3113 bool lineComplete = false;
3114 for(; (textPos < textBlock.textLen) && !lineComplete;)
3118 char * nextSpace = strchr(text + textPos, ' ');
3121 len = (nextSpace - (text + textPos)) + 1;
3123 len = textBlock.textLen - textPos;
3125 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3127 if(x + width + w > maxW && x > 0)
3129 lineComplete = true;
3139 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3141 curPosition = textPos;
3143 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3146 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3147 len = curPosition - startPos;
3148 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3152 selPosition = curPosition;
3153 selBlock = textBlock;
3156 PositionCaret(false);
3162 curPosition = textBlock.textLen;
3165 selPosition = curPosition;
3166 selBlock = textBlock;
3169 PositionCaret(false);
3172 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3176 textBlock = textBlock.next.next;
3177 sy = textBlock.startY;
3178 sx = textBlock.startX;
3179 text = textBlock.text;
3184 sx = textBlock.startX;
3188 /*if(textBlock.next && textBlock.next.next)
3190 textBlock = textBlock.next.next;
3191 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3192 selBlock = textBlock;
3193 PositionCaret(false);
3197 case Key { right, shift = true, ctrl = true }:
3200 bool foundAlpha = false;
3202 Block line, lastLine;
3205 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3207 int start = (line == textBlock) ? curPosition : 0;
3209 for(c = start; c < line.textLen; c++)
3211 char ch = line.text[c];
3212 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3213 if(key.shift ? isAlUnder : !isAlUnder)
3227 selPosition = curPosition;
3228 selBlock = textBlock;
3232 PositionCaret(true);
3237 // No next word found,
3238 if(!found && (c != curPosition || line != textBlock))
3242 lastC = line.textLen-1;
3247 curPosition = line.textLen;
3250 selPosition = curPosition;
3251 selBlock = textBlock;
3256 PositionCaret(true);
3262 if(key.shift && found)
3264 curPosition = lastC+1;
3265 textBlock = lastLine;
3266 PositionCaret(true);
3271 case Key { left, ctrl = true, shift = true }:
3274 bool foundAlpha = false;
3276 Block line, lastLine;
3279 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3282 if(curPosition == 0 && line != textBlock)
3285 lastC = line.textLen;
3289 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3290 for(c = start; c>=0; c--)
3292 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3307 // No next word found,
3308 if(!found && curPosition > 0)
3318 textBlock = lastLine;
3319 curPosition = lastC;
3322 selPosition = curPosition;
3323 selBlock = textBlock;
3325 PositionCaret(true);
3330 case Key { right, shift = true }:
3332 if(curPosition < textBlock.textLen)
3334 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3337 selPosition = curPosition;
3338 selBlock = textBlock;
3340 PositionCaret(true);
3343 else if(textBlock.next && textBlock.next.next)
3345 textBlock = textBlock.next.next;
3349 selPosition = curPosition;
3350 selBlock = textBlock;
3352 PositionCaret(true);
3356 case Key { left, shift = true }:
3360 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3363 selPosition = curPosition;
3364 selBlock = textBlock;
3366 PositionCaret(true);
3369 else if(textBlock.prev)
3371 textBlock = textBlock.prev.prev;
3372 curPosition = textBlock.textLen;
3375 selPosition = curPosition;
3376 selBlock = textBlock;
3378 PositionCaret(true);
3384 if(textBlock == selBlock && curPosition == selPosition)
3388 int c = curPosition;
3390 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3391 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3392 textBlock.textLen -= nb;
3393 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3395 selPosition = curPosition;
3396 selBlock = textBlock;
3400 PositionCaret(true);
3403 else if(textBlock.prev)
3405 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3406 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3407 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3409 selPosition = curPosition = prevBlock.textLen;
3410 selBlock = textBlock;
3411 prevBlock.textLen += textBlock.textLen;
3412 textBlock.parent.subBlocks.Remove(prev);
3413 if(prev == selBlock)
3415 selBlock = textBlock;
3416 selPosition = curPosition;
3419 textBlock.parent.subBlocks.Remove(textBlock);
3420 if(textBlock == selBlock)
3422 selBlock = prevBlock;
3423 selPosition = curPosition;
3426 textBlock = prevBlock;
3430 PositionCaret(true);
3439 if(textBlock != selBlock || curPosition != selPosition)
3441 else if(textBlock.textLen > curPosition)
3443 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3444 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3445 textBlock.textLen -= nb;
3446 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3451 PositionCaret(true);
3454 else if(textBlock.next && textBlock.next.next)
3456 Block next = textBlock.next, nextBlock = textBlock.next.next;
3457 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3458 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3460 textBlock.textLen += nextBlock.textLen;
3461 textBlock.parent.subBlocks.Remove(next);
3462 if(next == selBlock)
3464 selBlock = textBlock;
3465 selPosition = curPosition;
3468 textBlock.parent.subBlocks.Remove(nextBlock);
3469 if(nextBlock == selBlock)
3471 selBlock = textBlock;
3472 selPosition = curPosition;
3478 PositionCaret(true);
3492 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3493 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3494 startY = textBlock.startY;
3495 startX = textBlock.startX;
3497 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3498 textBlock.parent.subBlocks.Insert(textBlock, block);
3499 textBlock.parent.subBlocks.Insert(block, newBlock);
3503 newBlock.textLen = textBlock.textLen - curPosition;
3504 newBlock.text = new char[newBlock.textLen+1];
3505 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3506 textBlock.textLen = curPosition;
3507 textBlock.text[curPosition] = 0;
3509 newBlock.startY = startY;
3510 newBlock.startX = startX;
3511 selPosition = curPosition = 0;
3516 textBlock = newBlock;
3517 selBlock = textBlock;
3518 PositionCaret(true);
3523 case Key { del, shift = true }:
3538 ClipBoard clipBoard { };
3539 if(clipBoard.Load())
3542 char * text = clipBoard.memory;
3550 parent = textBlock.parent;
3551 font = textBlock.font;
3556 if(ch == '\n' || ch == '\r' || !ch)
3558 int len = c - start;
3559 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3560 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3561 memcpy(textBlock.text + curPosition, text + start, len);
3562 textBlock.textLen += len;
3564 selPosition = curPosition;
3565 selBlock = textBlock;
3568 Block block { type = BR, parent = parent, font = font };
3569 Block newBlock { type = TEXT, parent = parent, font = font };
3570 int startY = textBlock.startY, startX = textBlock.startX;
3573 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3574 textBlock.parent.subBlocks.Insert(textBlock, block);
3575 textBlock.parent.subBlocks.Insert(block, newBlock);
3579 newBlock.textLen = textBlock.textLen - curPosition;
3580 newBlock.text = new char[newBlock.textLen+1];
3581 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3582 textBlock.textLen = curPosition;
3583 textBlock.text[curPosition] = 0;
3585 newBlock.startY = startY;
3586 newBlock.startX = startX;
3587 selPosition = curPosition = 0;
3588 selBlock = textBlock;
3589 textBlock = newBlock;
3591 if(ch == '\r' && text[c+1] == '\n') c++;
3597 PositionCaret(true);
3605 // eC BUG HERE: (Should be fixed)
3606 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3609 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3614 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3615 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3617 for(c = 0; c<len; c++)
3619 textBlock.text[curPosition] = string[c];
3620 textBlock.textLen++;
3623 selPosition = curPosition;
3624 selBlock = textBlock;
3627 //Clear(html.block);
3628 //CreateForms(html.block);
3633 PositionCaret(true);
3642 void OnResize(int width, int height)
3644 HTMLView::OnResize(width, height);
3645 PositionCaret(true);
3649 void PositionCaret(bool setCaretX)
3655 int sx = textBlock.startX, sy = textBlock.startY;
3656 char * text = textBlock.text;
3658 Block block = textBlock;
3659 while(block && block.type != TD) block = block.parent;
3662 Block table = block;
3663 while(table && table.type != TABLE) table = table.parent;
3665 maxW = block.w - 2* table.cellPadding;
3667 maxW = clientSize.w - 10 - sx;
3670 maxW = clientSize.w - 10 - sx;
3672 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3674 while(textPos < textBlock.textLen)
3676 int startPos = textPos;
3679 bool lineComplete = false;
3681 for(; textPos<textBlock.textLen && !lineComplete;)
3685 char * nextSpace = strchr(text + textPos, ' ');
3688 len = (nextSpace - (text + textPos)) + 1;
3690 len = textBlock.textLen - textPos;
3692 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3694 if(x + width + w > maxW && x > 0)
3696 lineComplete = true;
3709 if(curPosition < textPos || textPos == textBlock.textLen)
3711 int len = curPosition - startPos;
3712 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3717 sx = textBlock.startX;
3722 SetCaret(sx, sy, th);
3724 Point scrollPos = scroll;
3725 bool doScroll = false;
3726 if(sy - scroll.y + th > clientSize.h)
3728 scrollPos.y = sy + th - clientSize.h;
3731 else if(sy - scroll.y < 0)
3736 if(sx - scroll.x + 10 > clientSize.w)
3738 scrollPos.x = sx + 10 - clientSize.w;
3741 else if(sx - scroll.x < 10)
3743 scrollPos.x = sx - 10;
3754 // Returns a character offset into the TextBlock from a window coordinate
3755 int TextPosFromPoint(int px, int py, Block * block, bool half)
3757 Block parentBlock = this.textBlock.parent;
3760 *block = this.textBlock;
3765 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3767 int sx = textBlock.startX, sy = textBlock.startY;
3770 char * text = textBlock.text;
3772 Block b = textBlock;
3775 if(textBlock.type != TEXT) continue;
3777 while(b && b.type != TD) b = b.parent;
3781 while(table && table.type != TABLE) table = table.parent;
3783 maxW = b.w - 2* table.cellPadding;
3785 maxW = clientSize.w - 10 - sx;
3788 maxW = clientSize.w - 10 - sx;
3790 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3791 //space = space/2+2;
3794 while(textPos < textBlock.textLen)
3798 bool lineComplete = false;
3800 for(; textPos<textBlock.textLen && !lineComplete;)
3804 char * nextSpace = strchr(text + textPos, ' ');
3807 len = (nextSpace - (text + textPos)) + 1;
3809 len = textBlock.textLen - textPos;
3811 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3813 sx = x + textBlock.startX;
3814 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3819 for(c = textPos; (ch = text[c]); c += numBytes)
3821 numBytes = UTF8_NUM_BYTES(ch);
3822 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3823 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3830 if(x + width + w > maxW && x > 0)
3832 lineComplete = true;
3845 if(/*py >= sy && */py < sy + th)
3848 return textBlock.textLen;
3853 result = textBlock.textLen;
3859 Application componentsApp;
3861 class Documentor : GuiApplication
3865 Platform os = __runtimePlatform;
3866 componentsApp = __ecere_COM_Initialize(false, 1, null);
3867 SetPrivateModule(componentsApp);
3868 SetGlobalContext(globalContext);
3869 SetExcludedSymbols(&excludedSymbols);
3870 SetDefines(&::defines);
3871 SetImports(&imports);
3873 SetGlobalData(globalData);
3875 settingsContainer.dataOwner = &settings;
3876 settingsContainer.Load();
3877 if(!settings.docDir || !settings.docDir[0] )
3879 if(os == win32) // if Windows OS then
3881 char programFilesDir[MAX_LOCATION];
3882 char appData[MAX_LOCATION];
3883 char homeDrive[MAX_LOCATION];
3884 char winDir[MAX_LOCATION];
3885 GetEnvironment("APPDATA", appData, sizeof(appData));
3886 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3887 GetEnvironment("windir", winDir, sizeof(winDir));
3888 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3890 PathCat(programFilesDir, "ECERE SDK\\doc");
3891 settings.docDir = programFilesDir;
3893 else if(homeDrive[0])
3895 PathCat(homeDrive, "ECERE SDK\\doc");
3896 settings.docDir = homeDrive;
3900 PathCat(winDir, "..\\ECERE SDK\\doc");
3901 settings.docDir = winDir;
3904 settings.docDir = "C:\\ECERE SDK\\doc";
3906 else // if Os is Linux, or Mac OSX or something else
3907 settings.docDir = "/usr/share/ecere/doc/";
3908 settingsContainer.Save();
3914 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3916 AddComponents(module, true);
3917 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3918 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3919 while((row = row.parent))
3920 row.collapsed = false;
3924 commandThread.Create();
3928 bool Cycle(bool idle)
3931 mainForm.Destroy(0);
3940 if(commandThread.created)
3942 console.CloseInput();
3943 console.CloseOutput();
3945 commandThread.Wait();
3949 FreeContext(globalContext);
3950 FreeExcludedSymbols(excludedSymbols);
3951 ::defines.Free(FreeModuleDefine);
3952 imports.Free(FreeModuleImport);
3954 FreeGlobalData(globalData);
3955 FreeTypeData(componentsApp);
3957 delete componentsApp;
3961 ConsoleFile console { };
3962 MainForm mainForm { };
3965 Thread commandThread
3972 console.GetLine(command, sizeof(command));
3973 if(!quit && command[0])
3976 if(!strcmpi(command, "Activate"))
3977 mainForm.Activate();
3978 else if(!strcmpi(command, "Quit"))