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 void GetTemplateString(Class c, char * templateString)
59 Module m = c.module.application;
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)
116 if(type._class && type._class.string)
119 strcat(string, type._class.string);
122 if(type._class.registered)
125 char * s = type._class.registered.name;
126 sprintf(hex, "%p", type._class.registered.templateClass ? type._class.registered.templateClass : type._class.registered);
127 strcat(string, "<a href=\"api://");
129 strcat(string, "\" style=\"text-decoration: none;\">");
133 GetTemplateString(type._class.registered, n);
137 strcat(string, type._class.registered.name);
138 strcat(string, "</a>");
141 strcat(string, type._class.string);
148 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
149 if(funcType && funcType.kind == functionType)
152 DocPrintType(funcType.returnType, string, false, fullName);
153 strcat(string, "(*");
154 if(printName || funcType.thisClass)
157 if(funcType.thisClass)
159 strcat(string, funcType.thisClass.string);
160 strcat(string, "::");
163 strcat(string, type.name);
165 strcat(string, ")(");
166 for(param = funcType.params.first; param; param = param.next)
168 DocPrintType(param, string, false, fullName);
169 if(param.next) strcat(string, ", ");
175 _PrintType(type.type, string, false /*printName*/, printFunction, fullName);
176 if(string[strlen(string)-1] == '(')
179 strcat(string, " *");
183 case voidType: strcat(string, "void"); break;
184 case intType: strcat(string, type.isSigned ? "int" : "uint"); break;
185 case int64Type: strcat(string, type.isSigned ? "int64" : "uint64"); break;
186 case charType: strcat(string, type.isSigned ? "char" : "byte"); break;
187 case shortType: strcat(string, type.isSigned ? "short" : "uint16"); break;
188 case floatType: strcat(string, "float"); break;
189 case doubleType: strcat(string, "double"); break;
193 strcat(string, "struct ");
194 strcat(string, type.enumName);
196 else if(type.typeName)
198 strcat(string, type.typeName);
203 strcat(string, "struct ");
204 strcat(string,"(unnamed)");
207 strcat(string, "struct {");
208 for(member = type.members.first; member; member = member.next)
210 DocPrintType(member, string, true, fullName);
219 strcat(string, "union ");
220 strcat(string, type.enumName);
222 else if(type.typeName)
224 strcat(string, type.typeName);
228 strcat(string, "union ");
229 strcat(string,"(unnamed)");
235 strcat(string, "enum ");
236 strcat(string, type.enumName);
238 else if(type.typeName)
240 strcat(string, type.typeName);
243 strcat(string, "enum");
250 strcat(string, "dllexport ");
251 DocPrintType(type.returnType, string, false, fullName);
255 // DANGER: Testing This
261 strcat(string, type.name);
264 char * name = RSearchString(type.name, "::", strlen(type.name), true, false);
265 if(name) name += 2; else name = type.name;
266 strcat(string, "<b>");
267 strcat(string, name);
268 strcat(string, "</b>");
281 for(param = type.params.first; param; param = param.next)
283 DocPrintType(param, string, true, fullName);
284 if(param.next) strcat(string, ", ");
293 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
294 if(funcType && funcType.kind == functionType)
297 DocPrintType(funcType.returnType, string, false, fullName);
298 strcat(string, "(*");
299 if(printName || funcType.thisClass)
302 if(funcType.thisClass)
304 strcat(string, funcType.thisClass.string);
305 strcat(string, "::");
308 strcat(string, type.name);
310 strcat(string, ")(");
311 for(param = funcType.params.first; param; param = param.next)
313 DocPrintType(param, string, false, fullName);
314 if(param.next) strcat(string, ", ");
320 char baseType[1024], size[256];
321 Type arrayType = type;
325 while(arrayType.kind == TypeKind::arrayType)
328 if(arrayType.enumClass)
329 strcat(size, arrayType.enumClass.string);
330 else if(arrayType.arraySizeExp)
331 PrintExpression(arrayType.arraySizeExp, size);
332 //sprintf(string, "%s[%s]", baseType, size);
335 arrayType = arrayType.arrayType;
337 _PrintType(arrayType, baseType, printName, printFunction, fullName);
338 strcat(string, baseType);
339 strcat(string, size);
343 DocPrintType(type.arrayType, baseType, printName, fullName);
345 strcpy(size, type.enumClass.string);
346 else if(type.arraySizeExp)
347 PrintExpression(type.arraySizeExp, size);
348 //sprintf(string, "%s[%s]", baseType, size);
349 strcat(string, baseType);
351 strcat(string, size);
359 strcat(string, "...");
362 _PrintType(type.method.dataType, string, false, printFunction, fullName);
365 strcat(string, "subclass(");
366 strcat(string, type._class ? type._class.string : "int");
372 if(type.name && printName && type.kind != functionType && (type.kind != pointerType || type.type.kind != functionType))
375 strcat(string, type.name);
380 void DocPrintType(Type type, char * string, bool printName, bool fullName)
383 for(funcType = type; funcType && (funcType.kind == pointerType || funcType.kind == arrayType); funcType = funcType.type);
384 if(funcType && funcType.kind == functionType && type != funcType)
386 char typeString[1024];
389 DocPrintType(funcType.returnType, string, false, fullName);
391 _PrintType(type, string, printName, false, fullName);
395 strcat(string, type.name);
402 for(param = funcType.params.first; param; param = param.next)
404 DocPrintType(param, string, true, fullName);
405 if(param.next) strcat(string, ", ");
410 _PrintType(type, string, printName, true, fullName);
413 void AddComponents(Module module, bool isDll)
418 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
420 row = mainForm.browser.AddRow();
421 row.SetData(null, APIPageNameSpace { name = "ecereCOM", nameSpace = &module.application.systemNameSpace });
422 row.tag = (int64)null;
423 AddNameSpace(row, null, module.application.systemNameSpace, null, "", !isDll);
426 for(m = module.modules.first; m; m = m.next)
428 if(m.importMode == publicAccess || !isDll)
429 AddComponents(m.module, true);
432 // PUT MODULE DESCRIPTION HERE
433 if(module.name && strcmp(module.name, "ecereCOM"))
435 row = mainForm.browser.AddRow();
436 row.SetData(null, APIPageNameSpace { name = module.name, module = module, nameSpace = &module.publicNameSpace });
437 row.tag = (int64)module;
438 AddNameSpace(row, module, module.publicNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
440 AddNameSpace(row, module, module.privateNameSpace, null /*module.application.systemNameSpace*/, "", !isDll);
452 char * OnGetString(char * tempString, void * fieldData, bool * needClass)
457 virtual void Generate(File f)
462 virtual Module GetModule()
464 return page ? page.GetModule() : null;
467 virtual NameSpace * GetNameSpace()
469 return page ? page.GetNameSpace() : null;
473 enum DocumentationType
481 enum DocumentationItem
497 static void FigureFileName(char * fileName, Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
499 NameSpace * nameSpace, * ns;
501 Method method = null;
502 GlobalFunction function = null;
503 char nsName[1024], temp[1024];
509 case nameSpaceDoc: nameSpace = object; break;
510 case classDoc: cl = (Class)object; nameSpace = cl.nameSpace; break;
511 case functionDoc: function = object; nameSpace = function.nameSpace; break;
512 case methodDoc: method = object; cl = method._class; nameSpace = cl.nameSpace; break;
517 while(ns && ns->name)
519 strcpy(temp, "namespaces/");
520 strcat(temp, ns->name);
522 strcat(temp, nsName);
523 strcpy(nsName, temp);
526 sprintf(docFile, "%s.eCdoc", (!module || !module.name || !strcmp(nsName, "namespaces/ecere/namespaces/com")) ? "ecereCOM" : module.name);
527 if(strchr(docFile, DIR_SEP))
529 GetLastDirectory(docFile, temp);
530 strcpy(docFile, temp);
533 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.
534 strcat(fileName, nsName);
538 strcat(fileName, "classes/");
539 strcat(fileName, cl.name);
540 strcat(fileName, "/");
545 strcat(fileName, "methods/");
546 strcat(fileName, method.name);
547 strcat(fileName, "/");
551 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
552 if(name) name += 2; else name = function.name;
553 strcat(fileName, "functions/");
554 strcat(fileName, name);
555 strcat(fileName, "/");
560 case description: strcat(fileName, "description"); break;
561 case usage: strcat(fileName, "usage"); break;
562 case remarks: strcat(fileName, "remarks"); break;
563 case example: strcat(fileName, "example"); break;
564 case seeAlso: strcat(fileName, "seeAlso"); break;
565 case returnValue: strcat(fileName, "returnValue"); break;
566 case enumerationValue:
567 strcat(fileName, "enumeration values/");
568 strcat(fileName, ((NamedLink)data).name);
571 strcat(fileName, "definitions/");
572 strcat(fileName, ((Definition)data).name);
576 char * name = RSearchString(((Property)data).name, "::", strlen(((Property)data).name), true, false);
577 if(name) name += 2; else name = ((Property)data).name;
578 strcat(fileName, "conversions/");
579 strcat(fileName, name);
582 case memberDescription:
583 strcat(fileName, "data members/");
584 strcat(fileName, ((DataMember)data).name);
586 case propertyDescription:
587 strcat(fileName, "properties/");
588 strcat(fileName, ((Property)data).name);
595 strcat(fileName, "parameters/");
596 for(prev = data, count = 0; prev; prev = prev.prev, count++);
597 sprintf(name, "%s.%d", ((Type)data).name, count);
598 strcat(fileName, name);
604 static char * ReadDoc(Module module, DocumentationType type, void * object, DocumentationItem item, void * data)
606 char fileName[MAX_LOCATION];
607 String contents = null;
610 FigureFileName(fileName, module, type, object, item, data);
611 file = FileOpen(fileName, read);
615 if((len = file.GetSize()))
617 contents = new char[len+1];
618 file.Read(contents, 1, len);
619 contents[len] = '\0';
626 for(c = 0; contents[c]; c++)
627 if(!isspace(contents[c])) break;
631 if(editing && !contents && !readOnly)
632 contents = CopyString($"[Add Text]");
636 class APIPageNameSpace : APIPage
638 NameSpace * nameSpace;
646 NameSpace * GetNameSpace()
651 void Generate(File f)
654 char nsName[1024], temp[1024];
661 while(ns && ns->name)
663 strcpy(temp, ns->name);
664 if(nsName[0]) strcat(temp, "::");
665 strcat(temp, nsName);
666 strcpy(nsName, temp);
669 // Generate Class Page
670 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
673 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", nsName );
674 tag = (int64)nameSpace;
675 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);
679 tag = (int64)(!module || !module.name || !strcmp(nsName, "ecere::com") ? null : module);
680 f.Printf($"<FONT FACE=\"Arial\" SIZE=\"6\">Module %s</FONT><br>\n", (!module || !module.name || !strcmp(nsName, "ecere::com")) ? "ecereCOM" : module.name);
684 ns = nameSpace->parent;
685 while(ns && ns->name)
687 strcpy(temp, ns->name);
688 if(nsName[0]) strcat(temp, "::");
689 strcat(temp, nsName);
690 strcpy(nsName, temp);
694 f.Printf($"Parent namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", nameSpace->parent, nsName);
698 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, description, null);
701 f.Printf($"<H3>Description</H3><br><br>\n");
704 char fileName[MAX_LOCATION];
705 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, description, null);
706 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
708 f.Printf("</a><br><br>");
711 f.Printf("%s<br><br>", desc);
716 if(nameSpace->nameSpaces.first)
719 for(ns = (NameSpace *)nameSpace->nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
721 char * desc = ReadDoc(module, nameSpaceDoc, ns, description, null);
724 f.Printf($"<H3>Sub Namespaces</H3><br><br>\n");
725 f.Printf("<TABLE>\n");
729 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);
734 char fileName[MAX_LOCATION];
735 FigureFileName(fileName, module, nameSpaceDoc, ns, description, null);
736 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
738 f.Printf("</a></TD>");
741 f.Printf("<TD valign=top height=22> %s</TD>", desc);
744 f.Printf("</TR><br>\n");
747 f.Printf("</TABLE><br>\n");
750 if(nameSpace->classes.first)
753 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
755 Class cl = link.data;
756 if(!cl.templateClass)
758 char * desc = ReadDoc(module, classDoc, cl, description, null);
762 f.Printf($"<a name=Classes></a><H3>Classes</H3><br><br>\n");
763 f.Printf("<TABLE>\n");
769 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);
774 char fileName[MAX_LOCATION];
775 FigureFileName(fileName, module, classDoc, cl, description, null);
776 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
778 f.Printf("</a></TD>");
781 f.Printf("<TD valign=top height=22>%s</TD>", desc);
788 f.Printf("</TABLE><br>\n");
791 if(nameSpace->functions.first)
794 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
796 GlobalFunction function = link.data;
797 char * desc = ReadDoc(module, functionDoc, function, description, null);
798 char * name = RSearchString(function.name, "::", strlen(function.name), true, false);
799 if(name) name += 2; else name = function.name;
802 f.Printf($"<a name=Functions></a><H3>Functions</H3><br><br>\n");
803 f.Printf("<TABLE>\n");
807 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);
812 char fileName[MAX_LOCATION];
813 FigureFileName(fileName, module, functionDoc, function, description, null);
814 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
816 f.Printf("</a></TD>");
819 f.Printf("<TD valign=top height=22> %s</TD>", desc);
822 f.Printf("</TR><br>\n");
825 f.Printf("</TABLE><br>\n");
828 if(nameSpace->defines.first)
831 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
833 DefinedExpression def = link.data;
834 char * desc = ReadDoc(module, nameSpaceDoc, nameSpace, definition, def);
837 f.Printf($"<a name=Definitions></a><H3>Definitions</H3><br><br>\n");
838 f.Printf("<TABLE>\n");
842 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);
843 f.Printf("<TD valign=top height=22>%s</TD>", def.value);
848 char fileName[MAX_LOCATION];
849 FigureFileName(fileName, module, nameSpaceDoc, nameSpace, definition, def);
850 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
852 f.Printf("</a></TD>");
855 f.Printf("<TD valign=top height=22> %s</TD>", desc);
858 f.Printf("</TR><br>\n");
861 f.Printf("</TABLE><br>\n");
864 f.Printf("</FONT></BODY></HTML>\n");
868 class APIPageClass : APIPage
877 NameSpace * GetNameSpace()
882 void Generate(File f)
888 char nsName[1024], temp[1024];
889 NameSpace * ns = cl.nameSpace;
890 Module module = cl.module;
893 while(ns && ns->name)
895 strcpy(temp, ns->name);
896 if(nsName[0]) strcat(temp, "::");
897 strcat(temp, nsName);
898 strcpy(nsName, temp);
901 // Generate Class Page
902 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
903 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
905 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);
907 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
910 char * classType = null;
914 classType = $"Bit Collection";
917 classType = $"Enumeration";
920 classType = $"Structure";
923 classType = $"Class";
926 classType = $"Class (No header)";
932 classType = $"Basic Data Type";
935 f.Printf($"Type: %s<br>\n", classType);
938 if(cl.type != systemClass && cl.base)
940 f.Printf($"Base Class: ");
941 if(!strcmp(cl.base.name, "struct") || !strcmp(cl.base.name, "class"))
943 f.Printf(cl.type == bitClass ? cl.dataTypeString : $"None");
945 else if(cl.type == enumClass && !strcmp(cl.base.name, "enum"))
946 f.Printf("%s", cl.dataTypeString);
948 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", cl.base.templateClass ? cl.base.templateClass : cl.base, cl.base.name);
953 char * desc = ReadDoc(module, classDoc, cl, description, null);
956 f.Printf($"<br><H3>Description</H3><br><br>\n");
959 char fileName[MAX_LOCATION];
960 FigureFileName(fileName, module, classDoc, cl, description, null);
961 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
963 f.Printf("</a><br><br>");
966 f.Printf("%s<br><br>", desc);
971 if(cl.type == enumClass)
973 EnumClassData enumeration = (EnumClassData)cl.data;
974 if(enumeration.values.first)
978 f.Printf($"<a name=EnumerationValues></a><H3>Enumeration Values</H3><br><br>\n");
979 f.Printf("<TABLE>\n");
981 for(item = enumeration.values.first; item; item = item.next)
983 char * desc = ReadDoc(module, classDoc, cl, enumerationValue, item);
984 bool needClass = true;
987 char tempString[1024];
989 while(base.type == enumClass) base = base.base;
991 if(base.type == systemClass ||
992 (base.type == bitClass && base.membersAndProperties.first && !strcmp(cl.fullName, ((DataMember)base.membersAndProperties.first).dataTypeString)))
995 base.dataType = ProcessTypeString(base.dataTypeString, false);
997 if(base.dataType.kind != classType)
1002 PrintType(base.dataType, string, false, true);
1003 classSym = FindClass(string);
1004 dataClass = classSym ? classSym.registered : null;
1007 dataClass = base.dataType._class ? base.dataType._class.registered : null;
1013 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);
1014 if(dataClass.type == systemClass)
1017 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)dataClass._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1020 s = ((char *(*)(void *, void *, char *, void *, bool *))(void *)eSystem_FindClass(componentsApp, "class")._vTbl[__ecereVMethodID_class_OnGetString])(dataClass, &item.data, tempString, null, &needClass);
1022 f.Printf("<TD valign=top height=22 nowrap=1>%s { %s }</TD>", dataClass.name, s);
1024 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", s);
1029 char fileName[MAX_LOCATION];
1030 FigureFileName(fileName, module, classDoc, cl, enumerationValue, item);
1031 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1033 f.Printf("</a></TD>");
1036 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1041 f.Printf("</TABLE><BR>\n");
1045 if(cl.conversions.first)
1047 f.Printf($"<a name=Conversions></a><H3>Conversions</H3><br><br>\n");
1048 f.Printf("<TABLE>\n");
1049 for(prop = cl.conversions.first; prop; prop = prop.next)
1051 if((prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate)) && prop.name)
1053 char * desc = ReadDoc(module, classDoc, cl, conversion, prop);
1056 Type type = ProcessTypeString(prop.name, false);
1057 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
1058 if(name) name += 2; else name = prop.name;
1063 DocPrintType(type, string, true, false);
1065 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a><img valign=center src=\"%s\"> %s</TD>", prop, iconNames[typeDataType], string);
1070 char fileName[MAX_LOCATION];
1071 FigureFileName(fileName, module, classDoc, cl, conversion, prop);
1072 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1074 f.Printf("</a></TD>");
1077 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1081 f.Printf("</TR>\n");
1086 f.Printf("</TABLE><br>\n");
1089 if(cl.membersAndProperties.first)
1092 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
1094 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
1098 f.Printf($"<a name=Members></a><H3>Properties and Members</H3><br><br>\n");
1099 f.Printf("<TABLE>\n");
1105 char * desc = ReadDoc(module, classDoc, cl, propertyDescription, prop);
1107 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
1111 DocPrintType(prop.dataType, string, true, false);
1113 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);
1114 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", string);
1119 char fileName[MAX_LOCATION];
1120 FigureFileName(fileName, module, classDoc, cl, propertyDescription, prop);
1121 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1123 f.Printf("</a></TD>");
1126 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1129 f.Printf("</TR>\n");
1133 AddDataMemberToPage(f, (DataMember)prop, 0, showPrivate);
1138 f.Printf("</TABLE><br>\n");
1141 if(cl.methods.first)
1145 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1147 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type == virtualMethod)
1149 char * desc = ReadDoc(module, methodDoc, method, description, null);
1152 f.Printf($"<a name=VirtualMethods></a><H3>Virtual Methods</H3><br><br>\n");
1153 f.Printf("<TABLE>\n");
1156 if(!method.dataType)
1157 ProcessMethodType(method);
1160 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);
1165 char fileName[MAX_LOCATION];
1166 FigureFileName(fileName, module, methodDoc, method, description, null);
1167 f.Printf("<TD valign=top height=22> <a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1169 f.Printf("</a></TD>");
1172 f.Printf("<TD valign=top height=22> %s</TD>", desc);
1175 f.Printf("</TR><br>\n");
1179 f.Printf("</TABLE><br>\n");
1181 // Non-Virtual Methods
1183 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
1185 if((method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate)) && method.type != virtualMethod)
1187 char * desc = ReadDoc(module, methodDoc, method, description, null);
1190 f.Printf($"<a name=Methods></a><H3>Non-Virtual Methods</H3><br><br>\n");
1191 f.Printf("<TABLE>\n");
1195 if(!method.dataType)
1196 ProcessMethodType(method);
1199 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);
1204 char fileName[MAX_LOCATION];
1205 FigureFileName(fileName, module, methodDoc, method, description, null);
1206 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1208 f.Printf("</a></TD>");
1211 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1215 f.Printf("</TR><br>\n");
1219 f.Printf("</TABLE><br>\n");
1222 char * usageDoc = ReadDoc(module, classDoc, cl, usage, null);
1225 f.Printf($"<H3>Usage</H3><br>\n");
1228 char fileName[MAX_LOCATION];
1229 FigureFileName(fileName, module, classDoc, cl, usage, null);
1230 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1235 f.Printf("<br>%s\n", usageDoc);
1236 f.Printf("<br><br>\n");
1241 char * exampleDoc = ReadDoc(module, classDoc, cl, example, null);
1244 f.Printf($"<H3>Example</H3><br>\n");
1245 f.Printf($"<FONT face=\"Courier New\">\n");
1246 f.Printf("<br><TABLE>\n");
1249 char fileName[MAX_LOCATION];
1250 FigureFileName(fileName, module, classDoc, cl, example, null);
1251 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1253 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1256 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1258 f.Printf("</TABLE></FONT>\n");
1264 char * remarksDoc = ReadDoc(module, classDoc, cl, remarks, null);
1268 f.Printf($"<H3>Remarks</H3><br>\n");
1271 char fileName[MAX_LOCATION];
1272 FigureFileName(fileName, module, classDoc, cl, remarks, null);
1273 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1278 f.Printf("<br>%s\n", remarksDoc);
1279 f.Printf("<br><br>\n");
1284 if(cl.type != systemClass)
1288 for(c = cl.derivatives.first; c; c = c.next)
1290 Class deriv = c.data;
1291 // TO VERIFY: Does this properly check public status?
1292 if(eSystem_FindClass(componentsApp, deriv.fullName))
1296 f.Printf($"<H3>Derived Classes</H3><br>\n");
1302 f.Printf("<a href=\"api://%p\" style=\"text-decoration: none;\">%s</a>", deriv, deriv.name);
1306 f.Printf("<br><br>\n");
1309 char * seeAlsoDoc = ReadDoc(module, classDoc, cl, seeAlso, null);
1312 f.Printf($"<H3>See Also</H3><br>\n");
1315 char fileName[MAX_LOCATION];
1316 FigureFileName(fileName, module, classDoc, cl, seeAlso, null);
1317 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1322 f.Printf("<br>%s\n", seeAlsoDoc);
1323 f.Printf("<br><br>\n");
1327 f.Printf("</FONT></BODY></HTML>\n");
1331 class APIPageMethod : APIPage
1337 return method._class.module;
1340 NameSpace * GetNameSpace()
1342 return method._class.nameSpace;
1345 void Generate(File f)
1347 Class cl = method._class;
1349 Module module = cl.module;
1351 char nsName[1024], temp[1024];
1352 NameSpace * ns = cl.nameSpace;
1355 while(ns && ns->name)
1357 strcpy(temp, ns->name);
1358 if(nsName[0]) strcat(temp, "::");
1359 strcat(temp, nsName);
1360 strcpy(nsName, temp);
1364 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1365 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1367 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);
1369 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl.nameSpace, nsName);
1370 f.Printf("Class: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", cl, cl.name);
1371 if(method.dataType.staticMethod)
1373 f.Printf($"this pointer class: None<br>\n");
1375 else if(method.dataType.thisClass && method.dataType.thisClass.registered && (method.dataType.thisClass.registered != method._class || method.type == virtualMethod))
1377 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);
1380 // Generate Method Page
1382 if(!method.dataType.name)
1383 method.dataType.name = CopyString(method.name);
1384 DocPrintType(method.dataType, string, true, false);
1385 f.Printf("<br>%s", string);
1388 char * desc = ReadDoc(module, methodDoc, method, description, null);
1391 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1394 char fileName[MAX_LOCATION];
1395 FigureFileName(fileName, module, methodDoc, method, description, null);
1396 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1401 f.Printf("%s", desc);
1406 f.Printf("<br><br>\n");
1407 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1409 f.Printf($"<H3>Parameters</H3><br><br>\n");
1411 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1412 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1414 f.Printf("<TABLE valign=center>\n");
1417 for(param = method.dataType.params.first; param; param = param.next)
1419 // ADD DESCRIPTION HERE
1420 if(param.kind != voidType)
1422 char * desc = ReadDoc(module, methodDoc, method, parameter, param);
1425 DocPrintType(param, string, false, false);
1427 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1428 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1433 char fileName[MAX_LOCATION];
1434 FigureFileName(fileName, module, methodDoc, method, parameter, param);
1435 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1437 f.Printf("</a></TD>\n");
1440 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1444 f.Printf("</TR>\n");
1447 if(method.dataType.returnType && method.dataType.returnType.kind != voidType)
1449 char * desc = ReadDoc(module, methodDoc, method, returnValue, null);
1450 if(method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType)
1452 f.Printf("<TR><TD> </TD></TR>");
1455 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1457 DocPrintType(method.dataType.returnType, string, false, false);
1458 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1463 char fileName[MAX_LOCATION];
1464 FigureFileName(fileName, module, methodDoc, method, returnValue, null);
1465 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1467 f.Printf("</a> </TD>\n");
1470 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1473 f.Printf("</TR>\n");
1474 f.Printf("</TABLE>\n");
1476 if((method.dataType.returnType && method.dataType.returnType.kind != voidType) ||
1477 (method.dataType.params.first && ((Type)method.dataType.params.first).kind != voidType))
1479 f.Printf("</TABLE><br>\n");
1482 char * usageDoc = ReadDoc(module, methodDoc, method, usage, null);
1485 f.Printf($"<H3>Usage</H3><br>\n");
1488 char fileName[MAX_LOCATION];
1489 FigureFileName(fileName, module, methodDoc, method, usage, null);
1490 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1495 f.Printf("<br>%s\n", usageDoc);
1496 f.Printf("<br><br>\n");
1501 char * exampleDoc = ReadDoc(module, methodDoc, method, example, null);
1504 f.Printf($"<H3>Example</H3><br>\n");
1505 f.Printf($"<FONT face=\"Courier New\">\n");
1506 f.Printf("<br><TABLE>\n");
1509 char fileName[MAX_LOCATION];
1510 FigureFileName(fileName, module, methodDoc, method, example, null);
1511 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1513 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1516 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1517 f.Printf("</TABLE></FONT>\n");
1523 char * remarksDoc = ReadDoc(module, methodDoc, method, remarks, null);
1526 f.Printf($"<H3>Remarks</H3><br>\n");
1529 char fileName[MAX_LOCATION];
1530 FigureFileName(fileName, module, methodDoc, method, remarks, null);
1531 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1536 f.Printf("<br>%s\n", method, remarksDoc);
1537 f.Printf("<br><br>\n");
1542 char * seeAlsoDoc = ReadDoc(module, methodDoc, method, seeAlso, null);
1545 f.Printf($"<H3>See Also</H3><br>\n");
1548 char fileName[MAX_LOCATION];
1549 FigureFileName(fileName, module, methodDoc, method, seeAlso, null);
1550 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1555 f.Printf("<br>%s\n", method, seeAlsoDoc);
1557 f.Printf("<br><br>\n");
1561 f.Printf("</FONT></BODY></HTML>\n");
1565 class APIPageFunction : APIPage
1567 GlobalFunction function;
1571 return function.module;
1574 NameSpace * GetNameSpace()
1576 return function.nameSpace;
1579 void Generate(File f)
1582 Module module = function.module;
1584 char nsName[1024], temp[1024];
1585 NameSpace * ns = function.nameSpace;
1588 while(ns && ns->name)
1590 strcpy(temp, ns->name);
1591 if(nsName[0]) strcat(temp, "::");
1592 strcat(temp, nsName);
1593 strcpy(nsName, temp);
1597 f.Printf($"<HTML><HEAD><TITLE>API Reference</TITLE></HEAD>\n<BODY><FONT SIZE=\"3\">\n");
1598 f.Printf("<FONT FACE=\"Arial\" SIZE=\"6\">%s</FONT><br><br>\n", name);
1600 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);
1603 f.Printf($"Namespace: <a href=\"api://%p\" style=\"text-decoration: none;\">%s</a><br>\n", function.nameSpace, nsName);
1605 if(!function.dataType)
1606 function.dataType = ProcessTypeString(function.dataTypeString, false);
1608 if(function.dataType.thisClass && function.dataType.thisClass.registered)
1610 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);
1613 // Generate Method Page
1615 if(!function.dataType.name)
1616 function.dataType.name = CopyString(function.name);
1617 DocPrintType(function.dataType, string, true, false);
1618 f.Printf("<br>%s", string);
1621 char * desc = ReadDoc(module, functionDoc, function, description, null);
1624 f.Printf($"<br><br><H3>Description</H3><br><br>\n");
1627 char fileName[MAX_LOCATION];
1628 FigureFileName(fileName, module, functionDoc, function, description, null);
1629 f.Printf("<a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1634 f.Printf("%s", desc);
1638 f.Printf("<br><br>\n");
1639 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1641 f.Printf($"<H3>Parameters</H3><br><br>\n");
1643 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1644 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1646 f.Printf("<TABLE valign=center>\n");
1649 for(param = function.dataType.params.first; param; param = param.next)
1651 // ADD DESCRIPTION HERE
1652 if(param.kind != voidType)
1654 char * desc = ReadDoc(module, functionDoc, function, parameter, param);
1657 DocPrintType(param, string, false, false);
1659 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", param.name ? param.name : "");
1660 f.Printf("<TD valign=top height=22 nowrap=1>%s </TD>\n", string);
1665 char fileName[MAX_LOCATION];
1666 FigureFileName(fileName, module, functionDoc, function, parameter, param);
1667 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1670 f.Printf("</a> </TD>\n");
1673 f.Printf("<TD valign=top height=22>%s </TD>\n", desc);
1676 f.Printf("</TR>\n");
1679 if(function.dataType.returnType && function.dataType.returnType.kind != voidType)
1681 char * desc = ReadDoc(module, functionDoc, function, returnValue, null);
1682 if(function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType)
1684 f.Printf("<TR><TD> </TD></TR>");
1687 f.Printf($"<TD valign=top height=22 nowrap=1><B>Return Value</B></TD>\n");
1689 DocPrintType(function.dataType.returnType, string, false, false);
1690 f.Printf("<TD valign=top height=22>%s </TD>\n", string);
1695 char fileName[MAX_LOCATION];
1696 FigureFileName(fileName, module, functionDoc, function, returnValue, null);
1697 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1699 f.Printf("</a> </TD>\n");
1702 f.Printf("<TD valign=top height=22>%s </TD>\n", function, desc);
1705 f.Printf("</TR>\n");
1706 f.Printf("</TABLE>\n");
1708 if((function.dataType.returnType && function.dataType.returnType.kind != voidType) ||
1709 (function.dataType.params.first && ((Type)function.dataType.params.first).kind != voidType))
1711 f.Printf("</TABLE><br>\n");
1714 char * usageDoc = ReadDoc(module, functionDoc, function, usage, null);
1717 f.Printf($"<H3>Usage</H3><br>\n");
1720 char fileName[MAX_LOCATION];
1721 FigureFileName(fileName, module, functionDoc, function, usage, null);
1722 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1727 f.Printf("<br>%s\n", usageDoc);
1728 f.Printf("<br><br>\n");
1733 char * exampleDoc = ReadDoc(module, functionDoc, function, example, null);
1736 f.Printf($"<H3>Example</H3><br>\n");
1737 f.Printf($"<FONT face=\"Courier New\">\n");
1738 f.Printf("<br><TABLE>\n");
1741 char fileName[MAX_LOCATION];
1742 FigureFileName(fileName, module, functionDoc, function, example, null);
1743 f.Printf("<TR><TD><CODE><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1745 f.Printf("</a></CODE></TD></TR>\n"); // bgcolor=#CFC9C0
1748 f.Printf("<TR><TD><CODE>%s</CODE></TD></TR>\n", exampleDoc); // bgcolor=#CFC9C0
1749 f.Printf("</TABLE></FONT>\n");
1755 char * remarksDoc = ReadDoc(module, functionDoc, function, remarks, null);
1758 f.Printf($"<H3>Remarks</H3><br>\n");
1761 char fileName[MAX_LOCATION];
1762 FigureFileName(fileName, module, functionDoc, function, remarks, null);
1763 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1768 f.Printf("<br>%s\n", remarksDoc);
1769 f.Printf("<br><br>\n");
1774 char * seeAlsoDoc = ReadDoc(module, functionDoc, function, seeAlso, null);
1777 f.Printf($"<H3>See Also</H3><br>\n");
1780 char fileName[MAX_LOCATION];
1781 FigureFileName(fileName, module, functionDoc, function, seeAlso, null);
1782 f.Printf("<br><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1787 f.Printf("<br>%s\n", seeAlsoDoc);
1788 f.Printf("<br><br>\n");
1792 f.Printf("</FONT></BODY></HTML>\n");
1796 static void AddNameSpace(DataRow parentRow, Module module, NameSpace mainNameSpace, NameSpace comNameSpace, char * parentName, bool showPrivate)
1800 NameSpace * nameSpace = mainNameSpace;
1802 DataRow classesRow = null;
1803 DataRow functionsRow = null, definesRow = null;
1806 char fileName[MAX_LOCATION];
1808 strcpy(nsName, parentName ? parentName : "");
1812 strcat(nsName, "::");
1813 strcat(nsName, nameSpace->name);
1818 row = parentRow.AddRow();
1819 row.SetData(null, (page = APIPageNameSpace { nameSpace->name, module = module, nameSpace = nameSpace, showPrivate = showPrivate }));
1820 row.tag = (int64)nameSpace;
1821 row.icon = mainForm.icons[typeNameSpace];
1825 // "Global NameSpace"
1827 page = parentRow.GetData(null);
1833 for(ns = (NameSpace *)mainNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1835 NameSpace * comNS = (comNameSpace != null) ? (NameSpace *)comNameSpace.nameSpaces.FindString(ns->name) : null;
1836 AddNameSpace(row, module, ns, comNS, nsName, showPrivate);
1838 if(comNameSpace != null)
1840 for(ns = (NameSpace *)comNameSpace.nameSpaces.first; ns; ns = (NameSpace *)((BTNode)ns).next)
1842 if(!mainNameSpace.nameSpaces.FindString(ns->name))
1844 AddNameSpace(row, module, ns, null, nsName, showPrivate);
1849 if(mainNameSpace.classes.first || (comNameSpace && comNameSpace.classes.first))
1851 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1853 if(nameSpace->classes.first)
1857 for(link = (BTNamedLink)nameSpace->classes.first; link; link = (BTNamedLink)((BTNode)link).next)
1860 if(!cl.templateClass && (!module || cl.module == module || (!cl.module.name && !strcmp(module.name, "ecere"))))
1862 if(!classesRow) { classesRow = row.AddRow(); classesRow.SetData(null, APIPage { $"Classes", page = page }); classesRow.collapsed = true; classesRow.icon = mainForm.icons[typeClass]; classesRow.tag = 1; }
1863 AddClass(classesRow, module, cl, nsName, showPrivate);
1870 if(mainNameSpace.functions.first || (comNameSpace && comNameSpace.functions.first))
1872 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1874 if(nameSpace->functions.first)
1878 for(link = (BTNamedLink)nameSpace->functions.first; link; link = (BTNamedLink)((BTNode)link).next)
1881 if(!module || fn.module == module || (!fn.module.name && !strcmp(module.name, "ecere")))
1883 char * name = ( name = RSearchString(fn.name, "::", strlen(fn.name), false, false), name ? name + 2 : fn.name);
1885 if(!functionsRow) { functionsRow = row.AddRow(); functionsRow.SetData(null, APIPage { $"Functions", page = page }); functionsRow.collapsed = true; functionsRow.icon = mainForm.icons[typeMethod]; functionsRow.tag = 2; };
1886 fnRow = functionsRow.AddRow(); fnRow.SetData(null, APIPageFunction { name, function = fn }); fnRow.icon = mainForm.icons[typeMethod]; fnRow.tag = (int64)fn;
1893 if(mainNameSpace.defines.first || (comNameSpace && comNameSpace.defines.first))
1895 for(nameSpace = mainNameSpace ; nameSpace; nameSpace = (nameSpace == mainNameSpace) ? comNameSpace : null)
1897 if(nameSpace->defines.first)
1901 for(link = (BTNamedLink)nameSpace->defines.first; link; link = (BTNamedLink)((BTNode)link).next)
1904 //if(def.module == module)
1906 char * name = ( name = RSearchString(def.name, "::", strlen(def.name), false, false), name ? name + 2 : def.name);
1908 if(!definesRow) { definesRow = row.AddRow(); definesRow.SetData(null, APIPage { $"Definitions", page = page }); definesRow.collapsed = true; definesRow.icon = mainForm.icons[typeData]; definesRow.tag = 3; };
1909 defRow = definesRow.AddRow(); defRow.SetData(null, APIPage { name, page = page }); defRow.icon = mainForm.icons[typeData]; defRow.tag = (int64)def;
1917 static void AddDataMemberToPage(File f, DataMember member, int indent, bool showPrivate)
1921 if(!member.dataType)
1922 member.dataType = ProcessTypeString(member.dataTypeString, false);
1926 DocPrintType(member.dataType, string, true, false);
1928 f.Printf("<TD valign=top height=22 nowrap=1><a name=%p></a>", member);
1929 for(c = 0; c<indent; c++)
1930 f.Printf(" ");
1931 f.Printf("<img valign=center src=\"%s\"> %s</TD>", iconNames[typeData], member.name ? member.name : ((member.type == structMember) ? "(struct)" : "(union)"));
1932 f.Printf("<TD valign=top height=22 nowrap=1>%s</TD>", (member.type == normalMember) ? string : "");
1933 if(member.type == normalMember)
1935 char * desc = ReadDoc(member._class.module, classDoc, member._class, memberDescription, member);
1940 char fileName[MAX_LOCATION];
1941 FigureFileName(fileName, member._class.module, classDoc, member._class, memberDescription, member);
1942 f.Printf("<TD valign=top height=22><a style=\"text-decoration:none;\" href=\"edit://%s\">", fileName);
1944 f.Printf("</a></TD>");
1947 f.Printf("<TD valign=top height=22>%s</TD>", desc);
1952 f.Printf("<TD valign=top height=22></TD>");
1954 if(member.type != normalMember)
1956 DataMember subMember;
1957 for(subMember = member.members.first; subMember; subMember = subMember.next)
1959 if((subMember.memberAccess == publicAccess || (subMember.memberAccess == privateAccess && showPrivate)))
1961 AddDataMemberToPage(f, subMember, indent + 1, showPrivate);
1965 f.Printf("</TR><br>\n");
1968 static void AddDataMember(DataRow parentRow, APIPage page, DataMember member)
1971 if(member.type == normalMember)
1973 row = parentRow.AddRow(); row.SetData(null, APIPage { member.name, page = page }); row.icon = mainForm.icons[typeData];
1974 row.tag = (int64)member;
1979 row = parentRow.AddRow(); row.SetData(null, APIPage { (member.type == unionMember) ? "(union)" : "(struct)", page });
1980 row.icon = mainForm.icons[typeData];
1981 row.tag = (int64)member;
1983 for(m = member.members.first; m; m = m.next)
1985 if(m.memberAccess == publicAccess || (m.memberAccess == privateAccess && page.showPrivate))
1986 AddDataMember(row, page, m);
1991 static void AddClass(DataRow parentRow, Module module, Class cl, char * nsName, bool showPrivate)
1993 char fileName[MAX_LOCATION];
2000 DataRow methodsRow = null, virtualsRow = null, eventsRow = null;
2001 DataRow propertiesRow = null, membersRow = null, conversionsRow = null, enumRow = null;
2004 row = parentRow.AddRow();
2005 row.SetData(null, (page = APIPageClass { cl.name, cl = cl, showPrivate = showPrivate }));
2006 row.tag = (int64)cl;
2007 row.collapsed = true;
2008 row.icon = (cl.type == enumClass || cl.type == unitClass || cl.type == systemClass) ? mainForm.icons[typeDataType] : mainForm.icons[typeClass];
2011 if(cl.methods.first)
2013 for(method = (Method)cl.methods.first; method; method = (Method)((BTNode)method).next)
2015 if(method.memberAccess == publicAccess || (method.memberAccess == privateAccess && showPrivate))
2018 if(!method.dataType)
2019 ProcessMethodType(method);
2020 if(method.type == virtualMethod)
2022 if(method.dataType.thisClass)
2024 if(!eventsRow) { eventsRow = row.AddRow(); eventsRow.SetData(null, APIPage { $"Events", page = page }); eventsRow.collapsed = true; eventsRow.icon = mainForm.icons[typeEvent]; eventsRow.tag = 4; }
2025 mRow = eventsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeEvent];
2026 mRow.tag = (int64)method;
2030 if(!virtualsRow) { virtualsRow = row.AddRow(); virtualsRow.SetData(null, APIPage { $"Virtual Methods", page = page }); virtualsRow.collapsed = true; virtualsRow.icon = mainForm.icons[typeMethod]; virtualsRow.tag = 4; }
2031 mRow = virtualsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2032 mRow.tag = (int64)method;
2037 if(!methodsRow) { methodsRow = row.AddRow(); methodsRow.SetData(null, APIPage { $"Methods", page = page }); methodsRow.collapsed = true; methodsRow.icon = mainForm.icons[typeMethod]; methodsRow.tag = 5; }
2038 mRow = methodsRow.AddRow(); mRow.SetData(null, APIPageMethod { method.name, method = method }); mRow.icon = mainForm.icons[typeMethod];
2039 mRow.tag = (int64)method;
2045 if(cl.membersAndProperties.first)
2047 for(prop = (Property)cl.membersAndProperties.first; prop; prop = prop.next)
2049 if(prop.memberAccess == publicAccess || (prop.memberAccess == privateAccess && showPrivate))
2052 prop.dataType = ProcessTypeString(prop.dataTypeString, false);
2056 if(!propertiesRow) { propertiesRow = row.AddRow(); propertiesRow.SetData(null, APIPage { $"Properties", page = page }); propertiesRow.collapsed = true; propertiesRow.icon = mainForm.icons[typeProperty]; propertiesRow.tag = 6; }
2057 mRow = propertiesRow.AddRow(); mRow.SetData(null, APIPage { prop.name, page }); mRow.icon = mainForm.icons[typeProperty];
2058 mRow.tag = (int64)prop;
2062 if(!membersRow) { membersRow = row.AddRow(); membersRow.SetData(null, APIPage { $"Data Members", page = page }); membersRow.collapsed = true; membersRow.icon = mainForm.icons[typeData]; membersRow.tag = 6; }
2063 AddDataMember(membersRow, page, (DataMember)prop);
2069 if(cl.conversions.first)
2071 for(prop = cl.conversions.first; prop; prop = prop.next)
2075 if(!conversionsRow) { conversionsRow = row.AddRow(); conversionsRow.SetData(null, APIPage { $"Conversions", page = page }); conversionsRow.collapsed = true; conversionsRow.icon = mainForm.icons[typeDataType]; conversionsRow.tag = 7; }
2076 name = RSearchString(prop.name, "::", strlen(prop.name), true, false);
2077 if(name) name += 2; else name = prop.name;
2078 mRow = conversionsRow.AddRow(); mRow.SetData(null, APIPage { name, page = page }); mRow.icon = mainForm.icons[typeDataType];
2079 mRow.tag = (int64)prop;
2082 if(cl.type == enumClass)
2084 EnumClassData enumeration = (EnumClassData)cl.data;
2086 for(item = enumeration.values.first; item; item = item.next)
2089 if(!enumRow) { enumRow = row.AddRow(); enumRow.SetData(null, APIPage { $"Enumeration Values", page = page }); enumRow.collapsed = true; enumRow.icon = mainForm.icons[typeEnumValue]; enumRow.tag = 8; }
2090 mRow = enumRow.AddRow(); mRow.SetData(null, APIPage { item.name, page = page }); mRow.icon = mainForm.icons[typeEnumValue];
2091 mRow.tag = (int64)item;
2096 class AddressBar : Window
2098 background = activeBorder;
2102 this, bevelOver = true, inactive = true, anchor = Anchor { left = 0, top = 0, bottom = 0 }, size = Size { 24 }, bitmap = { ":actions/docOpen.png" };
2104 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2106 MainForm mainForm = (MainForm)parent;
2107 FileDialog fileDialog = mainForm.fileDialog;
2108 if(fileDialog.Modal() == ok)
2109 mainForm.OpenModule(fileDialog.filePath);
2115 this, bevelOver = true, inactive = true, anchor = Anchor { left = 28, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altLeft, bitmap = { "<:ecere>actions/goPrevious.png" };
2118 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2120 ((MainForm)parent).Back();
2126 this, bevelOver = true, inactive = true, anchor = Anchor { left = 52, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = altRight, bitmap = { "<:ecere>actions/goNext.png" };
2129 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2131 ((MainForm)parent).Forward();
2137 this, bevelOver = true, inactive = true, anchor = Anchor { left = 80, top = 0, bottom = 0 }, size = Size { 24 }, hotKey = ctrlH, bitmap = { "<:ecere>actions/goHome.png" };
2139 bool NotifyClicked(Button button, int x, int y, Modifiers mods)
2141 ((MainForm)parent).Home();
2145 /* TODO: Search (#143/#441)
2146 When there's something in the search box, list matching sections, the exact match first,instead of the Hierarchy in the ListBox.
2147 Update this in the NotifyUpdate. Enter goes to the exact match.
2149 Label { this, anchor = Anchor { left = (124+12) }, labeledWindow = search };
2153 this, text = "Search:", anchor = Anchor { left = (16+48+124), right = 60, top = 0, bottom = 0 }, hotKey = altD;
2155 bool NotifyKeyDown(EditBox editBox, Key key, unichar ch)
2157 if(!disabled && (SmartKey)key == enter)
2158 ((MainForm)parent).Go(editBox.contents);
2162 void NotifyUpdate(EditBox editBox)
2164 String location = ((MainForm)parent).view.location;
2165 disabled = !strcmp(location ? location : "", editBox.contents);
2170 bool OnKeyHit(Key key, unichar ch)
2173 ((MainForm)parent).view.MakeActive();
2178 class MainForm : Window
2180 size = { 1000, 600 };
2182 borderStyle = sizable;
2185 icon = { ":documentorIcon.png" };
2186 text = $"API Documentation Browser";
2188 BitmapResource icons[CodeObjectType];
2193 for(c = 0; c < CodeObjectType::enumSize; c++)
2195 icons[c] = BitmapResource { iconNames[c], window = this, alphaBlend = true };
2197 browser.AddField(DataField { dataType = class(APIPage) });
2202 Menu fileMenu { menu, $"File", f };
2203 Array<FileFilter> fileFilters
2205 { $"eC Shared Library files (*.dll, *.so, *.dylib)", "dll, so, dylib" },
2206 { $"eC Symbol files (*.sym)", "sym" }
2209 FileDialog fileDialog
2211 filters = fileFilters.array, sizeFilters = fileFilters.count * sizeof(FileFilter)
2213 MenuItem fileOpenItem
2215 fileMenu, $"Open...", o, ctrlO;
2217 bool NotifySelect(MenuItem selection, Modifiers mods)
2219 if(fileDialog.Modal() == ok)
2221 OpenModule(fileDialog.filePath);
2226 MenuItem fileSettingsItem
2228 fileMenu, $"Settings...", s, ctrlS; // set the Settings item to the file menu with shortcut keys:s and ctrl+s
2230 bool NotifySelect(MenuItem selection, Modifiers mods)
2232 if(SettingsDialog { master = this }.Modal() == ok) // Open the settings dialog to allow the user to change the directory for the eCdoc files
2242 MenuDivider { fileMenu };
2243 MenuItem fileExit { fileMenu, $"Exit", x, altF4, NotifySelect = MenuFileExit };
2245 void OpenModule(char * filePath)
2247 char moduleName[MAX_LOCATION];
2248 char extension[MAX_EXTENSION];
2249 Module module = null;
2250 static char symbolsDir[MAX_LOCATION];
2254 FreeContext(globalContext);
2255 FreeExcludedSymbols(excludedSymbols);
2256 ::defines.Free(FreeModuleDefine);
2257 imports.Free(FreeModuleImport);
2259 FreeGlobalData(globalData);
2260 FreeTypeData(componentsApp);
2262 delete componentsApp;
2264 SetGlobalContext(globalContext);
2265 componentsApp = __ecere_COM_Initialize(false, 1, null);
2266 SetPrivateModule(componentsApp);
2268 StripLastDirectory(filePath, symbolsDir);
2269 SetSymbolsDir(symbolsDir);
2271 GetExtension(filePath, extension);
2273 mainForm.browser.Clear();
2275 ImportModule(filePath, normalImport, publicAccess, false);
2277 if(extension[0] && strcmpi(extension, "so") && strcmpi(extension, "dll") && strcmpi(extension, "dylib"))
2278 componentsApp.name = CopyString(filePath);
2280 for(module = componentsApp.allModules.first; module; module = module.next)
2282 if(module.name && (!strcmp(module.name, "ecere") || !strcmp(module.name, "ecereCOM")))
2286 eModule_LoadStrict(componentsApp, "ecereCOM", publicAccess /*privateAccess*/);
2287 AddComponents(componentsApp, false);
2289 GetLastDirectory(filePath, moduleName);
2290 // Extension, path and lib prefix get removed in Module::name
2293 StripExtension(moduleName);
2294 if((!strcmpi(extension, "so") || !strcmpi(extension, "dylib")) && strstr(moduleName, "lib") == moduleName)
2296 int len = strlen(moduleName) - 3;
2297 memmove(moduleName, moduleName + 3, len);
2298 moduleName[len] = 0;
2302 for(module = componentsApp.allModules.first; module; module = module.next)
2304 if(module.name && (!strcmp(module.name, moduleName)))
2307 if(!module) module = componentsApp;
2308 homeModule = module;
2309 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)module));
2311 SetSymbolsDir(null);
2314 AddressBar addressBar { this, borderStyle = bevel, anchor = Anchor { top = 0, left = 0, right = 0 }, size.h = 26, hotKey = altD };
2317 this, anchor = { left = 0, top = 26, bottom = 0 }, borderStyle = 0, background = aliceBlue;
2318 treeBranches = true; collapseControl = true; fullRowSelect = false; rootCollapseButton = true;
2321 bool NotifySelect(ListBox listBox, DataRow row, Modifiers mods)
2323 APIPage page = row.GetData(null);
2324 if(view.edit) view.OnLeftButtonDown(0,0,0);
2325 if(page && page.page) page = page.page;
2327 view.PositionCaret(true);
2328 if(page != view.page)
2330 Window activeChild = this.activeChild;
2332 // Back / Forward Support
2333 if(row && !dontRecordHistory)
2335 if(history.count > historyPos+1)
2336 history.count = historyPos+1;
2337 historyPos = history.count-1;
2338 addressBar.back.disabled = (historyPos == 0);
2339 addressBar.forward.disabled = (historyPos >= history.count-1);
2341 history.Add((Instance)(uint64)row.tag);
2342 historyPos = history.count-1;
2344 addressBar.back.disabled = (historyPos == 0);
2345 addressBar.forward.disabled = (historyPos >= history.count-1);
2351 activeChild.Activate();
2353 else if(!view.created)
2357 page = row.GetData(null);
2358 if(page && page.page)
2362 case 1: view.GoToAnchor("Classes"); break;
2363 case 2: view.GoToAnchor("Functions"); break;
2364 case 3: view.GoToAnchor("Definitions"); break;
2365 case 4: view.GoToAnchor("VirtualMethods"); break;
2366 case 5: view.GoToAnchor("Methods"); break;
2367 case 6: view.GoToAnchor("Members"); break;
2368 case 7: view.GoToAnchor("Conversions"); break;
2369 case 8: view.GoToAnchor("EnumerationValues"); break;
2373 sprintf(hex, "%p", row.tag);
2374 view.GoToAnchor(hex);
2380 view.SetScrollPosition(0, 0);
2388 this, anchor = { top = 26, bottom = 0, right = 0 };
2393 this, anchor.top = 26, leftPane = browser, rightPane = view, split = 300 /*scaleSplit = 0.3 */
2396 bool OnClose(bool parentClosing)
2399 view.OnLeftButtonDown(0,0,0);
2405 mainForm.OpenModule((((GuiApplication)__thisModule).argc > 1) ? ((GuiApplication)__thisModule).argv[1] : "ecere");
2406 //mainForm.OpenModule("ec");
2407 //mainForm.OpenModule("c:/games/chess/debug/chess.sym");
2408 //mainForm.OpenModule("c:/ide/Objects.IDE.Win32.Debug/ide.sym");
2410 int index = mainForm.browser.currentRow.index;
2411 int rowHeight = mainForm.browser.rowHeight;
2412 int height = mainForm.browser.clientSize.h;
2414 mainForm.browser.scroll = { 0, index * rowHeight - height / 2 };
2419 Array<Instance> history { };
2421 bool dontRecordHistory;
2426 if(historyPos < history.count-1)
2430 addressBar.back.disabled = (historyPos == 0);
2431 addressBar.forward.disabled = (historyPos >= history.count-1);
2432 sprintf(location, "api://%p", history[historyPos]);
2433 dontRecordHistory = true;
2434 view.OnOpen(location);
2435 dontRecordHistory = false;
2447 addressBar.back.disabled = (historyPos == 0);
2448 addressBar.forward.disabled = (historyPos >= history.count-1);
2449 sprintf(location, "api://%p", history[historyPos]);
2450 dontRecordHistory = true;
2451 view.OnOpen(location);
2452 dontRecordHistory = false;
2460 mainForm.browser.SelectRow(mainForm.browser.FindSubRow((int64)homeModule));
2464 class EditDialog : Window
2466 borderStyle = sizable;
2467 size = { 600, 400 };
2472 this, anchor = { left = 16, top = 16, right = 18, bottom = 61 }
2476 this, text = $"Save Changes", anchor = { horz = 184, vert = 160 }
2480 this, text = $"Cancel", anchor = { horz = 254, vert = 160 }
2484 #define UTF8_IS_FIRST(x) (__extension__({ byte b = x; (!(b) || !((b) & 0x80) || (b) & 0x40); }))
2485 #define UTF8_NUM_BYTES(x) (__extension__({ byte b = x; (b & 0x80 && b & 0x40) ? ((b & 0x20) ? ((b & 0x10) ? 4 : 3) : 2) : 1; }))
2487 class HelpView : HTMLView
2491 hasVertScroll = true;
2492 hasHorzScroll = true;
2494 char editString[MAX_LOCATION];
2500 page = mainForm.browser.currentRow.GetData(null);
2505 char docFile[MAX_LOCATION];
2507 Module module = page ? page.GetModule() : null;
2508 NameSpace * ns = page ? page.GetNameSpace() : null;
2510 sprintf(docFile, "%s/%s.eCdoc", settings.docDir, (!module || !module.name || (ns && ns->name && !strcmp(ns->name, "namespaces/ecere/namespaces/com"))) ? "ecereCOM" : module.name);
2511 if(FileExists(docFile))
2513 archive = ArchiveOpen(docFile, { true } );
2514 readOnly = archive == null;
2520 archive = ArchiveOpen(docFile, { true } );
2523 // Must create root directory on archive creation
2524 ArchiveDir dir = archive.OpenDirectory("", null, replace);
2536 GoToAnchor(page.label);
2538 if(page.page) page = page.page;
2541 return HTMLView::OnCreate();
2550 char archiveFile[MAX_LOCATION];
2551 char fileName[MAX_FILENAME];
2552 char directory[MAX_LOCATION];
2554 Archive archive = null;
2555 if(SplitArchivePath(editString, archiveFile, &location))
2557 GetLastDirectory(location, fileName);
2558 StripLastDirectory(location, directory);
2559 archive = ArchiveOpen(archiveFile, { true } );
2563 ArchiveDir dir = archive ? archive.OpenDirectory(directory, null, replace) : null;
2566 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2568 if(block.type == TEXT && block.textLen)
2576 for(block = textBlock.parent.subBlocks.first; block; block = block.next)
2578 if(block.type == BR)
2580 else if(block.type == TEXT)
2581 f.Write(block.text, 1, block.textLen);
2586 dir.AddFromFile(fileName, f, null, replace, 0, null, null);
2592 Block parent = textBlock.parent;
2593 while((block = parent.subBlocks.first))
2595 parent.subBlocks.Remove(block);
2598 textBlock = Block { type = TEXT, parent = parent, font = parent.font };
2599 textBlock.text = CopyString($"[Add Text]");
2600 textBlock.textLen = strlen(textBlock.text);
2601 parent.subBlocks.Add(textBlock);
2609 PositionCaret(true);
2615 bool OnLeftButtonDown(int x, int y, Modifiers mods)
2619 if(edit && (!textBlock || overLink != textBlock.parent))
2623 HTMLView::OnLeftButtonDown(x, y, mods);
2624 selPosition = curPosition = 0;
2625 selBlock = textBlock;
2629 result = HTMLView::OnLeftButtonDown(x, y, mods);
2631 if(!edit && clickedLink)
2634 if(clickedLink == overLink && clickedLink.href)
2636 if(OnOpen(clickedLink.href))
2644 if(textBlock && overLink == textBlock.parent)
2646 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2647 selBlock = textBlock;
2648 PositionCaret(true);
2656 bool OnLeftButtonUp(int x, int y, Modifiers mods)
2658 if(!edit || !textBlock || clickedLink != textBlock.parent)
2660 HTMLView::OnLeftButtonUp(x, y, mods);
2663 selPosition = curPosition = TextPosFromPoint(x, y, &textBlock, true);
2664 selBlock = textBlock;
2665 PositionCaret(true);
2676 bool OnMouseMove(int x, int y, Modifiers mods)
2678 if(edit && selecting)
2680 curPosition = TextPosFromPoint(x, y, &textBlock, true);
2681 PositionCaret(true);
2684 return HTMLView::OnMouseMove(x, y, mods);
2687 bool OnLeftDoubleClick(int mx, int my, Modifiers mods)
2689 if(edit && textBlock)
2695 selPosition = curPosition = TextPosFromPoint(mx, my, &textBlock, false);
2696 selBlock = textBlock;
2697 for(c = curPosition; c >= 0; c--)
2700 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[c])) c--;
2701 ch = UTF8GetChar(textBlock.text + c, &numBytes);
2702 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2708 for(c = start; c < textBlock.textLen; c += numBytes)
2710 unichar ch = UTF8GetChar(textBlock.text + c, &numBytes);
2711 if(!CharMatchCategories(ch, letters|numbers|marks|connector))
2714 selPosition = start;
2717 PositionCaret(true);
2725 bool OnOpen(char * href)
2727 if(!strncmp(href, "api://", 6))
2729 int64 tag = (int64)strtoull(href + 6, null, 16);
2730 DataRow row = mainForm.browser.FindSubRow(tag);
2734 mainForm.browser.SelectRow(row);
2735 while((row = row.parent))
2736 row.collapsed = false;
2737 row = mainForm.browser.currentRow;
2738 mainForm.browser.scroll = { 0, row.index * mainForm.browser.rowHeight - mainForm.browser.clientSize.h / 2 };
2741 else if(!strncmp(href, "edit://", 7))
2744 int startX = clickedLink.startX, startY = clickedLink.startY;
2745 for(block = (Block)clickedLink.subBlocks.first; block; block = block.next)
2747 if(block.type == TEXT) startX = block.startX, startY = block.startY;
2748 if(block.type == BR && (!block.prev || !block.next || block.next.type != TEXT))
2750 Block newBlock { type = TEXT, parent = block.parent, font = block.parent.font };
2752 display.FontExtent(block.font.font, " ", 1, null, &th);
2755 block.parent.subBlocks.Insert(null, newBlock);
2760 block.parent.subBlocks.Insert(block, newBlock);
2761 startY += block.prev.height;
2763 newBlock.startX = startX;
2764 newBlock.startY = startY;
2765 newBlock.text = new0 char[1];
2769 textBlock = (Block)clickedLink.subBlocks.first;
2770 if(!strcmp(textBlock.text, $"[Add Text]"))
2772 textBlock.text[0] = 0;
2773 textBlock.textLen = 0;
2776 strcpy(editString, href + 7);
2777 selPosition = curPosition = 0;
2778 selBlock = textBlock;
2781 // PositionCaret(true);
2788 void DeleteSelection()
2790 if(textBlock != selBlock || curPosition != selPosition)
2792 if(textBlock == selBlock)
2794 // Within same block
2795 int start = Min(curPosition, selPosition);
2796 int end = Max(curPosition, selPosition);
2797 memmove(textBlock.text + start, textBlock.text + end, textBlock.textLen - end);
2798 textBlock.textLen -= end-start;
2799 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
2800 curPosition = start;
2801 selPosition = start;
2805 int startSel, endSel;
2806 Block startSelBlock = null, endSelBlock = null, b, next;
2808 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2810 startSelBlock.text = renew startSelBlock.text char[startSel + endSelBlock.textLen - endSel + 1];
2811 memcpy(startSelBlock.text + startSel, endSelBlock.text + endSel, endSelBlock.textLen - endSel + 1);
2813 startSelBlock.textLen = startSel + endSelBlock.textLen - endSel;
2814 for(b = startSelBlock.next; b; b = next)
2816 bool isEnd = b == endSelBlock;
2817 next = GetNextBlock(b);
2818 b.parent.subBlocks.Remove(b);
2823 textBlock = startSelBlock;
2824 selBlock = startSelBlock;
2825 curPosition = startSel;
2826 selPosition = startSel;
2830 PositionCaret(true);
2835 String GetSelectionString()
2837 String selection = null;
2838 if(textBlock == selBlock)
2840 // Within same block
2841 int start = Min(curPosition, selPosition);
2842 int end = Max(curPosition, selPosition);
2843 int len = end - start;
2844 selection = new char[len + 1];
2845 memcpy(selection, textBlock.text + start, len);
2850 int startSel, endSel;
2851 Block startSelBlock = null, endSelBlock = null, b;
2854 NormalizeSelection(&startSelBlock, &startSel, &endSelBlock, &endSel);
2857 for(b = startSelBlock; b; b = GetNextBlock(b))
2859 int start = (b == startSelBlock) ? startSel : 0;
2860 int end = (b == endSelBlock) ? endSel : b.textLen;
2861 int len = end - start;
2863 if(b == endSelBlock)
2865 else if(b.type == TEXT)
2869 selection = new char[totalLen + 1];
2871 for(b = startSelBlock; b; b = GetNextBlock(b))
2873 int start = (b == startSelBlock) ? startSel : 0;
2874 int end = (b == endSelBlock) ? endSel : b.textLen;
2875 int len = end - start;
2876 memcpy(selection + totalLen, b.text + start, len);
2878 if(b == endSelBlock)
2880 else if(b.type == TEXT)
2881 selection[totalLen++] = '\n';
2883 selection[totalLen] = 0;
2888 void CopySelection()
2890 String s = GetSelectionString();
2893 int len = strlen(s);
2895 if(cb.Allocate(len + 1))
2897 memcpy(cb.text, s, len + 1);
2905 bool OnKeyDown(Key key, unichar ch)
2912 OnLeftButtonDown(0,0,0);
2914 case Key { end, shift = true }:
2916 curPosition = textBlock.textLen;
2919 selPosition = curPosition;
2920 selBlock = textBlock;
2922 PositionCaret(true);
2925 case Key { home, shift = true }:
2930 selPosition = curPosition;
2931 selBlock = textBlock;
2933 PositionCaret(true);
2936 case Key { home, ctrl = true, shift = true }:
2939 while(textBlock.prev)
2940 textBlock = textBlock.prev.prev;
2943 selPosition = curPosition;
2944 selBlock = textBlock;
2946 PositionCaret(true);
2949 case Key { end, ctrl = true, shift = true }:
2951 while(textBlock.next && textBlock.next.next)
2952 textBlock = textBlock.next.next;
2953 curPosition = textBlock.textLen;
2956 selPosition = curPosition;
2957 selBlock = textBlock;
2959 PositionCaret(true);
2965 return HTMLView::OnKeyDown(key, ch);
2969 bool OnKeyHit(Key key, unichar ch)
2975 case Key { up, shift = true }:
2978 if(caretY == textBlock.startY)
2982 textBlock = textBlock.prev.prev;
2983 curPosition = Min(curPosition, textBlock.textLen);
2986 selPosition = curPosition;
2987 selBlock = textBlock;
2990 PositionCaret(false);
3000 int sx = textBlock.startX, sy = textBlock.startY;
3001 char * text = textBlock.text;
3003 Block block = textBlock;
3004 while(block && block.type != TD) block = block.parent;
3007 Block table = block;
3008 while(table && table.type != TABLE) table = table.parent;
3010 maxW = block.w - 2* table.cellPadding;
3012 maxW = clientSize.w - 10 - sx;
3015 maxW = clientSize.w - 10 - sx;
3016 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3020 int startPos = textPos;
3023 bool lineComplete = false;
3024 for(; textPos<textBlock.textLen && !lineComplete;)
3028 char * nextSpace = strchr(text + textPos, ' ');
3031 len = (nextSpace - (text + textPos)) + 1;
3033 len = textBlock.textLen - textPos;
3035 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3037 if(x + width + w > maxW && x > 0)
3039 lineComplete = true;
3049 if(textPos == textBlock.textLen || (sy == caretY - th && caretX <= x + width + sx))
3052 curPosition = textPos;
3053 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3056 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3057 len = curPosition - startPos;
3058 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3062 selPosition = curPosition;
3063 selBlock = textBlock;
3067 PositionCaret(false);
3071 if(sy == caretY - th || textPos == textBlock.textLen)
3073 if(textPos != textBlock.textLen)
3075 int c = textPos - 1;
3076 while(c > 0 && text[c] == ' ') c--;
3077 curPosition = c + 1;
3080 selPosition = curPosition;
3081 selBlock = textBlock;
3087 curPosition = textBlock.textLen;
3090 selPosition = curPosition;
3091 selBlock = textBlock;
3095 PositionCaret(false);
3099 sx = textBlock.startX;
3100 } while(textPos < textBlock.textLen);
3105 case Key { down, shift = true }:
3110 int sx = textBlock.startX, sy = textBlock.startY;
3111 char * text = textBlock.text;
3113 Block block = textBlock;
3114 while(block && block.type != TD) block = block.parent;
3117 Block table = block;
3118 while(table && table.type != TABLE) table = table.parent;
3120 maxW = block.w - 2* table.cellPadding;
3122 maxW = clientSize.w - 10 - sx;
3125 maxW = clientSize.w - 10 - sx;
3126 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3128 while(!textPos || textPos < textBlock.textLen)
3130 int startPos = textPos;
3133 bool lineComplete = false;
3134 for(; (textPos < textBlock.textLen) && !lineComplete;)
3138 char * nextSpace = strchr(text + textPos, ' ');
3141 len = (nextSpace - (text + textPos)) + 1;
3143 len = textBlock.textLen - textPos;
3145 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3147 if(x + width + w > maxW && x > 0)
3149 lineComplete = true;
3159 if(sy > caretY && (textPos == textBlock.textLen || caretX <= x + width + sx))
3161 curPosition = textPos;
3163 while(curPosition > 0 && x + sx > caretX && textPos > startPos)
3166 while(curPosition > 0 && !UTF8_IS_FIRST(text[--curPosition]));
3167 len = curPosition - startPos;
3168 display.FontExtent(textBlock.font.font, text + startPos, len, &x, null);
3172 selPosition = curPosition;
3173 selBlock = textBlock;
3176 PositionCaret(false);
3182 curPosition = textBlock.textLen;
3185 selPosition = curPosition;
3186 selBlock = textBlock;
3189 PositionCaret(false);
3192 else if(textPos == textBlock.textLen && textBlock.next && textBlock.next.next)
3196 textBlock = textBlock.next.next;
3197 sy = textBlock.startY;
3198 sx = textBlock.startX;
3199 text = textBlock.text;
3204 sx = textBlock.startX;
3208 /*if(textBlock.next && textBlock.next.next)
3210 textBlock = textBlock.next.next;
3211 selPosition = curPosition = Min(curPosition, textBlock.textLen);
3212 selBlock = textBlock;
3213 PositionCaret(false);
3217 case Key { right, shift = true, ctrl = true }:
3220 bool foundAlpha = false;
3222 Block line, lastLine;
3225 for(line = textBlock; (line && !found); line = line.next ? line.next.next : null)
3227 int start = (line == textBlock) ? curPosition : 0;
3229 for(c = start; c < line.textLen; c++)
3231 char ch = line.text[c];
3232 bool isAlUnder = CharMatchCategories(ch, letters|numbers|marks|connector);
3233 if(key.shift ? isAlUnder : !isAlUnder)
3247 selPosition = curPosition;
3248 selBlock = textBlock;
3252 PositionCaret(true);
3257 // No next word found,
3258 if(!found && (c != curPosition || line != textBlock))
3262 lastC = line.textLen-1;
3267 curPosition = line.textLen;
3270 selPosition = curPosition;
3271 selBlock = textBlock;
3276 PositionCaret(true);
3282 if(key.shift && found)
3284 curPosition = lastC+1;
3285 textBlock = lastLine;
3286 PositionCaret(true);
3291 case Key { left, ctrl = true, shift = true }:
3294 bool foundAlpha = false;
3296 Block line, lastLine;
3299 for(line = textBlock; (line && !found); line = line.prev ? line.prev.prev : null)
3302 if(curPosition == 0 && line != textBlock)
3305 lastC = line.textLen;
3309 if(line == textBlock) start = curPosition-1; else start = line.textLen-1;
3310 for(c = start; c>=0; c--)
3312 if(CharMatchCategories(line.text[c], letters|numbers|marks|connector))
3327 // No next word found,
3328 if(!found && curPosition > 0)
3338 textBlock = lastLine;
3339 curPosition = lastC;
3342 selPosition = curPosition;
3343 selBlock = textBlock;
3345 PositionCaret(true);
3350 case Key { right, shift = true }:
3352 if(curPosition < textBlock.textLen)
3354 curPosition += UTF8_NUM_BYTES(textBlock.text[curPosition]);
3357 selPosition = curPosition;
3358 selBlock = textBlock;
3360 PositionCaret(true);
3363 else if(textBlock.next && textBlock.next.next)
3365 textBlock = textBlock.next.next;
3369 selPosition = curPosition;
3370 selBlock = textBlock;
3372 PositionCaret(true);
3376 case Key { left, shift = true }:
3380 while(curPosition > 0 && !UTF8_IS_FIRST(textBlock.text[--curPosition]));
3383 selPosition = curPosition;
3384 selBlock = textBlock;
3386 PositionCaret(true);
3389 else if(textBlock.prev)
3391 textBlock = textBlock.prev.prev;
3392 curPosition = textBlock.textLen;
3395 selPosition = curPosition;
3396 selBlock = textBlock;
3398 PositionCaret(true);
3404 if(textBlock == selBlock && curPosition == selPosition)
3408 int c = curPosition;
3410 while(c > 0 && !UTF8_IS_FIRST(textBlock.text[--c])) nb++;
3411 memmove(textBlock.text + curPosition - nb, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3412 textBlock.textLen -= nb;
3413 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3415 selPosition = curPosition;
3416 selBlock = textBlock;
3420 PositionCaret(true);
3423 else if(textBlock.prev)
3425 Block prev = textBlock.prev, prevBlock = textBlock.prev.prev;
3426 prevBlock.text = renew prevBlock.text char[prevBlock.textLen + textBlock.textLen + 1];
3427 memcpy(prevBlock.text + prevBlock.textLen, textBlock.text, textBlock.textLen + 1);
3429 selPosition = curPosition = prevBlock.textLen;
3430 selBlock = textBlock;
3431 prevBlock.textLen += textBlock.textLen;
3432 textBlock.parent.subBlocks.Remove(prev);
3433 if(prev == selBlock)
3435 selBlock = textBlock;
3436 selPosition = curPosition;
3439 textBlock.parent.subBlocks.Remove(textBlock);
3440 if(textBlock == selBlock)
3442 selBlock = prevBlock;
3443 selPosition = curPosition;
3446 textBlock = prevBlock;
3450 PositionCaret(true);
3459 if(textBlock != selBlock || curPosition != selPosition)
3461 else if(textBlock.textLen > curPosition)
3463 int nb = UTF8_NUM_BYTES(textBlock.text[curPosition]);
3464 memmove(textBlock.text + curPosition, textBlock.text + curPosition + nb, textBlock.textLen - curPosition + 1 - nb + 1);
3465 textBlock.textLen -= nb;
3466 textBlock.text = renew textBlock.text char[textBlock.textLen + 1];
3471 PositionCaret(true);
3474 else if(textBlock.next && textBlock.next.next)
3476 Block next = textBlock.next, nextBlock = textBlock.next.next;
3477 textBlock.text = renew textBlock.text char[textBlock.textLen + nextBlock.textLen + 1];
3478 memcpy(textBlock.text + textBlock.textLen, nextBlock.text, nextBlock.textLen + 1);
3480 textBlock.textLen += nextBlock.textLen;
3481 textBlock.parent.subBlocks.Remove(next);
3482 if(next == selBlock)
3484 selBlock = textBlock;
3485 selPosition = curPosition;
3488 textBlock.parent.subBlocks.Remove(nextBlock);
3489 if(nextBlock == selBlock)
3491 selBlock = textBlock;
3492 selPosition = curPosition;
3498 PositionCaret(true);
3512 block = { type = BR, parent = textBlock.parent, font = textBlock.font };
3513 newBlock = { type = TEXT, parent = textBlock.parent, font = textBlock.font };
3514 startY = textBlock.startY;
3515 startX = textBlock.startX;
3517 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3518 textBlock.parent.subBlocks.Insert(textBlock, block);
3519 textBlock.parent.subBlocks.Insert(block, newBlock);
3523 newBlock.textLen = textBlock.textLen - curPosition;
3524 newBlock.text = new char[newBlock.textLen+1];
3525 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3526 textBlock.textLen = curPosition;
3527 textBlock.text[curPosition] = 0;
3529 newBlock.startY = startY;
3530 newBlock.startX = startX;
3531 selPosition = curPosition = 0;
3536 textBlock = newBlock;
3537 selBlock = textBlock;
3538 PositionCaret(true);
3543 case Key { del, shift = true }:
3558 ClipBoard clipBoard { };
3559 if(clipBoard.Load())
3562 char * text = clipBoard.memory;
3570 parent = textBlock.parent;
3571 font = textBlock.font;
3576 if(ch == '\n' || ch == '\r' || !ch)
3578 int len = c - start;
3579 textBlock.text = renew textBlock.text char[textBlock.textLen + 1 + len];
3580 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3581 memcpy(textBlock.text + curPosition, text + start, len);
3582 textBlock.textLen += len;
3584 selPosition = curPosition;
3585 selBlock = textBlock;
3588 Block block { type = BR, parent = parent, font = font };
3589 Block newBlock { type = TEXT, parent = parent, font = font };
3590 int startY = textBlock.startY, startX = textBlock.startX;
3593 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3594 textBlock.parent.subBlocks.Insert(textBlock, block);
3595 textBlock.parent.subBlocks.Insert(block, newBlock);
3599 newBlock.textLen = textBlock.textLen - curPosition;
3600 newBlock.text = new char[newBlock.textLen+1];
3601 memcpy(newBlock.text, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3602 textBlock.textLen = curPosition;
3603 textBlock.text[curPosition] = 0;
3605 newBlock.startY = startY;
3606 newBlock.startX = startX;
3607 selPosition = curPosition = 0;
3608 selBlock = textBlock;
3609 textBlock = newBlock;
3611 if(ch == '\r' && text[c+1] == '\n') c++;
3617 PositionCaret(true);
3625 // eC BUG HERE: (Should be fixed)
3626 if(!readOnly && !key.ctrl && !key.alt && ch >= 32 && ch != 128 /*&& ch < 128*/)
3629 int len = UTF32toUTF8Len(&ch, 1, string, 5);
3634 textBlock.text = renew textBlock.text char[textBlock.textLen + len + 1];
3635 memmove(textBlock.text + curPosition + len, textBlock.text + curPosition, textBlock.textLen - curPosition + 1);
3637 for(c = 0; c<len; c++)
3639 textBlock.text[curPosition] = string[c];
3640 textBlock.textLen++;
3643 selPosition = curPosition;
3644 selBlock = textBlock;
3647 //Clear(html.block);
3648 //CreateForms(html.block);
3653 PositionCaret(true);
3662 void OnResize(int width, int height)
3664 HTMLView::OnResize(width, height);
3665 PositionCaret(true);
3669 void PositionCaret(bool setCaretX)
3675 int sx = textBlock.startX, sy = textBlock.startY;
3676 char * text = textBlock.text;
3678 Block block = textBlock;
3679 while(block && block.type != TD) block = block.parent;
3682 Block table = block;
3683 while(table && table.type != TABLE) table = table.parent;
3685 maxW = block.w - 2* table.cellPadding;
3687 maxW = clientSize.w - 10 - sx;
3690 maxW = clientSize.w - 10 - sx;
3692 display.FontExtent(textBlock.font.font, " ", 1, null, &th);
3694 while(textPos < textBlock.textLen)
3696 int startPos = textPos;
3699 bool lineComplete = false;
3701 for(; textPos<textBlock.textLen && !lineComplete;)
3705 char * nextSpace = strchr(text + textPos, ' ');
3708 len = (nextSpace - (text + textPos)) + 1;
3710 len = textBlock.textLen - textPos;
3712 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3714 if(x + width + w > maxW && x > 0)
3716 lineComplete = true;
3729 if(curPosition < textPos || textPos == textBlock.textLen)
3731 int len = curPosition - startPos;
3732 display.FontExtent(textBlock.font.font, text + startPos, len, &tw, null);
3737 sx = textBlock.startX;
3742 SetCaret(sx, sy, th);
3744 Point scrollPos = scroll;
3745 bool doScroll = false;
3746 if(sy - scroll.y + th > clientSize.h)
3748 scrollPos.y = sy + th - clientSize.h;
3751 else if(sy - scroll.y < 0)
3756 if(sx - scroll.x + 10 > clientSize.w)
3758 scrollPos.x = sx + 10 - clientSize.w;
3761 else if(sx - scroll.x < 10)
3763 scrollPos.x = sx - 10;
3774 // Returns a character offset into the TextBlock from a window coordinate
3775 int TextPosFromPoint(int px, int py, Block * block, bool half)
3777 Block parentBlock = this.textBlock.parent;
3780 *block = this.textBlock;
3785 for(textBlock = parentBlock.subBlocks.first; textBlock; textBlock = textBlock.next)
3787 int sx = textBlock.startX, sy = textBlock.startY;
3790 char * text = textBlock.text;
3792 Block b = textBlock;
3795 if(textBlock.type != TEXT) continue;
3797 while(b && b.type != TD) b = b.parent;
3801 while(table && table.type != TABLE) table = table.parent;
3803 maxW = b.w - 2* table.cellPadding;
3805 maxW = clientSize.w - 10 - sx;
3808 maxW = clientSize.w - 10 - sx;
3810 display.FontExtent(textBlock.font.font, " ", 1, &space, &th);
3811 //space = space/2+2;
3814 while(textPos < textBlock.textLen)
3816 int startPos = textPos;
3819 bool lineComplete = false;
3821 for(; textPos<textBlock.textLen && !lineComplete;)
3825 char * nextSpace = strchr(text + textPos, ' ');
3828 len = (nextSpace - (text + textPos)) + 1;
3830 len = textBlock.textLen - textPos;
3832 display.FontExtent(textBlock.font.font, text + textPos, len, &w, &th);
3834 sx = x + textBlock.startX;
3835 if(/*py >= sy && */py < sy + th && /*px >= sx-space && */px < sx + w-space)
3840 for(c = textPos; (ch = text[c]); c += numBytes)
3842 numBytes = UTF8_NUM_BYTES(ch);
3843 display.FontExtent(textBlock.font.font, text + c, numBytes, &w, &th);
3844 if(/*py >= sy && */py < sy + th && /*px >= sx-w/2-space && */px < sx + (half ? w/2 : w) -space)
3851 if(x + width + w > maxW && x > 0)
3853 lineComplete = true;
3866 if(/*py >= sy && */py < sy + th)
3869 return textBlock.textLen;
3874 result = textBlock.textLen;
3880 Application componentsApp;
3882 class Documentor : GuiApplication
3886 Platform os = GetRuntimePlatform();
3887 componentsApp = __ecere_COM_Initialize(false, 1, null);
3888 SetPrivateModule(componentsApp);
3889 SetGlobalContext(globalContext);
3890 SetExcludedSymbols(&excludedSymbols);
3891 SetDefines(&::defines);
3892 SetImports(&imports);
3894 SetGlobalData(globalData);
3896 settingsContainer.dataOwner = &settings;
3897 settingsContainer.Load();
3898 if(!settings.docDir || !settings.docDir[0] )
3900 if(os == win32) // if Windows OS then
3902 char programFilesDir[MAX_LOCATION];
3903 char appData[MAX_LOCATION];
3904 char homeDrive[MAX_LOCATION];
3905 char winDir[MAX_LOCATION];
3906 GetEnvironment("APPDATA", appData, sizeof(appData));
3907 GetEnvironment("HOMEDRIVE", homeDrive, sizeof(homeDrive));
3908 GetEnvironment("windir", winDir, sizeof(winDir));
3909 if(GetEnvironment("ProgramFiles", programFilesDir, MAX_LOCATION))
3911 PathCat(programFilesDir, "ECERE SDK\\doc");
3912 settings.docDir = programFilesDir;
3914 else if(homeDrive && homeDrive[0])
3916 PathCat(homeDrive, "ECERE SDK\\doc");
3917 settings.docDir = homeDrive;
3919 else if(winDir && winDir[0])
3921 PathCat(winDir, "..\\ECERE SDK\\doc");
3922 settings.docDir = winDir;
3925 settings.docDir = "C:\\ECERE SDK\\doc";
3927 else // if Os is Linux, or Mac OSX or something else
3928 settings.docDir = "/usr/share/ecere/doc/";
3929 settingsContainer.Save();
3935 Module module = eModule_Load(componentsApp, "ecere" /*argv[1]*/, privateAccess);
3937 AddComponents(module, true);
3938 mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)module);
3939 // mainForm.browser.currentRow = row = mainForm.browser.FindSubRow((int64)eSystem_FindClass(componentsApp, "Window"));
3940 while((row = row.parent))
3941 row.collapsed = false;
3945 commandThread.Create();
3949 bool Cycle(bool idle)
3952 mainForm.Destroy(0);
3961 if(commandThread.created)
3963 console.CloseInput();
3964 console.CloseOutput();
3966 commandThread.Wait();
3970 FreeContext(globalContext);
3971 FreeExcludedSymbols(excludedSymbols);
3972 ::defines.Free(FreeModuleDefine);
3973 imports.Free(FreeModuleImport);
3975 FreeGlobalData(globalData);
3976 FreeTypeData(componentsApp);
3978 delete componentsApp;
3982 ConsoleFile console { };
3983 MainForm mainForm { };
3986 Thread commandThread
3993 console.GetLine(command, sizeof(command));
3994 if(!quit && command[0])
3997 if(!strcmpi(command, "Activate"))
3998 mainForm.Activate();
3999 else if(!strcmpi(command, "Quit"))